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.cpp CreateMatrixWithDefault
239 ///
240 /// #2. Creating the simple SRT from the example above
241 /// \snippet examples.cpp CreateExampleSRT
242 ///
243 /// #3. Creating a parameterized SRT with pivot using UsdGeomXformCommonAPI
244 /// \snippet examples.cpp CreateSRTWithDefaults
245 ///
246 /// #4. Creating a rotate-only pivot transform with animated
247 /// rotation and translation
248 /// \snippet examples.cpp CreateAnimatedTransform
249 ///
250 ///
251 ///
253 {
254 public:
255  /// Compile time constant representing what kind of schema this class is.
256  ///
257  /// \sa UsdSchemaType
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 type of schema this class belongs to.
304  ///
305  /// \sa UsdSchemaType
307  UsdSchemaType _GetSchemaType() 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  /// \n C++ Type: VtArray<TfToken>
336  /// \n Usd Type: SdfValueTypeNames->TokenArray
337  /// \n Variability: SdfVariabilityUniform
338  /// \n Fallback Value: No Fallback
341 
342  /// See GetXformOpOrderAttr(), and also
343  /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
344  /// If specified, author \p defaultValue as the attribute's default,
345  /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
346  /// the default for \p writeSparsely is \c false.
348  UsdAttribute CreateXformOpOrderAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
349 
350 public:
351  // ===================================================================== //
352  // Feel free to add custom code below this line, it will be preserved by
353  // the code generator.
354  //
355  // Just remember to:
356  // - Close the class declaration with };
357  // - Close the namespace with PXR_NAMESPACE_CLOSE_SCOPE
358  // - Close the include guard with #endif
359  // ===================================================================== //
360  // --(BEGIN CUSTOM CODE)--
361 
362  /// \class XformQuery
363  ///
364  /// Helper class that caches the ordered vector of UsGeomXformOps that
365  /// contribute to the local transformation of an xformable prim
366  ///
367  /// Internally, the class initializes UsdAttributeQuery objects for the
368  /// xformOp attributes in order to facilitate efficient querying of their
369  /// values.
370  ///
371  /// \note This object does not listen to change notification. If a
372  /// consumer is holding onto a UsdGeomXformable::XformQuery object, it is
373  /// their responsibility to dispose of it, in response to a resync
374  /// change to the associated xformOp attributes. The class provides the
375  /// convenience method IncludesXformOpAttr for this purpose.
376  ///
377  class XformQuery {
378  public:
380  _resetsXformStack(false)
381  { }
382 
383  /// Constructs an XformQuery object for the given xformable prim.
384  /// Caches the ordered xformOps and initializes an UsdAttributeQuery
385  /// internally for all the associated attributes.
387  XformQuery(const UsdGeomXformable &xformable);
388 
389  /// Utilizes the internally cached UsdAttributeQuery's to efficiently
390  /// compute the transform value at the given \p time.
393  const UsdTimeCode time) const;
394 
395  /// Returns whether the xformable resets its parent's transformation.
396  bool GetResetXformStack() const {
397  return _resetsXformStack;
398  }
399 
400  /// Returns whether the xform value might change over time.
402  bool TransformMightBeTimeVarying() const;
403 
404  /// Sets the vector of times at which xformOp samples have been
405  /// authored in the cached set of xform ops.
406  ///
407  /// \sa UsdXformable::GetTimeSamples
409  bool GetTimeSamples(std::vector<double> *times) const;
410 
411  /// Sets the vector of times in the \p interval at which xformOp
412  /// samples have been authored in the cached set of xform ops.
413  ///
414  /// \sa UsdXformable::GetTimeSamples
416  bool GetTimeSamplesInInterval(const GfInterval &interval,
417  std::vector<double> *times) const;
418 
419  /// Returns whether the given attribute affects the local
420  /// transformation computed for this query.
423  const TfToken &attrName) const;
424 
425  private:
426  // Cached copy of the vector of ordered xform ops.
427  std::vector<UsdGeomXformOp> _xformOps;
428 
429  // Cache whether the xformable has !resetsXformStack! in its
430  // xformOpOrder.
431  bool _resetsXformStack;
432  };
433 
434  /// Add an affine transformation to the local stack represented by this
435  /// Xformable. This will fail if there is already a transform operation
436  /// of the same name in the ordered ops on this prim (i.e. as returned
437  /// by GetOrderedXformOps()), or if an op of the same name exists at all
438  /// on the prim with a different precision than that specified.
439  ///
440  /// The newly created operation will become the most-locally applied
441  /// transformation on the prim, and will appear last in the list
442  /// returned by GetOrderedXformOps(). It is OK to begin authoring values
443  /// to the returned UsdGeomXformOp immediately, interspersed with
444  /// subsequent calls to AddXformOp() - just note the order of application,
445  /// which \em can be changed at any time (and in stronger layers) via
446  /// SetXformOpOrder().
447  ///
448  /// \param opType is the type of transform operation, one of
449  /// \ref UsdGeomXformOp::Type.
450  /// \param precision allows you to specify the precision with which you
451  /// desire to encode the data. This should be one of the values in
452  /// the enum \ref UsdGeomXformOp::Precision .
453  /// \param opSuffix allows you to specify the purpose/meaning of the op in
454  /// the stack. When opSuffix is specified, the associated attribute's
455  /// name is set to "xformOp:<opType>:<opSuffix>".
456  /// \param isInverseOp is used to indicate an inverse transformation
457  /// operation.
458  ///
459  /// \return a UsdGeomXformOp that can be used to author to the operation.
460  /// An error is issued and the returned object will be invalid
461  /// (evaluate to false) if the op being added already exists in
462  /// \ref GetXformOpOrderAttr() "xformOpOrder" or if the
463  /// arguments supplied are invalid.
464  ///
465  /// \note If the attribute associated with the op already exists, but isn't
466  /// of the requested precision, a coding error is issued, but a valid
467  /// xformOp is returned with the existing attribute.
468  ///
473  TfToken const &opSuffix = TfToken(),
474  bool isInverseOp=false) const;
475 
476  /// Add a translate operation to the local stack represented by this
477  /// xformable.
478  ///
479  /// \sa AddXformOp()
483  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
484 
485  /// Add a scale operation to the local stack represented by this
486  /// xformable.
487  ///
488  /// \sa AddXformOp()
492  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
493 
494  /// Add a rotation about the X-axis to the local stack represented by
495  /// this xformable.
496  ///
497  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
498  /// \sa AddXformOp()
502  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
503 
504  /// Add a rotation about the YX-axis to the local stack represented by
505  /// this xformable.
506  ///
507  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
508  /// \sa AddXformOp()
512  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
513 
514  /// Add a rotation about the Z-axis to the local stack represented by
515  /// this xformable.
516  ///
517  /// \sa AddXformOp()
521  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
522 
523  /// Add a rotation op with XYZ rotation order to the local stack
524  /// represented by this xformable.
525  ///
526  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
527  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
531  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
532 
533  /// Add a rotation op with XZY rotation order to the local stack
534  /// represented by this xformable.
535  ///
536  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
537  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
541  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
542 
543  /// Add a rotation op with YXZ rotation order to the local stack
544  /// represented by this xformable.
545  ///
546  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
547  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
551  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
552 
553  /// Add a rotation op with YZX rotation order to the local stack
554  /// represented by this xformable.
555  ///
556  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
557  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
561  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
562 
563  /// Add a rotation op with ZXY rotation order to the local stack
564  /// represented by this xformable.
565  ///
566  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
567  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
571  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
572 
573  /// Add a rotation op with ZYX rotation order to the local stack
574  /// represented by this xformable.
575  ///
576  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
577  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
581  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
582 
583  /// Add a orient op (arbitrary axis/angle rotation) to the local stack
584  /// represented by this xformable.
585  ///
586  /// \sa AddXformOp()
590  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
591 
592  /// Add a tranform op (4x4 matrix transformation) to the local stack
593  /// represented by this xformable.
594  ///
595  /// \sa AddXformOp()
596  ///
597  /// Note: This method takes a precision argument only to be consistent
598  /// with the other types of xformOps. The only valid precision here is
599  /// double since matrix values cannot be encoded in floating-pt precision
600  /// in Sdf.
604  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
605 
606  /// Specify whether this prim's transform should reset the transformation
607  /// stack inherited from its parent prim.
608  ///
609  /// By default, parent transforms are inherited. SetResetXformStack() can be
610  /// called at any time during authoring, but will always add a
611  /// '!resetXformStack!' op as the \em first op in the ordered list, if one
612  /// does not exist already. If one already exists, and \p resetXform is
613  /// false, it will remove all ops upto and including the last
614  /// "!resetXformStack!" op.
616  bool SetResetXformStack(bool resetXform) const;
617 
618  /// Does this prim reset its parent's inherited transformation?
619  ///
620  /// Returns true if "!resetXformStack!" appears \em anywhere in xformOpOrder.
621  /// When this returns true, all ops upto the last "!resetXformStack!" in
622  /// xformOpOrder are ignored when computing the local transformation.
623  ///
625  bool GetResetXformStack() const;
626 
627  /// Reorder the already-existing transform ops on this prim.
628  ///
629  /// All elements in \p orderedXformOps must be valid and represent attributes
630  /// on this prim. Note that it is \em not required that all the existing
631  /// operations be present in \p orderedXformOps, so this method can be used to
632  /// completely change the transformation structure applied to the prim.
633  ///
634  /// If \p resetXformStack is set to true, then "!resetXformOp! will be
635  /// set as the first op in xformOpOrder, to indicate that the prim does
636  /// not inherit its parent's transformation.
637  ///
638  /// \note If you wish to re-specify a prim's transformation completely in
639  /// a stronger layer, you should first call this method with an \em empty
640  /// \p orderedXformOps vector. From there you can call AddXformOp() just as if
641  /// you were authoring to the prim from scratch.
642  ///
643  /// \return false if any of the elements of \p orderedXformOps are not extant
644  /// on this prim, or if an error occurred while authoring the ordering
645  /// metadata. Under either condition, no scene description is authored.
646  ///
647  /// \sa GetOrderedXformOps()
649  bool SetXformOpOrder(std::vector<UsdGeomXformOp> const &orderedXformOps,
650  bool resetXformStack = false) const;
651 
652  /// Return the ordered list of transform operations to be applied to
653  /// this prim, in least-to-most-local order. This is determined by the
654  /// intersection of authored op-attributes and the explicit ordering of
655  /// those attributes encoded in the \c xformOpOrder attribute on this prim.
656  /// Any entries in \c xformOpOrder that do not correspond to valid
657  /// attributes on the xformable prim are skipped and a warning is issued.
658  ///
659  /// A UsdGeomTransformable that has not had any ops added via AddXformOp()
660  /// will return an empty vector.
661  ///
662  /// The function also sets \p resetsXformStack to true if "!resetXformStack!"
663  /// appears \em anywhere in xformOpOrder (i.e., if the prim resets its
664  /// parent's inherited transformation).
665  ///
666  /// \note A coding error is issued if resetsXformStack is NULL.
667  ///
668  /// \sa GetResetXformStack()
670  std::vector<UsdGeomXformOp> GetOrderedXformOps(bool *resetsXformStack) const;
671 
672  /// Clears the local transform stack.
674  bool ClearXformOpOrder() const;
675 
676  /// Clears the existing local transform stack and creates a new xform op of
677  /// type 'transform'.
678  ///
679  /// This API is provided for convenience since this is the most common
680  /// xform authoring operation.
681  ///
682  /// \sa ClearXformOpOrder()
683  /// \sa AddTransformOp()
686 
687  /// Determine whether there is any possibility that this prim's \em local
688  /// transformation may vary over time.
689  ///
690  /// The determination is based on a snapshot of the authored state of the
691  /// op attributes on the prim, and may become invalid in the face of
692  /// further authoring.
694  bool TransformMightBeTimeVarying() const;
695 
696  /// \overload
697  /// Determine whether there is any possibility that this prim's \em local
698  /// transformation may vary over time, using a pre-fetched (cached) list of
699  /// ordered xform ops supplied by the client.
700  ///
701  /// The determination is based on a snapshot of the authored state of the
702  /// op attributes on the prim, and may become invalid in the face of
703  /// further authoring.
706  const std::vector<UsdGeomXformOp> &ops) const;
707 
708  /// Sets \p times to the union of all the timesamples at which xformOps that
709  /// are included in the xformOpOrder attribute are authored.
710  ///
711  /// This clears the \p times vector before accumulating sample times
712  /// from all the xformOps.
713  ///
714  /// \sa UsdAttribute::GetTimeSamples
716  bool GetTimeSamples(std::vector<double> *times) const;
717 
718  /// Sets \p times to the union of all the timesamples in the interval,
719  /// \p interval, at which xformOps that are included in the xformOpOrder
720  /// attribute are authored.
721  ///
722  /// This clears the \p times vector before accumulating sample times
723  /// from all the xformOps.
724  ///
725  /// \sa UsdAttribute::GetTimeSamples
727  bool GetTimeSamplesInInterval(const GfInterval &interval,
728  std::vector<double> *times) const;
729 
730  /// Returns the union of all the timesamples at which the attributes
731  /// belonging to the given \p orderedXformOps are authored.
732  ///
733  /// This clears the \p times vector before accumulating sample times
734  /// from \p orderedXformOps.
735  ///
736  /// \sa UsdGeomXformable::GetTimeSamples
738  static bool GetTimeSamples(
739  std::vector<UsdGeomXformOp> const &orderedXformOps,
740  std::vector<double> *times);
741 
742  /// Returns the union of all the timesamples in the \p interval
743  /// at which the attributes belonging to the given \p orderedXformOps
744  /// are authored.
745  ///
746  /// This clears the \p times vector before accumulating sample times
747  /// from \p orderedXformOps.
748  ///
749  /// \sa UsdGeomXformable::GetTimeSamplesInInterval
751  static bool GetTimeSamplesInInterval(
752  std::vector<UsdGeomXformOp> const &orderedXformOps,
753  const GfInterval &interval,
754  std::vector<double> *times);
755 
756  /// Computes the fully-combined, local-to-parent transformation for this prim.
757  ///
758  /// If a client does not need to manipulate the individual ops themselves,
759  /// and requires only the combined transform on this prim, this method will
760  /// take care of all the data marshalling and linear algebra needed to
761  /// combine the ops into a 4x4 affine transformation matrix, in
762  /// double-precision, regardless of the precision of the op inputs.
763  ///
764  /// \param transform is the output parameter that will hold the local
765  /// transform.
766  /// \param resetsXformStack is the output parameter that informs client
767  /// whether they need to reset the transform stack before pushing
768  /// \p transform.
769  /// \param time is the UsdTimeCode at which to sample the ops.
770  ///
771  /// \return true on success, false if there was an error reading data.
772  ///
773  /// \note A coding error is issued if \p transform or \p resetsXformStack
774  /// is NULL.
775  ///
779  bool *resetsXformStack,
780  const UsdTimeCode time = UsdTimeCode::Default()) const;
781 
782  /// \overload
783  /// Computes the fully-combined, local-to-parent transformation for this
784  /// prim as efficiently as possible, using a pre-fetched (cached) list of
785  /// ordered xform ops supplied by the client.
786  ///
787  /// \param transform is the output parameter that will hold the local
788  /// transform.
789  /// \param resetsXformStack is the output parameter that informs client
790  /// whether they need to reset the transform stack before pushing
791  /// \p transform.
792  /// \param ops is the ordered set of xform ops for this prim, and will be
793  /// queried without any validity checking. Passing this in can save
794  /// significant value-resolution costs, if the client is able to
795  /// retain this data from a call to GetOrderedXformOps().
796  /// \param time is the UsdTimeCode at which to sample the ops.
797  ///
798  /// \return true on success, false if there was an error reading data.
799  ///
800  /// \note A coding error is issued if \p transform or \p resetsXformStack
801  /// is NULL.
802  ///
804  bool GetLocalTransformation(GfMatrix4d *transform,
805  bool *resetsXformStack,
806  const std::vector<UsdGeomXformOp> &ops,
807  const UsdTimeCode time = UsdTimeCode::Default()) const;
808 
809  /// \overload
810  /// This is a static version of the preceding function that takes
811  /// a cached list of ordered xform ops.
812  ///
813  /// \param transform is the output parameter that will hold the local
814  /// transform.
815  /// \param ops is the ordered set of xform ops that must be combined
816  /// together to compute the local transformation.
817  /// \param time is the UsdTimeCode at which to sample the ops.
818  ///
819  /// \return true on success, false if there was an error reading data.
820  ///
822  static bool GetLocalTransformation(GfMatrix4d *transform,
823  std::vector<UsdGeomXformOp> const &ops,
824  const UsdTimeCode time);
825 
826  /// Returns true if the attribute named \p attrName could affect the local
827  /// transformation of an xformable prim.
829  static bool IsTransformationAffectedByAttrNamed(const TfToken &attrName);
830 
831 private:
832  // Extracts the value of the xformOpOrder attribute. Returns false if
833  // the xformOpOrder attribute doesn't exist on the prim (eg. when the prim
834  // type is incompatible or if it's a pure over).
835  bool _GetXformOpOrderValue(VtTokenArray *xformOpOrder) const;
836 
837  // Helper function for getting xformops with or without attribute queries.
838  std::vector<UsdGeomXformOp>
839  _GetOrderedXformOps(bool *resetsXformStack,
840  bool withAttributeQueries) const;
841 };
842 
844 
845 #endif
USDGEOM_API UsdAttribute CreateXformOpOrderAttr(VtValue const &defaultValue=VtValue(), bool writeSparsely=false) const
USDGEOM_API bool SetResetXformStack(bool resetXform) const
Double precision.
Definition: xformOp.h:141
static constexpr UsdTimeCode Default()
Definition: timeCode.h:113
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
GLuint GLenum GLenum transform
Definition: glew.h:14742
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
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 AddRotateZOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
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 bool SetXformOpOrder(std::vector< UsdGeomXformOp > const &orderedXformOps, bool resetXformStack=false) const
static const UsdSchemaType schemaType
Definition: xformable.h:258
USDGEOM_API bool GetTimeSamples(std::vector< double > *times) const
bool GetResetXformStack() const
Returns whether the xformable resets its parent's transformation.
Definition: xformable.h:396
Definition: token.h:89
USDGEOM_API UsdGeomXformOp AddRotateYOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
USDGEOM_API UsdSchemaType _GetSchemaType() const override
USDGEOM_API bool GetLocalTransformation(GfMatrix4d *transform, const UsdTimeCode time) const
USDGEOM_API bool GetLocalTransformation(GfMatrix4d *transform, bool *resetsXformStack, const UsdTimeCode time=UsdTimeCode::Default()) const
Floating-point precision.
Definition: xformOp.h:142
UsdSchemaType
Definition: common.h:149
Definition: prim.h:131
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:438
Represents a non-concrete typed schema.
USDGEOM_API UsdGeomXformOp AddOrientOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
Definition: path.h:287
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
static USDGEOM_API UsdGeomXformable Get(const UsdStagePtr &stage, const SdfPath &path)
USDGEOM_API bool IsAttributeIncludedInLocalTransform(const TfToken &attrName) const
GLsizei const GLchar *const * path
Definition: glew.h:6461
USDGEOM_API bool TransformMightBeTimeVarying() const
USDGEOM_API bool GetResetXformStack() const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1245
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:83
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:70
static USDGEOM_API const TfTokenVector & GetSchemaAttributeNames(bool includeInherited=true)
Type
Enumerates the set of all transformation operation types.
Definition: xformOp.h:116
#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.
GLenum GLint GLint * precision
Definition: glew.h:3500
static USDGEOM_API bool IsTransformationAffectedByAttrNamed(const TfToken &attrName)
Definition: value.h:182
Precision
Precision with which the value of the tranformation operation is encoded.
Definition: xformOp.h:140
virtual USDGEOM_API ~UsdGeomXformable()
Destructor.