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  /// | ||
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  /// Sets the vector of times at which xformOp samples have been
407  /// authored in the cached set of xform ops.
408  ///
409  /// \sa UsdXformable::GetTimeSamples
411  bool GetTimeSamples(std::vector<double> *times) const;
412 
413  /// Sets the vector of times in the \p interval at which xformOp
414  /// samples have been authored in the cached set of xform ops.
415  ///
416  /// \sa UsdXformable::GetTimeSamples
418  bool GetTimeSamplesInInterval(const GfInterval &interval,
419  std::vector<double> *times) const;
420 
421  /// Returns whether the given attribute affects the local
422  /// transformation computed for this query.
425  const TfToken &attrName) const;
426 
427  private:
428  // Cached copy of the vector of ordered xform ops.
429  std::vector<UsdGeomXformOp> _xformOps;
430 
431  // Cache whether the xformable has !resetsXformStack! in its
432  // xformOpOrder.
433  bool _resetsXformStack;
434  };
435 
436  /// Add an affine transformation to the local stack represented by this
437  /// Xformable. This will fail if there is already a transform operation
438  /// of the same name in the ordered ops on this prim (i.e. as returned
439  /// by GetOrderedXformOps()), or if an op of the same name exists at all
440  /// on the prim with a different precision than that specified.
441  ///
442  /// The newly created operation will become the most-locally applied
443  /// transformation on the prim, and will appear last in the list
444  /// returned by GetOrderedXformOps(). It is OK to begin authoring values
445  /// to the returned UsdGeomXformOp immediately, interspersed with
446  /// subsequent calls to AddXformOp() - just note the order of application,
447  /// which \em can be changed at any time (and in stronger layers) via
448  /// SetXformOpOrder().
449  ///
450  /// \param opType is the type of transform operation, one of
451  /// \ref UsdGeomXformOp::Type.
452  /// \param precision allows you to specify the precision with which you
453  /// desire to encode the data. This should be one of the values in
454  /// the enum \ref UsdGeomXformOp::Precision .
455  /// \param opSuffix allows you to specify the purpose/meaning of the op in
456  /// the stack. When opSuffix is specified, the associated attribute's
457  /// name is set to "xformOp:<opType>:<opSuffix>".
458  /// \param isInverseOp is used to indicate an inverse transformation
459  /// operation.
460  ///
461  /// \return a UsdGeomXformOp that can be used to author to the operation.
462  /// An error is issued and the returned object will be invalid
463  /// (evaluate to false) if the op being added already exists in
464  /// \ref GetXformOpOrderAttr() "xformOpOrder" or if the
465  /// arguments supplied are invalid.
466  ///
467  /// \note If the attribute associated with the op already exists, but isn't
468  /// of the requested precision, a coding error is issued, but a valid
469  /// xformOp is returned with the existing attribute.
470  ///
475  TfToken const &opSuffix = TfToken(),
476  bool isInverseOp=false) const;
477 
478  /// Add a translate operation to the local stack represented by this
479  /// xformable.
480  ///
481  /// \sa AddXformOp()
485  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
486 
487  /// Add a scale operation to the local stack represented by this
488  /// xformable.
489  ///
490  /// \sa AddXformOp()
494  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
495 
496  /// Add a rotation about the X-axis to the local stack represented by
497  /// this xformable.
498  ///
499  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
500  /// \sa AddXformOp()
504  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
505 
506  /// Add a rotation about the YX-axis to the local stack represented by
507  /// this xformable.
508  ///
509  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
510  /// \sa AddXformOp()
514  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
515 
516  /// Add a rotation about the Z-axis to the local stack represented by
517  /// this xformable.
518  ///
519  /// \sa AddXformOp()
523  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
524 
525  /// Add a rotation op with XYZ rotation order to the local stack
526  /// represented by this xformable.
527  ///
528  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
529  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
533  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
534 
535  /// Add a rotation op with XZY rotation order to the local stack
536  /// represented by this xformable.
537  ///
538  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
539  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
543  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
544 
545  /// Add a rotation op with YXZ rotation order to the local stack
546  /// represented by this xformable.
547  ///
548  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
549  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
553  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
554 
555  /// Add a rotation op with YZX rotation order to the local stack
556  /// represented by this xformable.
557  ///
558  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
559  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
563  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
564 
565  /// Add a rotation op with ZXY rotation order to the local stack
566  /// represented by this xformable.
567  ///
568  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
569  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
573  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
574 
575  /// Add a rotation op with ZYX rotation order to the local stack
576  /// represented by this xformable.
577  ///
578  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
579  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
583  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
584 
585  /// Add a orient op (arbitrary axis/angle rotation) to the local stack
586  /// represented by this xformable.
587  ///
588  /// \sa AddXformOp()
592  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
593 
594  /// Add a tranform op (4x4 matrix transformation) to the local stack
595  /// represented by this xformable.
596  ///
597  /// \sa AddXformOp()
598  ///
599  /// Note: This method takes a precision argument only to be consistent
600  /// with the other types of xformOps. The only valid precision here is
601  /// double since matrix values cannot be encoded in floating-pt precision
602  /// in Sdf.
606  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
607 
608  /// Specify whether this prim's transform should reset the transformation
609  /// stack inherited from its parent prim.
610  ///
611  /// By default, parent transforms are inherited. SetResetXformStack() can be
612  /// called at any time during authoring, but will always add a
613  /// '!resetXformStack!' op as the \em first op in the ordered list, if one
614  /// does not exist already. If one already exists, and \p resetXform is
615  /// false, it will remove all ops upto and including the last
616  /// "!resetXformStack!" op.
618  bool SetResetXformStack(bool resetXform) const;
619 
620  /// Does this prim reset its parent's inherited transformation?
621  ///
622  /// Returns true if "!resetXformStack!" appears \em anywhere in xformOpOrder.
623  /// When this returns true, all ops upto the last "!resetXformStack!" in
624  /// xformOpOrder are ignored when computing the local transformation.
625  ///
627  bool GetResetXformStack() const;
628 
629  /// Reorder the already-existing transform ops on this prim.
630  ///
631  /// All elements in \p orderedXformOps must be valid and represent attributes
632  /// on this prim. Note that it is \em not required that all the existing
633  /// operations be present in \p orderedXformOps, so this method can be used to
634  /// completely change the transformation structure applied to the prim.
635  ///
636  /// If \p resetXformStack is set to true, then "!resetXformOp! will be
637  /// set as the first op in xformOpOrder, to indicate that the prim does
638  /// not inherit its parent's transformation.
639  ///
640  /// \note If you wish to re-specify a prim's transformation completely in
641  /// a stronger layer, you should first call this method with an \em empty
642  /// \p orderedXformOps vector. From there you can call AddXformOp() just as if
643  /// you were authoring to the prim from scratch.
644  ///
645  /// \return false if any of the elements of \p orderedXformOps are not extant
646  /// on this prim, or if an error occurred while authoring the ordering
647  /// metadata. Under either condition, no scene description is authored.
648  ///
649  /// \sa GetOrderedXformOps()
651  bool SetXformOpOrder(std::vector<UsdGeomXformOp> const &orderedXformOps,
652  bool resetXformStack = false) const;
653 
654  /// Return the ordered list of transform operations to be applied to
655  /// this prim, in least-to-most-local order. This is determined by the
656  /// intersection of authored op-attributes and the explicit ordering of
657  /// those attributes encoded in the \c xformOpOrder attribute on this prim.
658  /// Any entries in \c xformOpOrder that do not correspond to valid
659  /// attributes on the xformable prim are skipped and a warning is issued.
660  ///
661  /// A UsdGeomTransformable that has not had any ops added via AddXformOp()
662  /// will return an empty vector.
663  ///
664  /// The function also sets \p resetsXformStack to true if "!resetXformStack!"
665  /// appears \em anywhere in xformOpOrder (i.e., if the prim resets its
666  /// parent's inherited transformation).
667  ///
668  /// \note A coding error is issued if resetsXformStack is NULL.
669  ///
670  /// \sa GetResetXformStack()
672  std::vector<UsdGeomXformOp> GetOrderedXformOps(bool *resetsXformStack) const;
673 
674  /// Clears the local transform stack.
676  bool ClearXformOpOrder() const;
677 
678  /// Clears the existing local transform stack and creates a new xform op of
679  /// type 'transform'.
680  ///
681  /// This API is provided for convenience since this is the most common
682  /// xform authoring operation.
683  ///
684  /// \sa ClearXformOpOrder()
685  /// \sa AddTransformOp()
688 
689  /// Determine whether there is any possibility that this prim's \em local
690  /// transformation may vary over time.
691  ///
692  /// The determination is based on a snapshot of the authored state of the
693  /// op attributes on the prim, and may become invalid in the face of
694  /// further authoring.
696  bool TransformMightBeTimeVarying() const;
697 
698  /// \overload
699  /// Determine whether there is any possibility that this prim's \em local
700  /// transformation may vary over time, using a pre-fetched (cached) list of
701  /// ordered xform ops supplied by the client.
702  ///
703  /// The determination is based on a snapshot of the authored state of the
704  /// op attributes on the prim, and may become invalid in the face of
705  /// further authoring.
708  const std::vector<UsdGeomXformOp> &ops) const;
709 
710  /// Sets \p times to the union of all the timesamples at which xformOps that
711  /// are included in the xformOpOrder attribute are authored.
712  ///
713  /// This clears the \p times vector before accumulating sample times
714  /// from all the xformOps.
715  ///
716  /// \sa UsdAttribute::GetTimeSamples
718  bool GetTimeSamples(std::vector<double> *times) const;
719 
720  /// Sets \p times to the union of all the timesamples in the interval,
721  /// \p interval, at which xformOps that are included in the xformOpOrder
722  /// attribute are authored.
723  ///
724  /// This clears the \p times vector before accumulating sample times
725  /// from all the xformOps.
726  ///
727  /// \sa UsdAttribute::GetTimeSamples
729  bool GetTimeSamplesInInterval(const GfInterval &interval,
730  std::vector<double> *times) const;
731 
732  /// Returns the union of all the timesamples at which the attributes
733  /// belonging to the given \p orderedXformOps are authored.
734  ///
735  /// This clears the \p times vector before accumulating sample times
736  /// from \p orderedXformOps.
737  ///
738  /// \sa UsdGeomXformable::GetTimeSamples
740  static bool GetTimeSamples(
741  std::vector<UsdGeomXformOp> const &orderedXformOps,
742  std::vector<double> *times);
743 
744  /// Returns the union of all the timesamples in the \p interval
745  /// at which the attributes belonging to the given \p orderedXformOps
746  /// are authored.
747  ///
748  /// This clears the \p times vector before accumulating sample times
749  /// from \p orderedXformOps.
750  ///
751  /// \sa UsdGeomXformable::GetTimeSamplesInInterval
753  static bool GetTimeSamplesInInterval(
754  std::vector<UsdGeomXformOp> const &orderedXformOps,
755  const GfInterval &interval,
756  std::vector<double> *times);
757 
758  /// Computes the fully-combined, local-to-parent transformation for this prim.
759  ///
760  /// If a client does not need to manipulate the individual ops themselves,
761  /// and requires only the combined transform on this prim, this method will
762  /// take care of all the data marshalling and linear algebra needed to
763  /// combine the ops into a 4x4 affine transformation matrix, in
764  /// double-precision, regardless of the precision of the op inputs.
765  ///
766  /// \param transform is the output parameter that will hold the local
767  /// transform.
768  /// \param resetsXformStack is the output parameter that informs client
769  /// whether they need to reset the transform stack before pushing
770  /// \p transform.
771  /// \param time is the UsdTimeCode at which to sample the ops.
772  ///
773  /// \return true on success, false if there was an error reading data.
774  ///
775  /// \note A coding error is issued if \p transform or \p resetsXformStack
776  /// is NULL.
777  ///
781  bool *resetsXformStack,
782  const UsdTimeCode time = UsdTimeCode::Default()) const;
783 
784  /// \overload
785  /// Computes the fully-combined, local-to-parent transformation for this
786  /// prim as efficiently as possible, using a pre-fetched (cached) list of
787  /// ordered xform ops supplied by the client.
788  ///
789  /// \param transform is the output parameter that will hold the local
790  /// transform.
791  /// \param resetsXformStack is the output parameter that informs client
792  /// whether they need to reset the transform stack before pushing
793  /// \p transform.
794  /// \param ops is the ordered set of xform ops for this prim, and will be
795  /// queried without any validity checking. Passing this in can save
796  /// significant value-resolution costs, if the client is able to
797  /// retain this data from a call to GetOrderedXformOps().
798  /// \param time is the UsdTimeCode at which to sample the ops.
799  ///
800  /// \return true on success, false if there was an error reading data.
801  ///
802  /// \note A coding error is issued if \p transform or \p resetsXformStack
803  /// is NULL.
804  ///
806  bool GetLocalTransformation(GfMatrix4d *transform,
807  bool *resetsXformStack,
808  const std::vector<UsdGeomXformOp> &ops,
809  const UsdTimeCode time = UsdTimeCode::Default()) const;
810 
811  /// \overload
812  /// This is a static version of the preceding function that takes
813  /// a cached list of ordered xform ops.
814  ///
815  /// \param transform is the output parameter that will hold the local
816  /// transform.
817  /// \param ops is the ordered set of xform ops that must be combined
818  /// together to compute the local transformation.
819  /// \param time is the UsdTimeCode at which to sample the ops.
820  ///
821  /// \return true on success, false if there was an error reading data.
822  ///
824  static bool GetLocalTransformation(GfMatrix4d *transform,
825  std::vector<UsdGeomXformOp> const &ops,
826  const UsdTimeCode time);
827 
828  /// Returns true if the attribute named \p attrName could affect the local
829  /// transformation of an xformable prim.
831  static bool IsTransformationAffectedByAttrNamed(const TfToken &attrName);
832 
833 private:
834  // Extracts the value of the xformOpOrder attribute. Returns false if
835  // the xformOpOrder attribute doesn't exist on the prim (eg. when the prim
836  // type is incompatible or if it's a pure over).
837  bool _GetXformOpOrderValue(VtTokenArray *xformOpOrder) const;
838 
839  // Helper function for getting xformops with or without attribute queries.
840  std::vector<UsdGeomXformOp>
841  _GetOrderedXformOps(bool *resetsXformStack,
842  bool withAttributeQueries) const;
843 };
844 
846 
847 #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:398
Definition: token.h:87
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:127
Definition: prim.h:132
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:446
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:288
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:1346
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: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:174
Precision
Precision with which the value of the tranformation operation is encoded.
Definition: xformOp.h:140
virtual USDGEOM_API ~UsdGeomXformable()
Destructor.