1 //
2 // Copyright 2019 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 
25 #ifndef PXR_USD_USD_STAGE_LOAD_RULES_H
26 #define PXR_USD_USD_STAGE_LOAD_RULES_H
27 
28 /// \file usd/stageLoadRules.h
29 
30 #include "pxr/pxr.h"
31 #include "pxr/usd/usd/api.h"
32 #include "pxr/usd/usd/common.h"
33 #include "pxr/usd/sdf/path.h"
34 
35 #include <iosfwd>
36 #include <vector>
37 
38 PXR_NAMESPACE_OPEN_SCOPE
39 
40 /// \class UsdStageLoadRules
41 ///
42 /// This class represents rules that govern payload inclusion on UsdStages.
43 ///
44 /// Rules are represented as pairs of SdfPath and a Rule enum value, one of
45 /// AllRule, OnlyRule, and NoneRule.  To understand how rules apply to
46 /// particular paths, see UsdStageLoadRules::GetEffectiveRuleForPath().
47 ///
48 /// Convenience methods for manipulating rules by typical 'Load' and 'Unload'
49 /// operations are provided in UsdStageLoadRules::LoadWithoutDescendants(),
50 /// UsdStageLoadRules::LoadWithDescendants(), UsdStageLoadRules::Unload().
51 ///
52 /// For finer-grained rule crafting, see AddRule().
53 ///
54 /// Remove redundant rules that do not change the effective load state with
55 /// UsdStageLoadRules::Minimize().
56 class UsdStageLoadRules
57 {
58 public:
59     /// \enum Rule
60     ///
61     /// These values are paired with paths to govern payload inclusion on
62     /// UsdStages.
63     enum Rule {
64         /// Include payloads on the specified prim and all descendants.
65         AllRule,
66         /// Include payloads on the specified prim but no descendants.
67         OnlyRule,
68         /// Exclude payloads on the specified prim and all descendants.
69         NoneRule
70     };
71 
72     /// Construct rules that load all payloads.
73     UsdStageLoadRules() = default;
74 
75     /// Return rules that load all payloads.  This is equivalent to
76     /// default-constructed UsdStageLoadRules.
LoadAll()77     static inline UsdStageLoadRules LoadAll() {
78         return UsdStageLoadRules();
79     }
80 
81     /// Return rules that load no payloads.
82     USD_API
83     static UsdStageLoadRules LoadNone();
84 
85     UsdStageLoadRules(UsdStageLoadRules const &) = default;
86     UsdStageLoadRules(UsdStageLoadRules &&) = default;
87     UsdStageLoadRules &operator=(UsdStageLoadRules const &) = default;
88     UsdStageLoadRules &operator=(UsdStageLoadRules &&) = default;
89 
90     /// Add a rule indicating that \p path, all its ancestors, and all its
91     /// descendants shall be loaded.
92     ///
93     /// Any previous rules created by calling LoadWithoutDescendants() or
94     /// Unload() on this path or descendant paths are replaced by this rule.
95     /// For example, calling LoadWithoutDescendants('/World/sets/kitchen')
96     /// followed by LoadWithDescendants('/World/sets') will effectively remove
97     /// the rule created in the first call.  See AddRule() for more direct
98     /// manipulation.
99     USD_API
100     void LoadWithDescendants(SdfPath const &path);
101 
102     /// Add a rule indicating that \p path and all its ancestors but none of its
103     /// descendants shall be loaded.
104     ///
105     /// Any previous rules created by calling LoadWithDescendants() or Unload()
106     /// on this path or descendant paths are replaced or restricted by this
107     /// rule.  For example, calling LoadWithDescendants('/World/sets') followed
108     /// by LoadWithoutDescendants('/World/sets/kitchen') will cause everything
109     /// under '/World/sets' to load except for those things under
110     /// '/World/sets/kitchen'.  See AddRule() for more direct manipulation.
111     USD_API
112     void LoadWithoutDescendants(SdfPath const &path);
113 
114     /// Add a rule indicating that \p path and all its descendants shall be
115     /// unloaded.
116     ///
117     /// Any previous rules created by calling LoadWithDescendants() or
118     /// LoadWithoutDescendants() on this path or descendant paths are replaced
119     /// or restricted by this rule.  For example, calling
120     /// LoadWithDescendants('/World/sets') followed by
121     /// Unload('/World/sets/kitchen') will cause everything under '/World/sets'
122     /// to load, except for '/World/sets/kitchen' and everything under it.
123     USD_API
124     void Unload(SdfPath const &path);
125 
126     /// Add rules as if Unload() was called for each element of \p unloadSet
127     /// followed by calls to either LoadWithDescendants() (if \p policy is
128     /// UsdLoadPolicy::LoadWithDescendants) or LoadWithoutDescendants() (if
129     /// \p policy is UsdLoadPolicy::LoadWithoutDescendants) for each element of
130     /// \p loadSet.
131     USD_API
132     void LoadAndUnload(const SdfPathSet &loadSet,
133                        const SdfPathSet &unloadSet, UsdLoadPolicy policy);
134 
135     /// Add a literal rule.  If there's already a rule for \p path, replace it.
136     USD_API
137     void AddRule(SdfPath const &path, Rule rule);
138 
139     /// Set literal rules, must be sorted by SdfPath::operator<.
140     USD_API
141     void SetRules(std::vector<std::pair<SdfPath, Rule>> const &rules);
142 
143     /// Set literal rules, must be sorted by SdfPath::operator<.
SetRules(std::vector<std::pair<SdfPath,Rule>> && rules)144     inline void SetRules(std::vector<std::pair<SdfPath, Rule>> &&rules) {
145         _rules = std::move(rules);
146     }
147 
148     /// Remove any redundant rules to make the set of rules as small as possible
149     /// without changing behavior.
150     USD_API
151     void Minimize();
152 
153     /// Return true if the given \p path is considered loaded by these rules, or
154     /// false if it is considered unloaded.  This is equivalent to
155     /// GetEffectiveRuleForPath(path) != NoneRule.
156     USD_API
157     bool IsLoaded(SdfPath const &path) const;
158 
159     /// Return true if the given \p path and all descendants are considered
160     /// loaded by these rules; false otherwise.
161     USD_API
162     bool IsLoadedWithAllDescendants(SdfPath const &path) const;
163 
164     /// Return true if the given \p path and is considered loaded, but none of
165     /// its descendants are considered loaded by these rules; false otherwise.
166     USD_API
167     bool IsLoadedWithNoDescendants(SdfPath const &path) const;
168 
169     /// Return the "effective" rule for the given \p path.  For example, if the
170     /// closest ancestral rule of \p path is an \p AllRule, return \p AllRule.
171     /// If the closest ancestral rule of \p path is for \p path itself and it is
172     /// an \p OnlyRule, return \p OnlyRule.  Otherwise if there is a closest
173     /// descendant rule to \p path this is an \p OnlyRule or an \p AllRule,
174     /// return \p OnlyRule.  Otherwise return \p NoneRule.
175     USD_API
176     Rule GetEffectiveRuleForPath(SdfPath const &path) const;
177 
178     /// Return all the rules as a vector.
GetRules()179     inline std::vector<std::pair<SdfPath, Rule>> const &GetRules() const {
180         return _rules;
181     }
182 
183     /// Return true if \p other has exactly the same set of rules as this.  Note
184     /// that this means rules that are functionally equivalent may compare
185     /// inequal.  If this is not desired, ensure both sets of rules are reduced
186     /// by Minimize() first.
187     USD_API
188     bool operator==(UsdStageLoadRules const &other) const;
189 
190     /// Return false if \p other has exactly the same set of rules as this.  See
191     /// operator==().
192     inline bool operator!=(UsdStageLoadRules const &other) const {
193         return !(*this == other);
194     }
195 
196     /// Swap the contents of these rules with \p other.
swap(UsdStageLoadRules & other)197     inline void swap(UsdStageLoadRules &other) {
198         _rules.swap(other._rules);
199     }
200 
201 private:
202     friend USD_API std::ostream &
203     operator<<(std::ostream &, std::pair<SdfPath, Rule> const &);
204 
205     friend USD_API std::ostream &
206     operator<<(std::ostream &, UsdStageLoadRules const &);
207 
208     friend USD_API
209     size_t hash_value(UsdStageLoadRules const &);
210 
211     USD_API
212     std::vector<std::pair<SdfPath, Rule> >::const_iterator
213     _LowerBound(SdfPath const &path) const;
214 
215     USD_API
216     std::vector<std::pair<SdfPath, Rule> >::iterator
217     _LowerBound(SdfPath const &path);
218 
219     std::vector<std::pair<SdfPath, Rule>> _rules;
220 
221 };
222 
223 /// Swap the contents of rules \p l and \p r.
swap(UsdStageLoadRules & l,UsdStageLoadRules & r)224 inline void swap(UsdStageLoadRules &l, UsdStageLoadRules &r)
225 {
226     l.swap(r);
227 }
228 
229 /// Stream a text representation of a UsdStageLoadRules object.
230 USD_API
231 std::ostream &operator<<(std::ostream &, UsdStageLoadRules const &);
232 
233 /// Stream a text representation of a pair of SdfPath and
234 /// UsdStageLoadRules::Rule.
235 USD_API
236 std::ostream &operator<<(std::ostream &,
237                          std::pair<SdfPath, UsdStageLoadRules::Rule> const &);
238 
239 /// Return the hash code for a UsdStageLoadRules object.
240 USD_API
241 size_t hash_value(UsdStageLoadRules const &);
242 
243 
244 PXR_NAMESPACE_CLOSE_SCOPE
245 
246 #endif // PXR_USD_USD_STAGE_LOAD_RULES_H
247