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 USDLUX_GENERATED_LISTAPI_H
25 #define USDLUX_GENERATED_LISTAPI_H
26 
27 /// \file usdLux/listAPI.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usd/usdLux/api.h"
31 #include "pxr/usd/usd/apiSchemaBase.h"
32 #include "pxr/usd/usd/prim.h"
33 #include "pxr/usd/usd/stage.h"
34 #include "pxr/usd/usdLux/tokens.h"
35 
36 #include "pxr/base/vt/value.h"
37 
38 #include "pxr/base/gf/vec3d.h"
39 #include "pxr/base/gf/vec3f.h"
40 #include "pxr/base/gf/matrix4d.h"
41 
42 #include "pxr/base/tf/token.h"
43 #include "pxr/base/tf/type.h"
44 
45 PXR_NAMESPACE_OPEN_SCOPE
46 
47 class SdfAssetPath;
48 
49 // -------------------------------------------------------------------------- //
50 // LISTAPI                                                                    //
51 // -------------------------------------------------------------------------- //
52 
53 /// \class UsdLuxListAPI
54 ///
55 /// API schema to support discovery and publishing of lights in a scene.
56 ///
57 /// \section UsdLuxListAPI_Discovery Discovering Lights via Traversal
58 ///
59 /// To motivate this API, consider what is required to discover all
60 /// lights in a scene.  We must load all payloads and traverse all prims:
61 ///
62 /// \code
63 /// 01  // Load everything on the stage so we can find all lights,
64 /// 02  // including those inside payloads
65 /// 03  stage->Load();
66 /// 04
67 /// 05  // Traverse all prims, checking if they have an applied UsdLuxLightAPI
68 /// 06  // (Note: ignoring instancing and a few other things for simplicity)
69 /// 07  SdfPathVector lights;
70 /// 08  for (UsdPrim prim: stage->Traverse()) {
71 /// 09      if (prim.HasAPI<UsdLuxLightAPI>()) {
72 /// 10          lights.push_back(i->GetPath());
73 /// 11      }
74 /// 12  }
75 /// \endcode
76 ///
77 /// This traversal -- suitably elaborated to handle certain details --
78 /// is the first and simplest thing UsdLuxListAPI provides.
79 /// UsdLuxListAPI::ComputeLightList() performs this traversal and returns
80 /// all lights in the scene:
81 ///
82 /// \code
83 /// 01  UsdLuxListAPI listAPI(stage->GetPseudoRoot());
84 /// 02  SdfPathVector lights = listAPI.ComputeLightList();
85 /// \endcode
86 ///
87 /// \section UsdLuxListAPI_LightList Publishing a Cached Light List
88 ///
89 /// Consider a USD client that needs to quickly discover lights but
90 /// wants to defer loading payloads and traversing the entire scene
91 /// where possible, and is willing to do up-front computation and
92 /// caching to achieve that.
93 ///
94 /// UsdLuxListAPI provides a way to cache the computed light list,
95 /// by publishing the list of lights onto prims in the model
96 /// hierarchy.  Consider a big set that contains lights:
97 ///
98 /// \code
99 /// 01  def Xform "BigSetWithLights" (
100 /// 02      kind = "assembly"
101 /// 03      payload = @BigSetWithLights.usd@   // Heavy payload
102 /// 04  ) {
103 /// 05      // Pre-computed, cached list of lights inside payload
104 /// 06      rel lightList = [
105 /// 07          <./Lights/light_1>,
106 /// 08          <./Lights/light_2>,
107 /// 09          ...
108 /// 10      ]
109 /// 11      token lightList:cacheBehavior = "consumeAndContinue";
110 /// 12  }
111 /// \endcode
112 ///
113 /// The lightList relationship encodes a set of lights, and the
114 /// lightList:cacheBehavior property provides fine-grained
115 /// control over how to use that cache.  (See details below.)
116 ///
117 /// The cache can be created by first invoking
118 /// ComputeLightList(ComputeModeIgnoreCache) to pre-compute the list
119 /// and then storing the result with UsdLuxListAPI::StoreLightList().
120 ///
121 /// To enable efficient retrieval of the cache, it should be stored
122 /// on a model hierarchy prim.  Furthermore, note that while you can
123 /// use a UsdLuxListAPI bound to the pseudo-root prim to query the
124 /// lights (as in the example above) because it will perform a
125 /// traversal over descendants, you cannot store the cache back to the
126 /// pseduo-root prim.
127 ///
128 /// To consult the cached list, we invoke
129 /// ComputeLightList(ComputeModeConsultModelHierarchyCache):
130 ///
131 /// \code
132 /// 01  // Find and load all lights, using lightList cache where available
133 /// 02  UsdLuxListAPI list(stage->GetPseudoRoot());
134 /// 03  SdfPathSet lights = list.ComputeLightList(
135 /// 04      UsdLuxListAPI::ComputeModeConsultModelHierarchyCache);
136 /// 05  stage.LoadAndUnload(lights, SdfPathSet());
137 /// \endcode
138 ///
139 /// In this mode, ComputeLightList() will traverse the model
140 /// hierarchy, accumulating cached light lists.
141 ///
142 /// \section UsdLuxListAPI_CacheBehavior Controlling Cache Behavior
143 ///
144 /// The lightList:cacheBehavior property gives additional fine-grained
145 /// control over cache behavior:
146 ///
147 /// \li The fallback value, "ignore", indicates that the lightList should
148 /// be disregarded.  This provides a way to invalidate cache entries.
149 /// Note that unless "ignore" is specified, a lightList with an empty
150 /// list of targets is considered a cache indicating that no lights
151 /// are present.
152 ///
153 /// \li The value "consumeAndContinue" indicates that the cache should
154 /// be consulted to contribute lights to the scene, and that recursion
155 /// should continue down the model hierarchy in case additional lights
156 /// are added as descedants. This is the default value established when
157 /// StoreLightList() is invoked. This behavior allows the lights within
158 /// a large model, such as the BigSetWithLights example above, to be
159 /// published outside the payload, while also allowing referencing and
160 /// layering to add additional lights over that set.
161 ///
162 /// \li The value "consumeAndHalt" provides a way to terminate recursive
163 /// traversal of the scene for light discovery. The cache will be
164 /// consulted but no descendant prims will be examined.
165 ///
166 /// \section UsdLuxListAPI_Instancing Instancing
167 ///
168 /// Where instances are present, UsdLuxListAPI::ComputeLightList() will
169 /// return the instance-unique paths to any lights discovered within
170 /// those instances.  Lights within a UsdGeomPointInstancer will
171 /// not be returned, however, since they cannot be referred to
172 /// solely via paths.
173 ///
174 ///
175 /// For any described attribute \em Fallback \em Value or \em Allowed \em Values below
176 /// that are text/tokens, the actual token is published and defined in \ref UsdLuxTokens.
177 /// So to set an attribute to the value "rightHanded", use UsdLuxTokens->rightHanded
178 /// as the value.
179 ///
180 class UsdLuxListAPI : public UsdAPISchemaBase
181 {
182 public:
183     /// Compile time constant representing what kind of schema this class is.
184     ///
185     /// \sa UsdSchemaKind
186     static const UsdSchemaKind schemaKind = UsdSchemaKind::SingleApplyAPI;
187 
188     /// Construct a UsdLuxListAPI on UsdPrim \p prim .
189     /// Equivalent to UsdLuxListAPI::Get(prim.GetStage(), prim.GetPath())
190     /// for a \em valid \p prim, but will not immediately throw an error for
191     /// an invalid \p prim
192     explicit UsdLuxListAPI(const UsdPrim& prim=UsdPrim())
UsdAPISchemaBase(prim)193         : UsdAPISchemaBase(prim)
194     {
195     }
196 
197     /// Construct a UsdLuxListAPI on the prim held by \p schemaObj .
198     /// Should be preferred over UsdLuxListAPI(schemaObj.GetPrim()),
199     /// as it preserves SchemaBase state.
UsdLuxListAPI(const UsdSchemaBase & schemaObj)200     explicit UsdLuxListAPI(const UsdSchemaBase& schemaObj)
201         : UsdAPISchemaBase(schemaObj)
202     {
203     }
204 
205     /// Destructor.
206     USDLUX_API
207     virtual ~UsdLuxListAPI();
208 
209     /// Return a vector of names of all pre-declared attributes for this schema
210     /// class and all its ancestor classes.  Does not include attributes that
211     /// may be authored by custom/extended methods of the schemas involved.
212     USDLUX_API
213     static const TfTokenVector &
214     GetSchemaAttributeNames(bool includeInherited=true);
215 
216     /// Return a UsdLuxListAPI holding the prim adhering to this
217     /// schema at \p path on \p stage.  If no prim exists at \p path on
218     /// \p stage, or if the prim at that path does not adhere to this schema,
219     /// return an invalid schema object.  This is shorthand for the following:
220     ///
221     /// \code
222     /// UsdLuxListAPI(stage->GetPrimAtPath(path));
223     /// \endcode
224     ///
225     USDLUX_API
226     static UsdLuxListAPI
227     Get(const UsdStagePtr &stage, const SdfPath &path);
228 
229 
230     /// Returns true if this <b>single-apply</b> API schema can be applied to
231     /// the given \p prim. If this schema can not be a applied to the prim,
232     /// this returns false and, if provided, populates \p whyNot with the
233     /// reason it can not be applied.
234     ///
235     /// Note that if CanApply returns false, that does not necessarily imply
236     /// that calling Apply will fail. Callers are expected to call CanApply
237     /// before calling Apply if they want to ensure that it is valid to
238     /// apply a schema.
239     ///
240     /// \sa UsdPrim::GetAppliedSchemas()
241     /// \sa UsdPrim::HasAPI()
242     /// \sa UsdPrim::CanApplyAPI()
243     /// \sa UsdPrim::ApplyAPI()
244     /// \sa UsdPrim::RemoveAPI()
245     ///
246     USDLUX_API
247     static bool
248     CanApply(const UsdPrim &prim, std::string *whyNot=nullptr);
249 
250     /// Applies this <b>single-apply</b> API schema to the given \p prim.
251     /// This information is stored by adding "ListAPI" to the
252     /// token-valued, listOp metadata \em apiSchemas on the prim.
253     ///
254     /// \return A valid UsdLuxListAPI object is returned upon success.
255     /// An invalid (or empty) UsdLuxListAPI object is returned upon
256     /// failure. See \ref UsdPrim::ApplyAPI() for conditions
257     /// resulting in failure.
258     ///
259     /// \sa UsdPrim::GetAppliedSchemas()
260     /// \sa UsdPrim::HasAPI()
261     /// \sa UsdPrim::CanApplyAPI()
262     /// \sa UsdPrim::ApplyAPI()
263     /// \sa UsdPrim::RemoveAPI()
264     ///
265     USDLUX_API
266     static UsdLuxListAPI
267     Apply(const UsdPrim &prim);
268 
269 protected:
270     /// Returns the kind of schema this class belongs to.
271     ///
272     /// \sa UsdSchemaKind
273     USDLUX_API
274     UsdSchemaKind _GetSchemaKind() const override;
275 
276 private:
277     // needs to invoke _GetStaticTfType.
278     friend class UsdSchemaRegistry;
279     USDLUX_API
280     static const TfType &_GetStaticTfType();
281 
282     static bool _IsTypedSchema();
283 
284     // override SchemaBase virtuals.
285     USDLUX_API
286     const TfType &_GetTfType() const override;
287 
288 public:
289     // --------------------------------------------------------------------- //
290     // LIGHTLISTCACHEBEHAVIOR
291     // --------------------------------------------------------------------- //
292     /// Controls how the lightList should be interpreted.
293     /// Valid values are:
294     /// - consumeAndHalt: The lightList should be consulted,
295     /// and if it exists, treated as a final authoritative statement
296     /// of any lights that exist at or below this prim, halting
297     /// recursive discovery of lights.
298     /// - consumeAndContinue: The lightList should be consulted,
299     /// but recursive traversal over nameChildren should continue
300     /// in case additional lights are added by descendants.
301     /// - ignore: The lightList should be entirely ignored.  This
302     /// provides a simple way to temporarily invalidate an existing
303     /// cache.  This is the fallback behavior.
304     ///
305     ///
306     /// | ||
307     /// | -- | -- |
308     /// | Declaration | `token lightList:cacheBehavior` |
309     /// | C++ Type | TfToken |
310     /// | \ref Usd_Datatypes "Usd Type" | SdfValueTypeNames->Token |
311     /// | \ref UsdLuxTokens "Allowed Values" | consumeAndHalt, consumeAndContinue, ignore |
312     USDLUX_API
313     UsdAttribute GetLightListCacheBehaviorAttr() const;
314 
315     /// See GetLightListCacheBehaviorAttr(), and also
316     /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create.
317     /// If specified, author \p defaultValue as the attribute's default,
318     /// sparsely (when it makes sense to do so) if \p writeSparsely is \c true -
319     /// the default for \p writeSparsely is \c false.
320     USDLUX_API
321     UsdAttribute CreateLightListCacheBehaviorAttr(VtValue const &defaultValue = VtValue(), bool writeSparsely=false) const;
322 
323 public:
324     // --------------------------------------------------------------------- //
325     // LIGHTLIST
326     // --------------------------------------------------------------------- //
327     /// Relationship to lights in the scene.
328     ///
329     USDLUX_API
330     UsdRelationship GetLightListRel() const;
331 
332     /// See GetLightListRel(), and also
333     /// \ref Usd_Create_Or_Get_Property for when to use Get vs Create
334     USDLUX_API
335     UsdRelationship CreateLightListRel() const;
336 
337 public:
338     // ===================================================================== //
339     // Feel free to add custom code below this line, it will be preserved by
340     // the code generator.
341     //
342     // Just remember to:
343     //  - Close the class declaration with };
344     //  - Close the namespace with PXR_NAMESPACE_CLOSE_SCOPE
345     //  - Close the include guard with #endif
346     // ===================================================================== //
347     // --(BEGIN CUSTOM CODE)--
348 
349     /// Runtime control over whether to consult stored lightList caches.
350     enum ComputeMode {
351         /// Consult any caches found on the model hierarchy.
352         /// Do not traverse beneath the model hierarchy.
353         ComputeModeConsultModelHierarchyCache,
354         /// Ignore any caches found, and do a full prim traversal.
355         ComputeModeIgnoreCache,
356     };
357 
358     /// Computes and returns the list of lights and light filters in
359     /// the stage, optionally consulting a cached result.
360     ///
361     /// In ComputeModeIgnoreCache mode, caching is ignored, and this
362     /// does a prim traversal looking for prims that have a UsdLuxLightAPI
363     /// or are of type UsdLuxLightFilter.
364     ///
365     /// In ComputeModeConsultModelHierarchyCache, this does a traversal
366     /// only of the model hierarchy. In this traversal, any lights that
367     /// live as model hierarchy prims are accumulated, as well as any
368     /// paths stored in lightList caches. The lightList:cacheBehavior
369     /// attribute gives further control over the cache behavior; see the
370     /// class overview for details.
371     ///
372     /// When instances are present, ComputeLightList(ComputeModeIgnoreCache)
373     /// will return the instance-uniqiue paths to any lights discovered
374     /// within those instances.  Lights within a UsdGeomPointInstancer
375     /// will not be returned, however, since they cannot be referred to
376     /// solely via paths.
377     USDLUX_API
378     SdfPathSet ComputeLightList(ComputeMode mode) const;
379 
380     /// Store the given paths as the lightlist for this prim.
381     /// Paths that do not have this prim's path as a prefix
382     /// will be silently ignored.
383     /// This will set the listList:cacheBehavior to "consumeAndContinue".
384     USDLUX_API
385     void StoreLightList(const SdfPathSet &) const;
386 
387     /// Mark any stored lightlist as invalid, by setting the
388     /// lightList:cacheBehavior attribute to ignore.
389     USDLUX_API
390     void InvalidateLightList() const;
391 };
392 
393 PXR_NAMESPACE_CLOSE_SCOPE
394 
395 #endif
396