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 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  /// Add a translate operation to the local stack represented by this
483  /// xformable.
484  ///
485  /// \sa AddXformOp()
489  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
490 
491  /// Add a scale operation to the local stack represented by this
492  /// xformable.
493  ///
494  /// \sa AddXformOp()
498  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
499 
500  /// Add a rotation about the X-axis to the local stack represented by
501  /// this xformable.
502  ///
503  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
504  /// \sa AddXformOp()
508  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
509 
510  /// Add a rotation about the YX-axis to the local stack represented by
511  /// this xformable.
512  ///
513  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
514  /// \sa AddXformOp()
518  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
519 
520  /// Add a rotation about the Z-axis to the local stack represented by
521  /// this xformable.
522  ///
523  /// \sa AddXformOp()
527  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
528 
529  /// Add a rotation op with XYZ rotation order to the local stack
530  /// represented by this xformable.
531  ///
532  /// Set the angle value of the resulting UsdGeomXformOp <b>in degrees</b>
533  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
537  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
538 
539  /// Add a rotation op with XZY rotation order to the local stack
540  /// represented by this xformable.
541  ///
542  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
543  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
547  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
548 
549  /// Add a rotation op with YXZ rotation order to the local stack
550  /// represented by this xformable.
551  ///
552  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
553  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
557  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
558 
559  /// Add a rotation op with YZX rotation order to the local stack
560  /// represented by this xformable.
561  ///
562  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
563  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
567  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
568 
569  /// Add a rotation op with ZXY rotation order to the local stack
570  /// represented by this xformable.
571  ///
572  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
573  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
577  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
578 
579  /// Add a rotation op with ZYX rotation order to the local stack
580  /// represented by this xformable.
581  ///
582  /// Set the angle values of the resulting UsdGeomXformOp <b>in degrees</b>
583  /// \sa AddXformOp(), \ref usdGeom_rotationPackingOrder "note on angle packing order"
587  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
588 
589  /// Add a orient op (arbitrary axis/angle rotation) to the local stack
590  /// represented by this xformable.
591  ///
592  /// \sa AddXformOp()
596  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
597 
598  /// Add a tranform op (4x4 matrix transformation) to the local stack
599  /// represented by this xformable.
600  ///
601  /// \sa AddXformOp()
602  ///
603  /// Note: This method takes a precision argument only to be consistent
604  /// with the other types of xformOps. The only valid precision here is
605  /// double since matrix values cannot be encoded in floating-pt precision
606  /// in Sdf.
610  TfToken const &opSuffix = TfToken(), bool isInverseOp=false) const;
611 
612  /// Specify whether this prim's transform should reset the transformation
613  /// stack inherited from its parent prim.
614  ///
615  /// By default, parent transforms are inherited. SetResetXformStack() can be
616  /// called at any time during authoring, but will always add a
617  /// '!resetXformStack!' op as the \em first op in the ordered list, if one
618  /// does not exist already. If one already exists, and \p resetXform is
619  /// false, it will remove all ops upto and including the last
620  /// "!resetXformStack!" op.
622  bool SetResetXformStack(bool resetXform) const;
623 
624  /// Does this prim reset its parent's inherited transformation?
625  ///
626  /// Returns true if "!resetXformStack!" appears \em anywhere in xformOpOrder.
627  /// When this returns true, all ops upto the last "!resetXformStack!" in
628  /// xformOpOrder are ignored when computing the local transformation.
629  ///
631  bool GetResetXformStack() const;
632 
633  /// Reorder the already-existing transform ops on this prim.
634  ///
635  /// All elements in \p orderedXformOps must be valid and represent attributes
636  /// on this prim. Note that it is \em not required that all the existing
637  /// operations be present in \p orderedXformOps, so this method can be used to
638  /// completely change the transformation structure applied to the prim.
639  ///
640  /// If \p resetXformStack is set to true, then "!resetXformOp! will be
641  /// set as the first op in xformOpOrder, to indicate that the prim does
642  /// not inherit its parent's transformation.
643  ///
644  /// \note If you wish to re-specify a prim's transformation completely in
645  /// a stronger layer, you should first call this method with an \em empty
646  /// \p orderedXformOps vector. From there you can call AddXformOp() just as if
647  /// you were authoring to the prim from scratch.
648  ///
649  /// \return false if any of the elements of \p orderedXformOps are not extant
650  /// on this prim, or if an error occurred while authoring the ordering
651  /// metadata. Under either condition, no scene description is authored.
652  ///
653  /// \sa GetOrderedXformOps()
655  bool SetXformOpOrder(std::vector<UsdGeomXformOp> const &orderedXformOps,
656  bool resetXformStack = false) const;
657 
658  /// Return the ordered list of transform operations to be applied to
659  /// this prim, in least-to-most-local order. This is determined by the
660  /// intersection of authored op-attributes and the explicit ordering of
661  /// those attributes encoded in the \c xformOpOrder attribute on this prim.
662  /// Any entries in \c xformOpOrder that do not correspond to valid
663  /// attributes on the xformable prim are skipped and a warning is issued.
664  ///
665  /// A UsdGeomTransformable that has not had any ops added via AddXformOp()
666  /// will return an empty vector.
667  ///
668  /// The function also sets \p resetsXformStack to true if "!resetXformStack!"
669  /// appears \em anywhere in xformOpOrder (i.e., if the prim resets its
670  /// parent's inherited transformation).
671  ///
672  /// \note A coding error is issued if resetsXformStack is NULL.
673  ///
674  /// \sa GetResetXformStack()
676  std::vector<UsdGeomXformOp> GetOrderedXformOps(bool *resetsXformStack) const;
677 
678  /// Clears the local transform stack.
680  bool ClearXformOpOrder() const;
681 
682  /// Clears the existing local transform stack and creates a new xform op of
683  /// type 'transform'.
684  ///
685  /// This API is provided for convenience since this is the most common
686  /// xform authoring operation.
687  ///
688  /// \sa ClearXformOpOrder()
689  /// \sa AddTransformOp()
692 
693  /// Determine whether there is any possibility that this prim's \em local
694  /// transformation may vary over time.
695  ///
696  /// The determination is based on a snapshot of the authored state of the
697  /// op attributes on the prim, and may become invalid in the face of
698  /// further authoring.
700  bool TransformMightBeTimeVarying() const;
701 
702  /// \overload
703  /// Determine whether there is any possibility that this prim's \em local
704  /// transformation may vary over time, using a pre-fetched (cached) list of
705  /// ordered xform ops supplied by the client.
706  ///
707  /// The determination is based on a snapshot of the authored state of the
708  /// op attributes on the prim, and may become invalid in the face of
709  /// further authoring.
712  const std::vector<UsdGeomXformOp> &ops) const;
713 
714  /// Sets \p times to the union of all the timesamples at which xformOps that
715  /// are included in the xformOpOrder attribute are authored.
716  ///
717  /// This clears the \p times vector before accumulating sample times
718  /// from all the xformOps.
719  ///
720  /// \sa UsdAttribute::GetTimeSamples
722  bool GetTimeSamples(std::vector<double> *times) const;
723 
724  /// Sets \p times to the union of all the timesamples in the interval,
725  /// \p interval, at which xformOps that are included in the xformOpOrder
726  /// attribute are authored.
727  ///
728  /// This clears the \p times vector before accumulating sample times
729  /// from all the xformOps.
730  ///
731  /// \sa UsdAttribute::GetTimeSamples
733  bool GetTimeSamplesInInterval(const GfInterval &interval,
734  std::vector<double> *times) const;
735 
736  /// Returns the union of all the timesamples at which the attributes
737  /// belonging to the given \p orderedXformOps are authored.
738  ///
739  /// This clears the \p times vector before accumulating sample times
740  /// from \p orderedXformOps.
741  ///
742  /// \sa UsdGeomXformable::GetTimeSamples
744  static bool GetTimeSamples(
745  std::vector<UsdGeomXformOp> const &orderedXformOps,
746  std::vector<double> *times);
747 
748  /// Returns the union of all the timesamples in the \p interval
749  /// at which the attributes belonging to the given \p orderedXformOps
750  /// are authored.
751  ///
752  /// This clears the \p times vector before accumulating sample times
753  /// from \p orderedXformOps.
754  ///
755  /// \sa UsdGeomXformable::GetTimeSamplesInInterval
757  static bool GetTimeSamplesInInterval(
758  std::vector<UsdGeomXformOp> const &orderedXformOps,
759  const GfInterval &interval,
760  std::vector<double> *times);
761 
762  /// Computes the fully-combined, local-to-parent transformation for this prim.
763  ///
764  /// If a client does not need to manipulate the individual ops themselves,
765  /// and requires only the combined transform on this prim, this method will
766  /// take care of all the data marshalling and linear algebra needed to
767  /// combine the ops into a 4x4 affine transformation matrix, in
768  /// double-precision, regardless of the precision of the op inputs.
769  ///
770  /// \param transform is the output parameter that will hold the local
771  /// transform.
772  /// \param resetsXformStack is the output parameter that informs client
773  /// whether they need to reset the transform stack before pushing
774  /// \p transform.
775  /// \param time is the UsdTimeCode at which to sample the ops.
776  ///
777  /// \return true on success, false if there was an error reading data.
778  ///
779  /// \note A coding error is issued if \p transform or \p resetsXformStack
780  /// is NULL.
781  ///
785  bool *resetsXformStack,
786  const UsdTimeCode time = UsdTimeCode::Default()) const;
787 
788  /// \overload
789  /// Computes the fully-combined, local-to-parent transformation for this
790  /// prim as efficiently as possible, using a pre-fetched (cached) list of
791  /// ordered xform ops supplied by the client.
792  ///
793  /// \param transform is the output parameter that will hold the local
794  /// transform.
795  /// \param resetsXformStack is the output parameter that informs client
796  /// whether they need to reset the transform stack before pushing
797  /// \p transform.
798  /// \param ops is the ordered set of xform ops for this prim, and will be
799  /// queried without any validity checking. Passing this in can save
800  /// significant value-resolution costs, if the client is able to
801  /// retain this data from a call to GetOrderedXformOps().
802  /// \param time is the UsdTimeCode at which to sample the ops.
803  ///
804  /// \return true on success, false if there was an error reading data.
805  ///
806  /// \note A coding error is issued if \p transform or \p resetsXformStack
807  /// is NULL.
808  ///
810  bool GetLocalTransformation(GfMatrix4d *transform,
811  bool *resetsXformStack,
812  const std::vector<UsdGeomXformOp> &ops,
813  const UsdTimeCode time = UsdTimeCode::Default()) const;
814 
815  /// \overload
816  /// This is a static version of the preceding function that takes
817  /// a cached list of ordered xform ops.
818  ///
819  /// \param transform is the output parameter that will hold the local
820  /// transform.
821  /// \param ops is the ordered set of xform ops that must be combined
822  /// together to compute the local transformation.
823  /// \param time is the UsdTimeCode at which to sample the ops.
824  ///
825  /// \return true on success, false if there was an error reading data.
826  ///
828  static bool GetLocalTransformation(GfMatrix4d *transform,
829  std::vector<UsdGeomXformOp> const &ops,
830  const UsdTimeCode time);
831 
832  /// Returns true if the attribute named \p attrName could affect the local
833  /// transformation of an xformable prim.
835  static bool IsTransformationAffectedByAttrNamed(const TfToken &attrName);
836 
837 private:
838  // Extracts the value of the xformOpOrder attribute. Returns false if
839  // the xformOpOrder attribute doesn't exist on the prim (eg. when the prim
840  // type is incompatible or if it's a pure over).
841  bool _GetXformOpOrderValue(VtTokenArray *xformOpOrder) const;
842 
843  // Helper function for getting xformops with or without attribute queries.
844  std::vector<UsdGeomXformOp>
845  _GetOrderedXformOps(bool *resetsXformStack,
846  bool withAttributeQueries) const;
847 };
848 
850 
851 #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: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
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 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 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
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
Floating-point precision.
Definition: xformOp.h:142
Definition: prim.h:135
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:442
USDGEOM_API UsdGeomXformOp AddOrientOp(UsdGeomXformOp::Precision const precision=UsdGeomXformOp::PrecisionFloat, TfToken const &opSuffix=TfToken(), bool isInverseOp=false) const
Definition: path.h:291
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:127
USDGEOM_API bool TransformMightBeTimeVarying() const
USDGEOM_API bool GetResetXformStack() const
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1441
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.
static USDGEOM_API bool IsTransformationAffectedByAttrNamed(const TfToken &attrName)
Definition: value.h:167
Precision
Precision with which the value of the tranformation operation is encoded.
Definition: xformOp.h:140
virtual USDGEOM_API ~UsdGeomXformable()
Destructor.