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