HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
xformable.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 USDGEOM_GENERATED_XFORMABLE_H
25 #define USDGEOM_GENERATED_XFORMABLE_H
26 
27 /// \file usdGeom/xformable.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/usdGeom/api.h"
32 #include "pxr/usd/usd/prim.h"
33 #include "pxr/usd/usd/stage.h"
34 #include "pxr/usd/usdGeom/tokens.h"
35 
36 #include "pxr/usd/usdGeom/xformOp.h"
37 #include <vector>
38 
39 #include "pxr/base/vt/value.h"
40 
41 #include "pxr/base/gf/vec3d.h"
42 #include "pxr/base/gf/vec3f.h"
43 #include "pxr/base/gf/matrix4d.h"
44 
45 #include "pxr/base/tf/token.h"
46 #include "pxr/base/tf/type.h"
47 
49 
50 class SdfAssetPath;
51 
52 // -------------------------------------------------------------------------- //
53 // XFORMABLE //
54 // -------------------------------------------------------------------------- //
55 
56 /// \class UsdGeomXformable
57 ///
58 /// Base class for all transformable prims, which allows arbitrary
59 /// sequences of component affine transformations to be encoded.
60 ///
61 /// \note
62 /// You may find it useful to review \ref UsdGeom_LinAlgBasics while reading
63 /// this class description.
64 ///
65 /// <b>Supported Component Transformation Operations</b>
66 ///
67 /// UsdGeomXformable currently supports arbitrary sequences of the following
68 /// operations, each of which can be encoded in an attribute of the proper
69 /// shape in any supported precision:
70 /// \li translate - 3D
71 /// \li scale - 3D
72 /// \li rotateX - 1D angle in degrees
73 /// \li rotateY - 1D angle in degrees
74 /// \li rotateZ - 1D angle in degrees
75 /// \li rotateABC - 3D where ABC can be any combination of the six principle
76 /// Euler Angle sets: XYZ, XZY, YXZ, YZX, ZXY, ZYX. See
77 /// \ref usdGeom_rotationPackingOrder "note on rotation packing order"
78 /// \li orient - 4D (quaternion)
79 /// \li transform - 4x4D
80 ///
81 /// <b>Creating a Component Transformation</b>
82 ///
83 /// To add components to a UsdGeomXformable prim, simply call AddXformOp()
84 /// with the desired op type, as enumerated in \ref UsdGeomXformOp::Type,
85 /// and the desired precision, which is one of \ref UsdGeomXformOp::Precision.
86 /// Optionally, you can also provide an "op suffix" for the operator that
87 /// disambiguates it from other components of the same type on the same prim.
88 /// Application-specific transform schemas can use the suffixes to fill a role
89 /// similar to that played by AbcGeom::XformOp's "Hint" enums for their own
90 /// round-tripping logic.
91 ///
92 /// We also provide specific "Add" API for each type, for clarity and
93 /// conciseness, e.g. AddTranslateOp(), AddRotateXYZOp() etc.
94 ///
95 /// AddXformOp() will return a UsdGeomXformOp object, which is a schema on a
96 /// newly created UsdAttribute that provides convenience API for authoring
97 /// and computing the component transformations. The UsdGeomXformOp can then
98 /// be used to author any number of timesamples and default for the op.
99 ///
100 /// Each successive call to AddXformOp() adds an operator that will be applied
101 /// "more locally" than the preceding operator, just as if we were pushing
102 /// transforms onto a transformation stack - which is precisely what should
103 /// happen when the operators are consumed by a reader.
104 ///
105 /// \note
106 /// If you can, please try to use the UsdGeomXformCommonAPI, which wraps
107 /// the UsdGeomXformable with an interface in which Op creation is taken
108 /// care of for you, and there is a much higher chance that the data you
109 /// author will be importable without flattening into other DCC's, as it
110 /// conforms to a fixed set of Scale-Rotate-Translate Ops.
111 ///
112 /// \sa \ref usdGeom_xformableExamples "Using the Authoring API"
113 ///
114 /// <b>Data Encoding and Op Ordering</b>
115 ///
116 /// Because there is no "fixed schema" of operations, all of the attributes
117 /// that encode transform operations are dynamic, and are scoped in
118 /// the namespace "xformOp". The second component of an attribute's name provides
119 /// the \em type of operation, as listed above. An "xformOp" attribute can
120 /// have additional namespace components derived from the \em opSuffix argument
121 /// to the AddXformOp() suite of methods, which provides a preferred way of
122 /// naming the ops such that we can have multiple "translate" ops with unique
123 /// attribute names. For example, in the attribute named
124 /// "xformOp:translate:maya:pivot", "translate" is the type of operation and
125 /// "maya:pivot" is the suffix.
126 ///
127 /// The following ordered list of attribute declarations in usda
128 /// define a basic Scale-Rotate-Translate with XYZ Euler angles, wherein the
129 /// translation is double-precision, and the remainder of the ops are single,
130 /// in which we will:
131 ///
132 /// <ol>
133 /// <li> Scale by 2.0 in each dimension
134 /// <li> Rotate about the X, Y, and Z axes by 30, 60, and 90 degrees, respectively
135 /// <li> Translate by 100 units in the Y direction
136 /// </ol>
137 ///
138 /// \code
139 /// float3 xformOp:rotateXYZ = (30, 60, 90)
140 /// float3 xformOp:scale = (2, 2, 2)
141 /// double3 xformOp:translate = (0, 100, 0)
142 /// uniform token[] xformOpOrder = [ "xformOp:translate", "xformOp:rotateXYZ", "xformOp:scale" ]
143 /// \endcode
144 ///
145 /// The attributes appear in the dictionary order in which USD, by default,
146 /// sorts them. To ensure the ops are recovered and evaluated in the correct
147 /// order, the schema introduces the **xformOpOrder** attribute, which
148 /// contains the names of the op attributes, in the precise sequence in which
149 /// they should be pushed onto a transform stack. **Note** that the order is
150 /// opposite to what you might expect, given the matrix algebra described in
151 /// \ref UsdGeom_LinAlgBasics. This also dictates order of op creation,
152 /// since each call to AddXformOp() adds a new op to the end of the
153 /// \b xformOpOrder array, as a new "most-local" operation. See
154 /// \ref usdGeom_xformableExamples "Example 2 below" for C++ code that could
155 /// have produced this USD.
156 ///
157 /// If it were important for the prim's rotations to be independently
158 /// overridable, we could equivalently (at some performance cost) encode
159 /// the transformation also like so:
160 /// \code
161 /// float xformOp:rotateX = 30
162 /// float xformOp:rotateY = 60
163 /// float xformOp:rotateZ = 90
164 /// float3 xformOp:scale = (2, 2, 2)
165 /// double3 xformOp:translate = (0, 100, 0)
166 /// uniform token[] xformOpOrder = [ "xformOp:translate", "xformOp:rotateZ", "xformOp:rotateY", "xformOp:rotateX", "xformOp:scale" ]
167 /// \endcode
168 ///
169 /// Again, note that although we are encoding an XYZ rotation, the three
170 /// rotations appear in the **xformOpOrder** in the opposite order, with Z,
171 /// followed, by Y, followed by X.
172 ///
173 /// Were we to add a Maya-style scalePivot to the above example, it might
174 /// look like the following:
175 /// \code
176 /// float3 xformOp:rotateXYZ = (30, 60, 90)
177 /// float3 xformOp:scale = (2, 2, 2)
178 /// double3 xformOp:translate = (0, 100, 0)
179 /// double3 xformOp:translate:scalePivot
180 /// uniform token[] xformOpOrder = [ "xformOp:translate", "xformOp:rotateXYZ", "xformOp:translate:scalePivot", "xformOp:scale" ]
181 /// \endcode
182 ///
183 /// <b>Paired "Inverted" Ops</b>
184 ///
185 /// We have been claiming that the ordered list of ops serves as a set
186 /// of instructions to a transform stack, but you may have noticed in the last
187 /// example that there is a missing operation - the pivot for the scale op
188 /// needs to be applied in its inverse-form as a final (most local) op! In the
189 /// AbcGeom::Xform schema, we would have encoded an actual "final" translation
190 /// op whose value was authored by the exporter as the negation of the pivot's
191 /// value. However, doing so would be brittle in USD, given that each op can
192 /// be independently overridden, and the constraint that one attribute must be
193 /// maintained as the negation of the other in order for successful
194 /// re-importation of the schema cannot be expressed in USD.
195 ///
196 /// Our solution leverages the **xformOpOrder** member of the schema, which,
197 /// in addition to ordering the ops, may also contain one of two special
198 /// tokens that address the paired op and "stack resetting" behavior.
199 ///
200 /// The "paired op" behavior is encoded as an "!invert!" prefix in
201 /// \b xformOpOrder, as the result of an AddXformOp(isInverseOp=True) call.
202 /// The \b xformOpOrder for the last example would look like:
203 /// \code
204 /// uniform token[] xformOpOrder = [ "xformOp:translate", "xformOp:rotateXYZ", "xformOp:translate:scalePivot", "xformOp:scale", "!invert!xformOp:translate:scalePivot" ]
205 /// \endcode
206 ///
207 /// When asked for its value via UsdGeomXformOp::GetOpTransform(), an
208 /// "inverted" Op (i.e. the "inverted" half of a set of paired Ops) will fetch
209 /// the value of its paired attribute and return its negation. This works for
210 /// all op types - an error will be issued if a "transform" type op is singular
211 /// and cannot be inverted. When getting the authored value of an inverted op
212 /// via UsdGeomXformOp::Get(), the raw, uninverted value of the associated
213 /// attribute is returned.
214 ///
215 /// For the sake of robustness, <b>setting a value on an inverted op is disallowed.</b>
216 /// Attempting to set a value on an inverted op will result in a coding error
217 /// and no value being set.
218 ///
219 /// <b>Resetting the Transform Stack</b>
220 ///
221 /// The other special op/token that can appear in \em xformOpOrder is
222 /// \em "!resetXformStack!", which, appearing as the first element of
223 /// \em xformOpOrder, indicates this prim should not inherit the transformation
224 /// of its namespace parent. See SetResetXformStack()
225 ///
226 /// <b>Expected Behavior for "Missing" Ops</b>
227 ///
228 /// If an importer expects Scale-Rotate-Translate operations, but a prim
229 /// has only translate and rotate ops authored, the importer should assume
230 /// an identity scale. This allows us to optimize the data a bit, if only
231 /// a few components of a very rich schema (like Maya's) are authored in the
232 /// app.
233 ///
234 /// \anchor usdGeom_xformableExamples
235 /// <b>Using the C++ API</b>
236 ///
237 /// #1. Creating a simple transform matrix encoding
238 /// \snippet examples_usdGeom.cpp CreateMatrixWithDefault
239 ///
240 /// #2. Creating the simple SRT from the example above
241 /// \snippet examples_usdGeom.cpp CreateExampleSRT
242 ///
243 /// #3. Creating a parameterized SRT with pivot using UsdGeomXformCommonAPI
244 /// \snippet examples_usdGeom.cpp CreateSRTWithDefaults
245 ///
246 /// #4. Creating a rotate-only pivot transform with animated
247 /// rotation and translation
248 /// \snippet examples_usdGeom.cpp CreateAnimatedTransform
249 ///
250 ///
251 ///
253 {
254 public:
255  /// Compile time constant representing what kind of schema this class is.
256  ///
257  /// \sa UsdSchemaKind
259 
260  /// Construct a UsdGeomXformable on UsdPrim \p prim .
261  /// Equivalent to UsdGeomXformable::Get(prim.GetStage(), prim.GetPath())
262  /// for a \em valid \p prim, but will not immediately throw an error for
263  /// an invalid \p prim
264  explicit UsdGeomXformable(const UsdPrim& prim=UsdPrim())
265  : UsdGeomImageable(prim)
266  {
267  }
268 
269  /// Construct a UsdGeomXformable on the prim held by \p schemaObj .
270  /// Should be preferred over UsdGeomXformable(schemaObj.GetPrim()),
271  /// as it preserves SchemaBase state.
272  explicit UsdGeomXformable(const UsdSchemaBase& schemaObj)
273  : UsdGeomImageable(schemaObj)
274  {
275  }
276 
277  /// Destructor.
279  virtual ~UsdGeomXformable();
280 
281  /// Return a vector of names of all pre-declared attributes for this schema
282  /// class and all its ancestor classes. Does not include attributes that
283  /// may be authored by custom/extended methods of the schemas involved.
285  static const TfTokenVector &
286  GetSchemaAttributeNames(bool includeInherited=true);
287 
288  /// Return a UsdGeomXformable holding the prim adhering to this
289  /// schema at \p path on \p stage. If no prim exists at \p path on
290  /// \p stage, or if the prim at that path does not adhere to this schema,
291  /// return an invalid schema object. This is shorthand for the following:
292  ///
293  /// \code
294  /// UsdGeomXformable(stage->GetPrimAtPath(path));
295  /// \endcode
296  ///
298  static UsdGeomXformable
299  Get(const UsdStagePtr &stage, const SdfPath &path);
300 
301 
302 protected:
303  /// Returns the kind of schema this class belongs to.
304  ///
305  /// \sa UsdSchemaKind
307  UsdSchemaKind _GetSchemaKind() const override;
308 
309 private:
310  // needs to invoke _GetStaticTfType.
311  friend class UsdSchemaRegistry;
313  static const TfType &_GetStaticTfType();
314 
315  static bool _IsTypedSchema();
316 
317  // override SchemaBase virtuals.
319  const TfType &_GetTfType() const override;
320 
321 public:
322  // --------------------------------------------------------------------- //
323  // XFORMOPORDER
324  // --------------------------------------------------------------------- //
325  /// Encodes the sequence of transformation operations in the
326  /// order in which they should be pushed onto a transform stack while
327  /// visiting a UsdStage's prims in a graph traversal that will effect
328  /// the desired positioning for this prim and its descendant prims.
329  ///
330  /// You should rarely, if ever, need to manipulate this attribute directly.
331  /// It is managed by the AddXformOp(), SetResetXformStack(), and
332  /// SetXformOpOrder(), and consulted by GetOrderedXformOps() and
333  /// GetLocalTransformation().
334  ///
335  /// | ||
336  /// | -- | -- |
337  /// | Declaration | `uniform token[] xformOpOrder` |
338  /// | C++ Type | VtArray<TfToken> |
339  /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->TokenArray |
340  /// | \ref SdfVariability "Variability" | SdfVariabilityUniform |
343 
344  /// See GetXformOpOrderAttr(), and also
345  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
346  /// If specified, author \p defaultValue as the attribute's default,
347  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
348  /// the default for \p writeSparsely is \c false.
350  UsdAttribute CreateXformOpOrderAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
351 
352 public:
353  // ===================================================================== //
354  // Feel free to add custom code below this line, it will be preserved by
355  // the code generator.
356  //
357  // Just remember to:
358  // - Close the class declaration with };
359  // - Close the namespace with PXR_NAMESPACE_CLOSE_SCOPE
360  // - Close the include guard with #endif
361  // ===================================================================== //
362  // --(BEGIN CUSTOM CODE)--
363 
364  /// \class XformQuery
365  ///
366  /// Helper class that caches the ordered vector of UsGeomXformOps that
367  /// contribute to the local transformation of an xformable prim
368  ///
369  /// Internally, the class initializes UsdAttributeQuery objects for the
370  /// xformOp attributes in order to facilitate efficient querying of their
371  /// values.
372  ///
373  /// \note This object does not listen to change notification. If a
374  /// consumer is holding onto a UsdGeomXformable::XformQuery object, it is
375  /// their responsibility to dispose of it, in response to a resync
376  /// change to the associated xformOp attributes. The class provides the
377  /// convenience method IncludesXformOpAttr for this purpose.
378  ///
379  class XformQuery {
380  public:
382  _resetsXformStack(false)
383  { }
384 
385  /// Constructs an XformQuery object for the given xformable prim.
386  /// Caches the ordered xformOps and initializes an UsdAttributeQuery
387  /// internally for all the associated attributes.
389  XformQuery(const UsdGeomXformable &xformable);
390 
391  /// Utilizes the internally cached UsdAttributeQuery's to efficiently
392  /// compute the transform value at the given \p time.
395  const UsdTimeCode time) const;
396 
397  /// Returns whether the xformable resets its parent's transformation.
398  bool GetResetXformStack() const {
399  return _resetsXformStack;
400  }
401 
402  /// Returns whether the xform value might change over time.
404  bool TransformMightBeTimeVarying() const;
405 
406  /// Returns whether xformOpOrder is non-empty.
408  bool HasNonEmptyXformOpOrder() const;
409 
410  /// Sets the vector of times at which xformOp samples have been
411  /// authored in the cached set of xform ops.
412  ///
413  /// \sa UsdXformable::GetTimeSamples
415  bool GetTimeSamples(std::vector<double> *times) const;
416 
417  /// Sets the vector of times in the \p interval at which xformOp
418  /// samples have been authored in the cached set of xform ops.
419  ///
420  /// \sa UsdXformable::GetTimeSamples
422  bool GetTimeSamplesInInterval(const GfInterval &interval,
423  std::vector<double> *times) const;
424 
425  /// Returns whether the given attribute affects the local
426  /// transformation computed for this query.
429  const TfToken &attrName) const;
430 
431  private:
432  // Cached copy of the vector of ordered xform ops.
433  std::vector<UsdGeomXformOp> _xformOps;
434 
435  // Cache whether the xformable has !resetsXformStack! in its
436  // xformOpOrder.
437  bool _resetsXformStack;
438  };
439 
440  /// Add an affine transformation to the local stack represented by this
441  /// Xformable. This will fail if there is already a transform operation
442  /// of the same name in the ordered ops on this prim (i.e. as returned
443  /// by GetOrderedXformOps()), or if an op of the same name exists at all
444  /// on the prim with a different precision than that specified.
445  ///
446  /// The newly created operation will become the most-locally applied
447  /// transformation on the prim, and will appear last in the list
448  /// returned by GetOrderedXformOps(). It is OK to begin authoring values
449  /// to the returned UsdGeomXformOp immediately, interspersed with
450  /// subsequent calls to AddXformOp() - just note the order of application,
451  /// which \em can be changed at any time (and in stronger layers) via
452  /// SetXformOpOrder().
453  ///
454  /// \param opType is the type of transform operation, one of
455  /// \ref UsdGeomXformOp::Type.
456  /// \param precision allows you to specify the precision with which you
457  /// desire to encode the data. This should be one of the values in
458  /// the enum \ref UsdGeomXformOp::Precision .
459  /// \param opSuffix allows you to specify the purpose/meaning of the op in
460  /// the stack. When opSuffix is specified, the associated attribute's
461  /// name is set to "xformOp:<opType>:<opSuffix>".
462  /// \param isInverseOp is used to indicate an inverse transformation
463  /// operation.
464  ///
465  /// \return a UsdGeomXformOp that can be used to author to the operation.
466  /// An error is issued and the returned object will be invalid
467  /// (evaluate to false) if the op being added already exists in
468  /// \ref GetXformOpOrderAttr() "xformOpOrder" or if the
469  /// arguments supplied are invalid.
470  ///
471  /// \note If the attribute associated with the op already exists, but isn't
472  /// of the requested precision, a coding error is issued, but a valid
473  /// xformOp is returned with the existing attribute.
474  ///
479  TfToken const &opSuffix = TfToken(),
480  bool isInverseOp=false) const;
481 
482  /// Get an affine transformation from the local stack represented by this
483  /// Xformable. This will return an invalid op if there is no transform operation
484  /// of the same name in the ordered ops on this prim (i.e. as returned
485  /// by GetOrderedXformOps())
486  ///
487  /// \param opType is the type of transform operation, one of
488  /// \ref UsdGeomXformOp::Type.
489  /// \param opSuffix specifies the purpose/meaning of the op in
490  /// the stack. When opSuffix is specified, the associated attribute's
491  /// name is "xformOp:<opType>:<opSuffix>".
492  /// \param isInverseOp is used to indicate an inverse transformation
493  /// operation.
494  ///
495  /// \return a UsdGeomXformOp with the specified attributes.
496  /// The returned object will be invalid (evaluate to false)
497  /// if the op requested does not exist in
498  /// \ref GetXformOpOrderAttr() "xformOpOrder" or if the
499  /// arguments supplied are invalid.
500  ///
503  TfToken const &opSuffix = TfToken(),
504  bool isInverseOp=false) const;
505 
506  /// Add a translate operation to the local stack represented by this
507  /// xformable.
508  ///
509  /// \sa AddXformOp()
513  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
514 
515  /// Get a translate operation from the local stack represented by this
516  /// xformable.
517  ///
518  /// \sa GetXformOp()
521  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
522 
523  /// Add a scale operation to the local stack represented by this
524  /// xformable.
525  ///
526  /// \sa AddXformOp()
530  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
531 
532  /// Get a scale operation from the local stack represented by this
533  /// xformable.
534  ///
535  /// \sa GetXformOp()
538  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
539 
540  /// Add a rotation about the X-axis to the local stack represented by
541  /// this xformable.
542  ///
543  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
544  /// \sa AddXformOp()
548  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
549 
550  /// Get a rotation about the X-axis from the local stack represented by
551  /// this xformable.
552  ///
553  /// \sa GetXformOp()
556  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
557 
558  /// Add a rotation about the Y-axis to the local stack represented by
559  /// this xformable.
560  ///
561  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
562  /// \sa AddXformOp()
566  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
567 
568  /// Get a rotation about the Y-axis from the local stack represented by
569  /// this xformable.
570  ///
571  /// \sa GetXformOp()
574  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
575 
576  /// Add a rotation about the Z-axis to the local stack represented by
577  /// this xformable.
578  ///
579  /// \sa AddXformOp()
583  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
584 
585  /// Get a rotation about the Z-axis from the local stack represented by
586  /// this xformable.
587  ///
588  /// \sa GetXformOp()
591  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
592 
593  /// Add a rotation op with XYZ rotation order to the local stack
594  /// represented by this xformable.
595  ///
596  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
597  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
601  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
602 
603  /// Get a rotation op with XYZ rotation order from the local stack
604  /// represented by this xformable.
605  ///
606  /// \sa GetXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
609  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
610 
611  /// Add a rotation op with XZY rotation order to the local stack
612  /// represented by this xformable.
613  ///
614  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
615  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
619  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
620 
621  /// Get a rotation op with XZY rotation order from the local stack
622  /// represented by this xformable.
623  ///
624  /// \sa GetXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
627  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
628 
629  /// Add a rotation op with YXZ rotation order to the local stack
630  /// represented by this xformable.
631  ///
632  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
633  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
637  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
638 
639  /// Get a rotation op with YXZ rotation order from the local stack
640  /// represented by this xformable.
641  ///
642  /// \sa GetXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
645  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
646 
647  /// Add a rotation op with YZX rotation order to the local stack
648  /// represented by this xformable.
649  ///
650  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
651  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
655  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
656 
657  /// Get a rotation op with YZX rotation order from the local stack
658  /// represented by this xformable.
659  ///
660  /// \sa GetXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
663  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
664 
665  /// Add a rotation op with ZXY rotation order to the local stack
666  /// represented by this xformable.
667  ///
668  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
669  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
673  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
674 
675  /// Get a rotation op with ZXY rotation order from the local stack
676  /// represented by this xformable.
677  ///
678  /// \sa GetXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
681  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
682 
683  /// Add a rotation op with ZYX rotation order to the local stack
684  /// represented by this xformable.
685  ///
686  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
687  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
691  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
692 
693  /// Get a rotation op with ZYX rotation order from the local stack
694  /// represented by this xformable.
695  ///
696  /// \sa GetXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
699  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
700 
701  /// Add a orient op (arbitrary axis/angle rotation) to the local stack
702  /// represented by this xformable.
703  ///
704  /// \sa AddXformOp()
708  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
709 
710  /// Get an orient op (arbitrary axis/angle rotation) from the local stack
711  /// represented by this xformable.
712  ///
713  /// \sa GetXformOp()
716  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
717 
718  /// Add a tranform op (4x4 matrix transformation) to the local stack
719  /// represented by this xformable.
720  ///
721  /// \sa AddXformOp()
722  ///
723  /// Note: This method takes a precision argument only to be consistent
724  /// with the other types of xformOps. The only valid precision here is
725  /// double since matrix values cannot be encoded in floating-pt precision
726  /// in Sdf.
730  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
731 
732  /// Get a tranform op (4x4 matrix transformation) from the local stack
733  /// represented by this xformable.
734  ///
735  /// \sa GetXformOp()
736  ///
739  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
740 
741  /// Specify whether this prim's transform should reset the transformation
742  /// stack inherited from its parent prim.
743  ///
744  /// By default, parent transforms are inherited. SetResetXformStack() can be
745  /// called at any time during authoring, but will always add a
746  /// '!resetXformStack!' op as the \em first op in the ordered list, if one
747  /// does not exist already. If one already exists, and \p resetXform is
748  /// false, it will remove all ops upto and including the last
749  /// "!resetXformStack!" op.
751  bool SetResetXformStack(bool resetXform) const;
752 
753  /// Does this prim reset its parent's inherited transformation?
754  ///
755  /// Returns true if "!resetXformStack!" appears \em anywhere in xformOpOrder.
756  /// When this returns true, all ops upto the last "!resetXformStack!" in
757  /// xformOpOrder are ignored when computing the local transformation.
758  ///
760  bool GetResetXformStack() const;
761 
762  /// Reorder the already-existing transform ops on this prim.
763  ///
764  /// All elements in \p orderedXformOps must be valid and represent attributes
765  /// on this prim. Note that it is \em not required that all the existing
766  /// operations be present in \p orderedXformOps, so this method can be used to
767  /// completely change the transformation structure applied to the prim.
768  ///
769  /// If \p resetXformStack is set to true, then "!resetXformOp! will be
770  /// set as the first op in xformOpOrder, to indicate that the prim does
771  /// not inherit its parent's transformation.
772  ///
773  /// \note If you wish to re-specify a prim's transformation completely in
774  /// a stronger layer, you should first call this method with an \em empty
775  /// \p orderedXformOps vector. From there you can call AddXformOp() just as if
776  /// you were authoring to the prim from scratch.
777  ///
778  /// \return false if any of the elements of \p orderedXformOps are not extant
779  /// on this prim, or if an error occurred while authoring the ordering
780  /// metadata. Under either condition, no scene description is authored.
781  ///
782  /// \sa GetOrderedXformOps()
784  bool SetXformOpOrder(std::vector<UsdGeomXformOp> const &orderedXformOps,
785  bool resetXformStack = false) const;
786 
787  /// Return the ordered list of transform operations to be applied to
788  /// this prim, in least-to-most-local order. This is determined by the
789  /// intersection of authored op-attributes and the explicit ordering of
790  /// those attributes encoded in the \c xformOpOrder attribute on this prim.
791  /// Any entries in \c xformOpOrder that do not correspond to valid
792  /// attributes on the xformable prim are skipped and a warning is issued.
793  ///
794  /// A UsdGeomTransformable that has not had any ops added via AddXformOp()
795  /// will return an empty vector.
796  ///
797  /// The function also sets \p resetsXformStack to true if "!resetXformStack!"
798  /// appears \em anywhere in xformOpOrder (i.e., if the prim resets its
799  /// parent's inherited transformation).
800  ///
801  /// \note A coding error is issued if resetsXformStack is NULL.
802  ///
803  /// \sa GetResetXformStack()
805  std::vector<UsdGeomXformOp> GetOrderedXformOps(bool *resetsXformStack) const;
806 
807  /// Clears the local transform stack.
809  bool ClearXformOpOrder() const;
810 
811  /// Clears the existing local transform stack and creates a new xform op of
812  /// type 'transform'.
813  ///
814  /// This API is provided for convenience since this is the most common
815  /// xform authoring operation.
816  ///
817  /// \sa ClearXformOpOrder()
818  /// \sa AddTransformOp()
821 
822  /// Determine whether there is any possibility that this prim's \em local
823  /// transformation may vary over time.
824  ///
825  /// The determination is based on a snapshot of the authored state of the
826  /// op attributes on the prim, and may become invalid in the face of
827  /// further authoring.
829  bool TransformMightBeTimeVarying() const;
830 
831  /// \overload
832  /// Determine whether there is any possibility that this prim's \em local
833  /// transformation may vary over time, using a pre-fetched (cached) list of
834  /// ordered xform ops supplied by the client.
835  ///
836  /// The determination is based on a snapshot of the authored state of the
837  /// op attributes on the prim, and may become invalid in the face of
838  /// further authoring.
841  const std::vector<UsdGeomXformOp> &ops) const;
842 
843  /// Sets \p times to the union of all the timesamples at which xformOps that
844  /// are included in the xformOpOrder attribute are authored.
845  ///
846  /// This clears the \p times vector before accumulating sample times
847  /// from all the xformOps.
848  ///
849  /// \sa UsdAttribute::GetTimeSamples
851  bool GetTimeSamples(std::vector<double> *times) const;
852 
853  /// Sets \p times to the union of all the timesamples in the interval,
854  /// \p interval, at which xformOps that are included in the xformOpOrder
855  /// attribute are authored.
856  ///
857  /// This clears the \p times vector before accumulating sample times
858  /// from all the xformOps.
859  ///
860  /// \sa UsdAttribute::GetTimeSamples
862  bool GetTimeSamplesInInterval(const GfInterval &interval,
863  std::vector<double> *times) const;
864 
865  /// Returns the union of all the timesamples at which the attributes
866  /// belonging to the given \p orderedXformOps are authored.
867  ///
868  /// This clears the \p times vector before accumulating sample times
869  /// from \p orderedXformOps.
870  ///
871  /// \sa UsdGeomXformable::GetTimeSamples
873  static bool GetTimeSamples(
874  std::vector<UsdGeomXformOp> const &orderedXformOps,
875  std::vector<double> *times);
876 
877  /// Returns the union of all the timesamples in the \p interval
878  /// at which the attributes belonging to the given \p orderedXformOps
879  /// are authored.
880  ///
881  /// This clears the \p times vector before accumulating sample times
882  /// from \p orderedXformOps.
883  ///
884  /// \sa UsdGeomXformable::GetTimeSamplesInInterval
886  static bool GetTimeSamplesInInterval(
887  std::vector<UsdGeomXformOp> const &orderedXformOps,
888  const GfInterval &interval,
889  std::vector<double> *times);
890 
891  /// Computes the fully-combined, local-to-parent transformation for this prim.
892  ///
893  /// If a client does not need to manipulate the individual ops themselves,
894  /// and requires only the combined transform on this prim, this method will
895  /// take care of all the data marshalling and linear algebra needed to
896  /// combine the ops into a 4x4 affine transformation matrix, in
897  /// double-precision, regardless of the precision of the op inputs.
898  ///
899  /// \param transform is the output parameter that will hold the local
900  /// transform.
901  /// \param resetsXformStack is the output parameter that informs client
902  /// whether they need to reset the transform stack before pushing
903  /// \p transform.
904  /// \param time is the UsdTimeCode at which to sample the ops.
905  ///
906  /// \return true on success, false if there was an error reading data.
907  ///
908  /// \note A coding error is issued if \p transform or \p resetsXformStack
909  /// is NULL.
910  ///
914  bool *resetsXformStack,
915  const UsdTimeCode time = UsdTimeCode::Default()) const;
916 
917  /// \overload
918  /// Computes the fully-combined, local-to-parent transformation for this
919  /// prim as efficiently as possible, using a pre-fetched (cached) list of
920  /// ordered xform ops supplied by the client.
921  ///
922  /// \param transform is the output parameter that will hold the local
923  /// transform.
924  /// \param resetsXformStack is the output parameter that informs client
925  /// whether they need to reset the transform stack before pushing
926  /// \p transform.
927  /// \param ops is the ordered set of xform ops for this prim, and will be
928  /// queried without any validity checking. Passing this in can save
929  /// significant value-resolution costs, if the client is able to
930  /// retain this data from a call to GetOrderedXformOps().
931  /// \param time is the UsdTimeCode at which to sample the ops.
932  ///
933  /// \return true on success, false if there was an error reading data.
934  ///
935  /// \note A coding error is issued if \p transform or \p resetsXformStack
936  /// is NULL.
937  ///
939  bool GetLocalTransformation(GfMatrix4d *transform,
940  bool *resetsXformStack,
941  const std::vector<UsdGeomXformOp> &ops,
942  const UsdTimeCode time = UsdTimeCode::Default()) const;
943 
944  /// \overload
945  /// This is a static version of the preceding function that takes
946  /// a cached list of ordered xform ops.
947  ///
948  /// \param transform is the output parameter that will hold the local
949  /// transform.
950  /// \param ops is the ordered set of xform ops that must be combined
951  /// together to compute the local transformation.
952  /// \param time is the UsdTimeCode at which to sample the ops.
953  ///
954  /// \return true on success, false if there was an error reading data.
955  ///
957  static bool GetLocalTransformation(GfMatrix4d *transform,
958  std::vector<UsdGeomXformOp> const &ops,
959  const UsdTimeCode time);
960 
961  /// Returns true if the attribute named \p attrName could affect the local
962  /// transformation of an xformable prim.
964  static bool IsTransformationAffectedByAttrNamed(const TfToken &attrName);
965 
966 private:
967  // Extracts the value of the xformOpOrder attribute. Returns false if
968  // the xformOpOrder attribute doesn't exist on the prim (eg. when the prim
969  // type is incompatible or if it's a pure over).
970  bool _GetXformOpOrderValue(VtTokenArray *xformOpOrder) const;
971 
972  // Helper function for getting xformops with or without attribute queries.
973  std::vector<UsdGeomXformOp>
974  _GetOrderedXformOps(bool *resetsXformStack,
975  bool withAttributeQueries) const;
976 };
977 
979 
980 #endif
USDGEOM_API UsdGeomXformOp GetTranslateOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdAttribute CreateXformOpOrderAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
USDGEOM_API bool SetResetXformStack(bool resetXform) const
Double precision.
Definition: xformOp.h:140
static constexpr UsdTimeCode Default()
Definition: timeCode.h:112
USDGEOM_API UsdGeomXformOp AddRotateZYXOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp AddRotateXYZOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp GetTransformOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
GT_API const UT_StringHolder time
USDGEOM_API bool GetTimeSamplesInInterval(const GfInterval &interval, std::vector< double > *times) const
UsdGeomXformable(const UsdPrim &prim=UsdPrim())
Definition: xformable.h:264
USDGEOM_API UsdGeomXformOp AddTransformOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionDouble, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
USDGEOM_API UsdGeomXformOp AddRotateYXZOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp AddXformOp(UsdGeomXformOp::Type const opType, UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionDouble, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp GetScaleOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp GetRotateYOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp AddRotateZOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API bool HasNonEmptyXformOpOrder() const
Returns whether xformOpOrder is non-empty.
USDGEOM_API UsdGeomXformOp AddRotateYZXOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp MakeMatrixXform() const
USDGEOM_API UsdGeomXformOp AddRotateZXYOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdSchemaKind _GetSchemaKind() const override
USDGEOM_API bool SetXformOpOrder(std::vector< UsdGeomXformOp > const &orderedXformOps, bool resetXformStack=false) const
USDGEOM_API UsdGeomXformOp GetRotateXZYOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp GetRotateZXYOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API bool GetTimeSamples(std::vector< double > *times) const
bool GetResetXformStack() const
Returns whether the xformable resets its parent's transformation.
Definition: xformable.h:398
USDGEOM_API UsdGeomXformOp GetRotateYZXOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
Definition: token.h:87
Represents a non-concrete typed schema.
USDGEOM_API UsdGeomXformOp AddRotateYOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API bool GetLocalTransformation(GfMatrix4d *transform, const UsdTimeCode time) const
USDGEOM_API bool GetLocalTransformation(GfMatrix4d *transform, bool *resetsXformStack, const UsdTimeCode time=UsdTimeCode::Default()) const
USDGEOM_API UsdGeomXformOp GetRotateXYZOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp GetRotateXOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp GetRotateZOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
Floating-point precision.
Definition: xformOp.h:141
Definition: prim.h:133
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:457
USDGEOM_API UsdGeomXformOp AddOrientOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
Definition: path.h:290
USDGEOM_API bool GetTimeSamplesInInterval(const GfInterval &interval, std::vector< double > *times) const
USDGEOM_API UsdGeomXformOp AddRotateXZYOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
GA_API const UT_StringHolder transform
static USDGEOM_API UsdGeomXformable Get(const UsdStagePtr &stage, const SdfPath &path)
USDGEOM_API bool IsAttributeIncludedInLocalTransform(const TfToken &attrName) const
static const UsdSchemaKind schemaKind
Definition: xformable.h:258
GLenum GLint GLint * precision
Definition: glcorearb.h:1925
UsdSchemaKind
Definition: common.h:129
USDGEOM_API UsdGeomXformOp GetRotateZYXOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API bool TransformMightBeTimeVarying() const
USDGEOM_API bool GetResetXformStack() const
USDGEOM_API UsdGeomXformOp GetXformOp(UsdGeomXformOp::Type const opType, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
USDGEOM_API UsdGeomXformOp AddTranslateOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionDouble, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
UsdGeomXformable(const UsdSchemaBase &schemaObj)
Definition: xformable.h:272
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
USDGEOM_API UsdGeomXformOp AddScaleOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdAttribute GetXformOpOrderAttr() const
Definition: type.h:64
static USDGEOM_API const TfTokenVector & GetSchemaAttributeNames(bool includeInherited=true)
Type
Enumerates the set of all transformation operation types.
Definition: xformOp.h:115
#define USDGEOM_API
Definition: api.h:40
USDGEOM_API bool TransformMightBeTimeVarying() const
Returns whether the xform value might change over time.
USDGEOM_API std::vector< UsdGeomXformOp > GetOrderedXformOps(bool *resetsXformStack) const
USDGEOM_API UsdGeomXformOp AddRotateXOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API bool GetTimeSamples(std::vector< double > *times) const
USDGEOM_API bool ClearXformOpOrder() const
Clears the local transform stack.
static USDGEOM_API bool IsTransformationAffectedByAttrNamed(const TfToken &attrName)
Definition: value.h:164
USDGEOM_API UsdGeomXformOp GetRotateYXZOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdGeomXformOp GetOrientOp(TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
Precision
Precision with which the value of the tranformation operation is encoded.
Definition: xformOp.h:139
virtual USDGEOM_API ~UsdGeomXformable()
Destructor.