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 PXR_USD_PCP_TYPES_H
25 #define PXR_USD_PCP_TYPES_H
26
27 #include "pxr/pxr.h"
28 #include "pxr/usd/pcp/api.h"
29 #include "pxr/usd/pcp/site.h"
30 #include "pxr/usd/sdf/layer.h"
31 #include "pxr/base/tf/denseHashSet.h"
32
33 #include <limits>
34 #include <vector>
35
36 #include <boost/operators.hpp>
37
38 /// \file pcp/types.h
39
40 PXR_NAMESPACE_OPEN_SCOPE
41
42 /// \enum PcpArcType
43 ///
44 /// Describes the type of arc connecting two nodes in the prim index.
45 ///
46 enum PcpArcType {
47 // The root arc is a special value used for the root node of
48 // the prim index. Unlike the following arcs, it has no parent node.
49 PcpArcTypeRoot,
50
51 // The following arcs are listed in strength order.
52 PcpArcTypeInherit,
53 PcpArcTypeVariant,
54 PcpArcTypeRelocate,
55 PcpArcTypeReference,
56 PcpArcTypePayload,
57 PcpArcTypeSpecialize,
58
59 PcpNumArcTypes
60 };
61
62 /// \enum PcpRangeType
63 enum PcpRangeType {
64 // Range including just the root node.
65 PcpRangeTypeRoot,
66
67 // Ranges including child arcs, from the root node, of the specified type
68 // as well as all descendants of those arcs.
69 PcpRangeTypeInherit,
70 PcpRangeTypeVariant,
71 PcpRangeTypeReference,
72 PcpRangeTypePayload,
73 PcpRangeTypeSpecialize,
74
75 // Range including all nodes.
76 PcpRangeTypeAll,
77
78 // Range including all nodes weaker than the root node.
79 PcpRangeTypeWeakerThanRoot,
80
81 // Range including all nodes stronger than the payload
82 // node.
83 PcpRangeTypeStrongerThanPayload,
84
85 PcpRangeTypeInvalid
86 };
87
88 /// Returns true if \p arcType represents an inherit arc, false
89 /// otherwise.
90 inline bool
PcpIsInheritArc(PcpArcType arcType)91 PcpIsInheritArc(PcpArcType arcType)
92 {
93 return (arcType == PcpArcTypeInherit);
94 }
95
96 /// Returns true if \p arcType represents a specialize arc, false
97 /// otherwise.
98 inline bool
PcpIsSpecializeArc(PcpArcType arcType)99 PcpIsSpecializeArc(PcpArcType arcType)
100 {
101 return (arcType == PcpArcTypeSpecialize);
102 }
103
104 /// Returns true if \p arcType represents a class-based
105 /// composition arc, false otherwise.
106 ///
107 /// The key characteristic of these arcs is that they imply
108 /// additional sources of opinions outside of the site where
109 /// the arc is introduced.
110 inline bool
PcpIsClassBasedArc(PcpArcType arcType)111 PcpIsClassBasedArc(PcpArcType arcType)
112 {
113 return PcpIsInheritArc(arcType) || PcpIsSpecializeArc(arcType);
114 }
115
116 /// \struct PcpSiteTrackerSegment
117 ///
118 /// Used to keep track of which sites have been visited and through
119 /// what type of arcs.
120 ///
121 struct PcpSiteTrackerSegment {
122 PcpSiteStr site;
123 PcpArcType arcType;
124 };
125
126 /// \typedef std::vector<PcpSiteTrackerSegment> PcpSiteTracker
127 /// Represents a single path through the composition tree. As the tree
128 /// is being built, we add segments to the tracker. If we encounter a
129 /// site that we've already visited, we've found a cycle.
130 typedef std::vector<PcpSiteTrackerSegment> PcpSiteTracker;
131
132 // Internal type for Sd sites.
133 struct Pcp_SdSiteRef : boost::totally_ordered<Pcp_SdSiteRef> {
Pcp_SdSiteRefPcp_SdSiteRef134 Pcp_SdSiteRef(const SdfLayerRefPtr& layer_, const SdfPath& path_) :
135 layer(layer_), path(path_)
136 {
137 // Do nothing
138 }
139
140 bool operator==(const Pcp_SdSiteRef& other) const
141 {
142 return layer == other.layer && path == other.path;
143 }
144
145 bool operator<(const Pcp_SdSiteRef& other) const
146 {
147 return layer < other.layer ||
148 (!(other.layer < layer) && path < other.path);
149 }
150
151 // These are held by reference for performance,
152 // to avoid extra ref-counting operations.
153 const SdfLayerRefPtr & layer;
154 const SdfPath & path;
155 };
156
157 // Internal type for Sd sites.
158 struct Pcp_CompressedSdSite {
Pcp_CompressedSdSitePcp_CompressedSdSite159 Pcp_CompressedSdSite(size_t nodeIndex_, size_t layerIndex_) :
160 nodeIndex(static_cast<uint16_t>(nodeIndex_)),
161 layerIndex(static_cast<uint16_t>(layerIndex_))
162 {
163 TF_VERIFY(nodeIndex_ < (size_t(1) << 16));
164 TF_VERIFY(layerIndex_ < (size_t(1) << 16));
165 }
166
167 // These are small to minimize the size of vectors of these.
168 uint16_t nodeIndex; // The index of the node in its graph.
169 uint16_t layerIndex; // The index of the layer in the node's layer stack.
170 };
171 typedef std::vector<Pcp_CompressedSdSite> Pcp_CompressedSdSiteVector;
172
173 // XXX Even with <map> included properly, doxygen refuses to acknowledge
174 // the existence of std::map, so if we include the full typedef in the
175 // \typedef directive, it will warn and fail to produce an entry for
176 // PcpVariantFallbackMap. So we instead put the decl inline.
177 /// \typedef PcpVariantFallbackMap
178 /// typedef std::map<std::string, std::vector<std::string>> PcpVariantFallbackMap
179 ///
180 /// A "map of lists" of fallbacks to attempt to use when evaluating
181 /// variant sets that lack an authored selection.
182 ///
183 /// This maps a name of a variant set (ex: "shadingComplexity") to a
184 /// ordered list of variant selection names. If there is no variant
185 /// selection in scene description, Pcp will check for each listed
186 /// fallback in sequence, using the first one that exists.
187 ///
188 typedef std::map<std::string, std::vector<std::string>> PcpVariantFallbackMap;
189
190 typedef TfDenseHashSet<TfToken, TfToken::HashFunctor> PcpTokenSet;
191
192 /// \var size_t PCP_INVALID_INDEX
193 /// A value which indicates an invalid index. This is simply used inplace of
194 /// either -1 or numeric_limits::max() (which are equivalent for size_t).
195 /// for better clarity.
196 #if defined(doxygen)
197 constexpr size_t PCP_INVALID_INDEX = unspecified;
198 #else
199 constexpr size_t PCP_INVALID_INDEX = std::numeric_limits<size_t>::max();
200 #endif
201
202 PXR_NAMESPACE_CLOSE_SCOPE
203
204 #endif // PXR_USD_PCP_TYPES_H
205