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 #include "pxr/usd/usdLux/listAPI.h"
25 #include "pxr/usd/usd/schemaRegistry.h"
26 #include "pxr/usd/usd/typed.h"
27 #include "pxr/usd/usd/tokens.h"
28 
29 #include "pxr/usd/sdf/types.h"
30 #include "pxr/usd/sdf/assetPath.h"
31 
32 PXR_NAMESPACE_OPEN_SCOPE
33 
34 // Register the schema with the TfType system.
TF_REGISTRY_FUNCTION(TfType)35 TF_REGISTRY_FUNCTION(TfType)
36 {
37     TfType::Define<UsdLuxListAPI,
38         TfType::Bases< UsdAPISchemaBase > >();
39 
40 }
41 
42 TF_DEFINE_PRIVATE_TOKENS(
43     _schemaTokens,
44     (ListAPI)
45 );
46 
47 /* virtual */
~UsdLuxListAPI()48 UsdLuxListAPI::~UsdLuxListAPI()
49 {
50 }
51 
52 /* static */
53 UsdLuxListAPI
Get(const UsdStagePtr & stage,const SdfPath & path)54 UsdLuxListAPI::Get(const UsdStagePtr &stage, const SdfPath &path)
55 {
56     if (!stage) {
57         TF_CODING_ERROR("Invalid stage");
58         return UsdLuxListAPI();
59     }
60     return UsdLuxListAPI(stage->GetPrimAtPath(path));
61 }
62 
63 
64 /* virtual */
_GetSchemaKind() const65 UsdSchemaKind UsdLuxListAPI::_GetSchemaKind() const
66 {
67     return UsdLuxListAPI::schemaKind;
68 }
69 
70 /* static */
71 bool
CanApply(const UsdPrim & prim,std::string * whyNot)72 UsdLuxListAPI::CanApply(
73     const UsdPrim &prim, std::string *whyNot)
74 {
75     return prim.CanApplyAPI<UsdLuxListAPI>(whyNot);
76 }
77 
78 /* static */
79 UsdLuxListAPI
Apply(const UsdPrim & prim)80 UsdLuxListAPI::Apply(const UsdPrim &prim)
81 {
82     if (prim.ApplyAPI<UsdLuxListAPI>()) {
83         return UsdLuxListAPI(prim);
84     }
85     return UsdLuxListAPI();
86 }
87 
88 /* static */
89 const TfType &
_GetStaticTfType()90 UsdLuxListAPI::_GetStaticTfType()
91 {
92     static TfType tfType = TfType::Find<UsdLuxListAPI>();
93     return tfType;
94 }
95 
96 /* static */
97 bool
_IsTypedSchema()98 UsdLuxListAPI::_IsTypedSchema()
99 {
100     static bool isTyped = _GetStaticTfType().IsA<UsdTyped>();
101     return isTyped;
102 }
103 
104 /* virtual */
105 const TfType &
_GetTfType() const106 UsdLuxListAPI::_GetTfType() const
107 {
108     return _GetStaticTfType();
109 }
110 
111 UsdAttribute
GetLightListCacheBehaviorAttr() const112 UsdLuxListAPI::GetLightListCacheBehaviorAttr() const
113 {
114     return GetPrim().GetAttribute(UsdLuxTokens->lightListCacheBehavior);
115 }
116 
117 UsdAttribute
CreateLightListCacheBehaviorAttr(VtValue const & defaultValue,bool writeSparsely) const118 UsdLuxListAPI::CreateLightListCacheBehaviorAttr(VtValue const &defaultValue, bool writeSparsely) const
119 {
120     return UsdSchemaBase::_CreateAttr(UsdLuxTokens->lightListCacheBehavior,
121                        SdfValueTypeNames->Token,
122                        /* custom = */ false,
123                        SdfVariabilityVarying,
124                        defaultValue,
125                        writeSparsely);
126 }
127 
128 UsdRelationship
GetLightListRel() const129 UsdLuxListAPI::GetLightListRel() const
130 {
131     return GetPrim().GetRelationship(UsdLuxTokens->lightList);
132 }
133 
134 UsdRelationship
CreateLightListRel() const135 UsdLuxListAPI::CreateLightListRel() const
136 {
137     return GetPrim().CreateRelationship(UsdLuxTokens->lightList,
138                        /* custom = */ false);
139 }
140 
141 namespace {
142 static inline TfTokenVector
_ConcatenateAttributeNames(const TfTokenVector & left,const TfTokenVector & right)143 _ConcatenateAttributeNames(const TfTokenVector& left,const TfTokenVector& right)
144 {
145     TfTokenVector result;
146     result.reserve(left.size() + right.size());
147     result.insert(result.end(), left.begin(), left.end());
148     result.insert(result.end(), right.begin(), right.end());
149     return result;
150 }
151 }
152 
153 /*static*/
154 const TfTokenVector&
GetSchemaAttributeNames(bool includeInherited)155 UsdLuxListAPI::GetSchemaAttributeNames(bool includeInherited)
156 {
157     static TfTokenVector localNames = {
158         UsdLuxTokens->lightListCacheBehavior,
159     };
160     static TfTokenVector allNames =
161         _ConcatenateAttributeNames(
162             UsdAPISchemaBase::GetSchemaAttributeNames(true),
163             localNames);
164 
165     if (includeInherited)
166         return allNames;
167     else
168         return localNames;
169 }
170 
171 PXR_NAMESPACE_CLOSE_SCOPE
172 
173 // ===================================================================== //
174 // Feel free to add custom code below this line. It will be preserved by
175 // the code generator.
176 //
177 // Just remember to wrap code in the appropriate delimiters:
178 // 'PXR_NAMESPACE_OPEN_SCOPE', 'PXR_NAMESPACE_CLOSE_SCOPE'.
179 // ===================================================================== //
180 // --(BEGIN CUSTOM CODE)--
181 
182 #include "pxr/usd/usd/primRange.h"
183 #include "pxr/usd/usdLux/lightAPI.h"
184 #include "pxr/usd/usdLux/lightFilter.h"
185 
186 PXR_NAMESPACE_OPEN_SCOPE
187 
TF_REGISTRY_FUNCTION(TfEnum)188 TF_REGISTRY_FUNCTION(TfEnum)
189 {
190     TF_ADD_ENUM_NAME(UsdLuxListAPI::ComputeModeConsultModelHierarchyCache,
191                      "Consult lightList cache");
192     TF_ADD_ENUM_NAME(UsdLuxListAPI::ComputeModeIgnoreCache,
193                      "Ignore lightList cache");
194 }
195 
196 static void
_Traverse(const UsdPrim & prim,UsdLuxListAPI::ComputeMode mode,SdfPathSet * lights)197 _Traverse(const UsdPrim &prim,
198           UsdLuxListAPI::ComputeMode mode,
199           SdfPathSet *lights)
200 {
201     // If requested, check lightList cache.
202     if (mode == UsdLuxListAPI::ComputeModeConsultModelHierarchyCache &&
203         prim.GetPath().IsPrimPath() /* no cache on pseudoRoot */) {
204         UsdLuxListAPI listAPI(prim);
205         TfToken cacheBehavior;
206         if (listAPI.GetLightListCacheBehaviorAttr().Get(&cacheBehavior)) {
207             if (cacheBehavior == UsdLuxTokens->consumeAndContinue ||
208                 cacheBehavior == UsdLuxTokens->consumeAndHalt) {
209                 // Check stored lightList.
210                 UsdRelationship rel = listAPI.GetLightListRel();
211                 SdfPathVector targets;
212                 rel.GetForwardedTargets(&targets);
213                 lights->insert(targets.begin(), targets.end());
214                 if (cacheBehavior == UsdLuxTokens->consumeAndHalt) {
215                     return;
216                 }
217             }
218         }
219     }
220     // Accumulate discovered prims.
221     if (prim.HasAPI<UsdLuxLightAPI>() || prim.IsA<UsdLuxLightFilter>()) {
222         lights->insert(prim.GetPath());
223     }
224     // Traverse descendants.
225     auto flags = UsdPrimIsActive && !UsdPrimIsAbstract && UsdPrimIsDefined;
226     if (mode == UsdLuxListAPI::ComputeModeConsultModelHierarchyCache) {
227         // When consulting the cache we only traverse model hierarchy.
228         flags = flags && UsdPrimIsModel;
229     }
230     for (const UsdPrim &child:
231          prim.GetFilteredChildren(UsdTraverseInstanceProxies(flags))) {
232         _Traverse(child, mode, lights);
233     }
234 }
235 
236 SdfPathSet
ComputeLightList(UsdLuxListAPI::ComputeMode mode) const237 UsdLuxListAPI::ComputeLightList(UsdLuxListAPI::ComputeMode mode) const
238 {
239     SdfPathSet result;
240     _Traverse(GetPrim(), mode, &result);
241     return result;
242 }
243 
244 void
StoreLightList(const SdfPathSet & lights) const245 UsdLuxListAPI::StoreLightList(const SdfPathSet &lights) const
246 {
247     SdfPathVector targets;
248     for (const SdfPath &p: lights) {
249         if (p.IsAbsolutePath() && !p.HasPrefix(GetPath())) {
250             // Light path does not have this prim as a prefix; ignore.
251             continue;
252         }
253         targets.push_back(p);
254     }
255     CreateLightListRel().SetTargets(targets);
256     CreateLightListCacheBehaviorAttr().Set(UsdLuxTokens->consumeAndContinue);
257 }
258 
259 void
InvalidateLightList() const260 UsdLuxListAPI::InvalidateLightList() const
261 {
262     CreateLightListCacheBehaviorAttr().Set(UsdLuxTokens->ignore);
263 }
264 
265 PXR_NAMESPACE_CLOSE_SCOPE
266