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_PRIMVARSAPI_H
25 #define USDGEOM_GENERATED_PRIMVARSAPI_H
26 
27 /// \file usdGeom/primvarsAPI.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/usdGeom/api.h"
31 #include "pxr/usd/usd/apiSchemaBase.h"
32 #include "pxr/usd/usd/prim.h"
33 #include "pxr/usd/usd/stage.h"
34 
35 #include "pxr/usd/usdGeom/primvar.h"
36 
37 #include "pxr/base/vt/value.h"
38 
39 #include "pxr/base/gf/vec3d.h"
40 #include "pxr/base/gf/vec3f.h"
41 #include "pxr/base/gf/matrix4d.h"
42 
43 #include "pxr/base/tf/token.h"
44 #include "pxr/base/tf/type.h"
45 
46 PXR_NAMESPACE_OPEN_SCOPE
47 
48 class SdfAssetPath;
49 
50 // -------------------------------------------------------------------------- //
51 // PRIMVARSAPI                                                                //
52 // -------------------------------------------------------------------------- //
53 
54 /// \class UsdGeomPrimvarsAPI
55 ///
56 /// UsdGeomPrimvarsAPI encodes geometric "primitive variables",
57 /// as UsdGeomPrimvar, which interpolate across a primitive's topology,
58 /// can override shader inputs, and inherit down namespace.
59 ///
60 /// \section usdGeom_PrimvarFetchingAPI Which Method to Use to Retrieve Primvars
61 ///
62 /// While creating primvars is unambiguous (CreatePrimvar()), there are quite
63 /// a few methods available for retrieving primvars, making it potentially
64 /// confusing knowing which one to use.  Here are some guidelines:
65 ///
66 /// \li If you are populating a GUI with the primvars already available for
67 /// authoring values on a prim, use GetPrimvars().
68 /// \li If you want all of the "useful" (e.g. to a renderer) primvars
69 /// available at a prim, including those inherited from ancestor prims, use
70 /// FindPrimvarsWithInheritance().  Note that doing so individually for many
71 /// prims will be inefficient.
72 /// \li To find a particular primvar defined directly on a prim, which may
73 /// or may not provide a value, use GetPrimvar().
74 /// \li To find a particular primvar defined on a prim or inherited from
75 /// ancestors, which may or may not provide a value, use
76 /// FindPrimvarWithInheritance().
77 /// \li To *efficiently* query for primvars using the overloads of
78 /// FindPrimvarWithInheritance() and FindPrimvarsWithInheritance(), one
79 /// must first cache the results of FindIncrementallyInheritablePrimvars() for
80 /// each non-leaf prim on the stage.
81 ///
82 class UsdGeomPrimvarsAPI : public UsdAPISchemaBase
83 {
84 public:
85     /// Compile time constant representing what kind of schema this class is.
86     ///
87     /// \sa UsdSchemaKind
88     static const UsdSchemaKind schemaKind = UsdSchemaKind::NonAppliedAPI;
89 
90     /// Construct a UsdGeomPrimvarsAPI on UsdPrim \p prim .
91     /// Equivalent to UsdGeomPrimvarsAPI::Get(prim.GetStage(), prim.GetPath())
92     /// for a \em valid \p prim, but will not immediately throw an error for
93     /// an invalid \p prim
94     explicit UsdGeomPrimvarsAPI(const UsdPrim& prim=UsdPrim())
UsdAPISchemaBase(prim)95         : UsdAPISchemaBase(prim)
96     {
97     }
98 
99     /// Construct a UsdGeomPrimvarsAPI on the prim held by \p schemaObj .
100     /// Should be preferred over UsdGeomPrimvarsAPI(schemaObj.GetPrim()),
101     /// as it preserves SchemaBase state.
UsdGeomPrimvarsAPI(const UsdSchemaBase & schemaObj)102     explicit UsdGeomPrimvarsAPI(const UsdSchemaBase& schemaObj)
103         : UsdAPISchemaBase(schemaObj)
104     {
105     }
106 
107     /// Destructor.
108     USDGEOM_API
109     virtual ~UsdGeomPrimvarsAPI();
110 
111     /// Return a vector of names of all pre-declared attributes for this schema
112     /// class and all its ancestor classes.  Does not include attributes that
113     /// may be authored by custom/extended methods of the schemas involved.
114     USDGEOM_API
115     static const TfTokenVector &
116     GetSchemaAttributeNames(bool includeInherited=true);
117 
118     /// Return a UsdGeomPrimvarsAPI holding the prim adhering to this
119     /// schema at \p path on \p stage.  If no prim exists at \p path on
120     /// \p stage, or if the prim at that path does not adhere to this schema,
121     /// return an invalid schema object.  This is shorthand for the following:
122     ///
123     /// \code
124     /// UsdGeomPrimvarsAPI(stage->GetPrimAtPath(path));
125     /// \endcode
126     ///
127     USDGEOM_API
128     static UsdGeomPrimvarsAPI
129     Get(const UsdStagePtr &stage, const SdfPath &path);
130 
131 
132 protected:
133     /// Returns the kind of schema this class belongs to.
134     ///
135     /// \sa UsdSchemaKind
136     USDGEOM_API
137     UsdSchemaKind _GetSchemaKind() const override;
138 
139 private:
140     // needs to invoke _GetStaticTfType.
141     friend class UsdSchemaRegistry;
142     USDGEOM_API
143     static const TfType &_GetStaticTfType();
144 
145     static bool _IsTypedSchema();
146 
147     // override SchemaBase virtuals.
148     USDGEOM_API
149     const TfType &_GetTfType() const override;
150 
151 public:
152     // ===================================================================== //
153     // Feel free to add custom code below this line, it will be preserved by
154     // the code generator.
155     //
156     // Just remember to:
157     //  - Close the class declaration with };
158     //  - Close the namespace with PXR_NAMESPACE_CLOSE_SCOPE
159     //  - Close the include guard with #endif
160     // ===================================================================== //
161     // --(BEGIN CUSTOM CODE)--
162 
163     /// Author scene description to create an attribute on this prim that
164     /// will be recognized as Primvar (i.e. will present as a valid
165     /// UsdGeomPrimvar).
166     ///
167     /// The name of the created attribute may or may not be the specified
168     /// \p name, due to the possible need to apply property namespacing
169     /// for primvars.  See \ref Usd_Creating_and_Accessing_Primvars
170     /// for more information.  Creation may fail and return an invalid
171     /// Primvar if \p name contains a reserved keyword, such as the
172     /// "indices" suffix we use for indexed primvars.
173     ///
174     /// The behavior with respect to the provided \p typeName
175     /// is the same as for UsdAttributes::Create(), and
176     /// \p interpolation and \p elementSize are as described in
177     /// UsdGeomPrimvar::GetInterpolation() and UsdGeomPrimvar::GetElementSize().
178     ///
179     /// If \p interpolation and/or \p elementSize are left unspecified, we
180     /// will author no opinions for them, which means any (strongest) opinion
181     /// already authored in any contributing layer for these fields will
182     /// become the Primvar's values, or the fallbacks if no opinions
183     /// have been authored.
184     ///
185     /// \return an invalid UsdGeomPrimvar if we failed to create a valid
186     /// attribute, a valid UsdGeomPrimvar otherwise.  It is not an
187     /// error to create over an existing, compatible attribute.
188     ///
189     /// \sa UsdPrim::CreateAttribute(), UsdGeomPrimvar::IsPrimvar()
190     USDGEOM_API
191     UsdGeomPrimvar CreatePrimvar(const TfToken& name,
192                                  const SdfValueTypeName &typeName,
193                                  const TfToken& interpolation = TfToken(),
194                                  int elementSize = -1) const;
195 
196     /// Author scene description to create an attribute and authoring a \p value
197     /// on this prim that will be recognized as a Primvar (i.e. will present as
198     /// a valid UsdGeomPrimvar). Note that unlike CreatePrimvar using this API
199     /// explicitly authors a block for the indices attr associated with the
200     /// primvar, thereby blocking any indices set in any weaker layers.
201     ///
202     /// \return an invalid UsdGeomPrimvar on error, a valid UsdGeomPrimvar
203     /// otherwise. It is fine to call this method multiple times, and in
204     /// different UsdEditTargets, even if there is an existing primvar of the
205     /// same name, indexed or not.
206     ///
207     /// \sa CreatePrimvar(), CreateIndexedPrimvar(), UsdPrim::CreateAttribute(),
208     /// UsdGeomPrimvar::IsPrimvar()
209     template <typename T>
210     UsdGeomPrimvar CreateNonIndexedPrimvar(
211             const TfToken& name,
212             const SdfValueTypeName &typeName,
213             const T &value,
214             const TfToken &interpolation = TfToken(),
215             int elementSize = -1,
216             UsdTimeCode time = UsdTimeCode::Default()) const
217     {
218         UsdGeomPrimvar primvar =
219             CreatePrimvar(name, typeName, interpolation, elementSize);
220 
221         primvar.GetAttr().Set(value, time);
222         primvar.BlockIndices();
223         return primvar;
224     }
225 
226     /// Author scene description to create an attribute and authoring a \p value
227     /// on this prim that will be recognized as an indexed Primvar with \p
228     /// indices appropriately set (i.e. will present as a valid UsdGeomPrimvar).
229     ///
230     /// \return an invalid UsdGeomPrimvar on error, a valid UsdGeomPrimvar
231     /// otherwise. It is fine to call this method multiple times, and in
232     /// different UsdEditTargets, even if there is an existing primvar of the
233     /// same name, indexed or not.
234     ///
235     /// \sa CreatePrimvar(), CreateNonIndexedPrimvar(),
236     /// UsdPrim::CreateAttribute(), UsdGeomPrimvar::IsPrimvar()
237     template <typename T>
238     UsdGeomPrimvar CreateIndexedPrimvar(
239             const TfToken& name,
240             const SdfValueTypeName &typeName,
241             const T &value,
242             const VtIntArray &indices,
243             const TfToken &interpolation = TfToken(),
244             int elementSize = -1,
245             UsdTimeCode time = UsdTimeCode::Default()) const
246     {
247         UsdGeomPrimvar primvar =
248             CreatePrimvar(name, typeName, interpolation, elementSize);
249 
250         primvar.GetAttr().Set(value, time);
251         primvar.SetIndices(indices, time);
252         return primvar;
253     }
254 
255     /// Author scene description to delete an attribute on this prim that
256     /// was recognized as Primvar (i.e. will present as a valid UsdGeomPrimvar),
257     /// <em>in the current UsdEditTarget</em>.
258     ///
259     /// Because this method can only remove opinions about the primvar
260     /// from the current EditTarget, you may generally find it more useful to
261     /// use BlockPrimvar() which will ensure that all values from the EditTarget
262     /// and weaker layers for the primvar and its indices will be ignored.
263     ///
264     /// Removal may fail and return false if \p name contains a reserved
265     /// keyword, such as the "indices" suffix we use for indexed primvars.
266     ///
267     /// Note this will also remove the indices attribute associated with an
268     /// indiced primvar.
269     ///
270     /// \return true if UsdGeomPrimvar and indices attribute was successfully
271     /// removed, false otherwise.
272     ///
273     /// \sa UsdPrim::RemoveProperty())
274     USDGEOM_API
275     bool RemovePrimvar(const TfToken& name);
276 
277     /// Remove all time samples on the primvar and its associated indices attr,
278     /// and author a *block* \c default value. This will cause authored opinions
279     /// in weaker layers to be ignored.
280     ///
281     /// \sa UsdAttribute::Block(), UsdGeomPrimvar::BlockIndices
282     USDGEOM_API
283     void BlockPrimvar(const TfToken& name);
284 
285     /// Return the Primvar object named by \p name, which will
286     /// be valid if a Primvar attribute definition already exists.
287     ///
288     /// Name lookup will account for Primvar namespacing, which means
289     /// that this method will succeed in some cases where
290     /// \code
291     /// UsdGeomPrimvar(prim->GetAttribute(name))
292     /// \endcode
293     /// will not, unless \p name is properly namespace prefixed.
294     ///
295     /// \note Just because a Primvar is valid and defined, and *even if* its
296     /// underlying UsdAttribute (GetAttr()) answers HasValue() affirmatively,
297     /// one must still check the return value of Get(), due to the potential
298     /// of time-varying value blocks (see \ref Usd_AttributeBlocking).
299     ///
300     /// \sa HasPrimvar(), \ref usdGeom_PrimvarFetchingAPI
301     USDGEOM_API
302     UsdGeomPrimvar GetPrimvar(const TfToken &name) const;
303 
304     /// Return valid UsdGeomPrimvar objects for all defined Primvars on
305     /// this prim, similarly to UsdPrim::GetAttributes().
306     ///
307     /// The returned primvars may not possess any values, and therefore not
308     /// be useful to some clients. For the primvars useful for inheritance
309     /// computations, see GetPrimvarsWithAuthoredValues(), and for primvars
310     /// useful for direct consumption, see GetPrimvarsWithValues().
311     ///
312     /// \sa \ref usdGeom_PrimvarFetchingAPI
313     USDGEOM_API
314     std::vector<UsdGeomPrimvar> GetPrimvars() const;
315 
316     /// Like GetPrimvars(), but include only primvars that have some
317     /// authored scene description (though not necessarily a value).
318     ///
319     /// \sa \ref usdGeom_PrimvarFetchingAPI
320     USDGEOM_API
321     std::vector<UsdGeomPrimvar> GetAuthoredPrimvars() const;
322 
323     /// Like GetPrimvars(), but include only primvars that have some
324     /// value, whether it comes from authored scene description or a schema
325     /// fallback.
326     ///
327     /// For most purposes, this method is more useful than GetPrimvars().
328     ///
329     /// \sa \ref usdGeom_PrimvarFetchingAPI
330     USDGEOM_API
331     std::vector<UsdGeomPrimvar> GetPrimvarsWithValues() const;
332 
333     /// Like GetPrimvars(), but include only primvars that have an **authored**
334     /// value.
335     ///
336     /// This is the query used when computing inheritable primvars, and is
337     /// generally more useful than GetAuthoredPrimvars().
338     ///
339     /// \sa \ref usdGeom_PrimvarFetchingAPI
340     USDGEOM_API
341     std::vector<UsdGeomPrimvar> GetPrimvarsWithAuthoredValues() const;
342 
343     /// Compute the primvars that can be inherited from this prim by its
344     /// child prims, including the primvars that **this** prim inherits from
345     /// ancestor prims.  Inherited primvars will be bound to attributes on
346     /// the corresponding ancestor prims.
347     ///
348     /// Only primvars with **authored**, **non-blocked**,
349     /// **constant interpolation** values are inheritable;
350     /// fallback values are not inherited.   The order of the returned
351     /// primvars is undefined.
352     ///
353     /// It is not generally useful to call this method on UsdGeomGprim leaf
354     /// prims, and furthermore likely to be expensive since *most* primvars
355     /// are defined on Gprims.
356     ///
357     /// \sa \ref usdGeom_PrimvarFetchingAPI
358     USDGEOM_API
359     std::vector<UsdGeomPrimvar> FindInheritablePrimvars() const;
360 
361     /// Compute the primvars that can be inherited from this prim by its
362     /// child prims, starting from the set of primvars inherited from
363     /// this prim's ancestors.  If this method returns an empty vector, then
364     /// this prim's children should inherit the same set of primvars available
365     /// to this prim, i.e. the input `inheritedFromAncestors` .
366     ///
367     /// As opposed to FindInheritablePrimvars(), which always recurses up
368     /// through all of the prim's ancestors, this method allows more
369     /// efficient computation of inheritable primvars by starting with the
370     /// list of primvars inherited from this prim's ancestors, and returning
371     /// a newly allocated vector only when this prim makes a change to the
372     /// set of inherited primvars.  This enables O(n) inherited primvar
373     /// computation for all prims on a Stage, with potential to share
374     /// computed results that are identical (i.e. when this method returns an
375     /// empty vector, its parent's result can (and must!) be reused for all
376     /// of the prim's children.
377     ///
378     /// \sa \ref usdGeom_PrimvarFetchingAPI
379     USDGEOM_API
380     std::vector<UsdGeomPrimvar> FindIncrementallyInheritablePrimvars(
381         const std::vector<UsdGeomPrimvar> &inheritedFromAncestors) const;
382 
383     /// Like GetPrimvar(), but if the named primvar does not exist or has no
384     /// authored value on this prim, search for the named, value-producing
385     /// primvar on ancestor prims.
386     ///
387     /// The returned primvar will be bound to the attribute on the
388     /// corresponding ancestor prim on which it was found (if any).  If neither
389     /// this prim nor any ancestor contains a value-producing primvar, then
390     /// the returned primvar will be the same as that returned by GetPrimvar().
391     ///
392     /// This is probably the method you want to call when needing to consume
393     /// a primvar of a particular name.
394     ///
395     /// \sa \ref usdGeom_PrimvarFetchingAPI
396     USDGEOM_API
397     UsdGeomPrimvar FindPrimvarWithInheritance(const TfToken &name) const;
398 
399     /// \overload
400     ///
401     /// This version of FindPrimvarWithInheritance() takes the pre-computed
402     /// set of primvars inherited from this prim's ancestors, as computed
403     /// by FindInheritablePrimvars() or FindIncrementallyInheritablePrimvars()
404     /// on the prim's parent.
405     ///
406     /// \sa \ref usdGeom_PrimvarFetchingAPI
407     USDGEOM_API
408     UsdGeomPrimvar FindPrimvarWithInheritance(const TfToken &name,
409         const std::vector<UsdGeomPrimvar> &inheritedFromAncestors) const;
410 
411     /// Find all of the value-producing primvars either defined on this prim,
412     /// or inherited from ancestor prims.
413     ///
414     /// \sa \ref usdGeom_PrimvarFetchingAPI
415     USDGEOM_API
416     std::vector<UsdGeomPrimvar> FindPrimvarsWithInheritance() const;
417 
418     /// \overload
419     ///
420     /// This version of FindPrimvarsWithInheritance() takes the pre-computed
421     /// set of primvars inherited from this prim's ancestors, as computed
422     /// by FindInheritablePrimvars() or FindIncrementallyInheritablePrimvars()
423     /// on the prim's parent.
424     ///
425     /// \sa \ref usdGeom_PrimvarFetchingAPI
426     USDGEOM_API
427     std::vector<UsdGeomPrimvar> FindPrimvarsWithInheritance(
428         const std::vector<UsdGeomPrimvar> &inheritedFromAncestors) const;
429 
430     /// Is there a defined Primvar \p name on this prim?
431     ///
432     /// Name lookup will account for Primvar namespacing.
433     ///
434     /// Like GetPrimvar(), a return value of `true` for HasPrimvar() does not
435     /// guarantee the primvar will produce a value.
436     USDGEOM_API
437     bool HasPrimvar(const TfToken &name) const;
438 
439     /// Is there a Primvar named \p name with an authored value on this
440     /// prim or any of its ancestors?
441     ///
442     /// This is probably the method you want to call when wanting to know
443     /// whether or not the prim "has" a primvar of a particular name.
444     ///
445     /// \sa FindPrimvarWithInheritance()
446     USDGEOM_API
447     bool HasPossiblyInheritedPrimvar(const TfToken &name) const;
448 
449     /// Test whether a given \p name contains the "primvars:" prefix
450     ///
451     USDGEOM_API
452     static bool CanContainPropertyName(const TfToken& name);
453 };
454 
455 PXR_NAMESPACE_CLOSE_SCOPE
456 
457 #endif
458