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