All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
instancing.h
Go to the documentation of this file.
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 PCP_INSTANCING_H
25 #define PCP_INSTANCING_H
26 
31 
32 #include "pxr/pxr.h"
33 #include "pxr/usd/pcp/composeSite.h"
34 #include "pxr/usd/pcp/node_Iterator.h"
35 #include "pxr/usd/pcp/primIndex.h"
36 
37 PXR_NAMESPACE_OPEN_SCOPE
38 
43 bool
44 Pcp_PrimIndexIsInstanceable(
45  const PcpPrimIndex& primIndex);
46 
62 template <class Visitor>
63 void
64 Pcp_TraverseInstanceableStrongToWeak(
65  const PcpPrimIndex& primIndex,
66  Visitor* visitor);
67 
80 template <class Visitor>
81 void
82 Pcp_TraverseInstanceableWeakToStrong(
83  const PcpPrimIndex& primIndex,
84  Visitor* visitor);
85 
86 // Implementation ----------------------------------------
87 
88 inline bool
89 Pcp_ChildNodeIsInstanceable(
90  const PcpNodeRef& node)
91 {
92  // Non-ancestral nodes are instanceable: they represent a direct
93  // composition arc to a portion of scenegraph that could be shared
94  // with other prim indexes, as long as the other criteria laid out
95  // in PcpInstanceKey are met.
96  //
97  // If a node has no specs, we do not consider it instanceable since
98  // it has no opinions to contribute to the prim index. In particular,
99  // this allows prim indexes with implied arcs in different layer stacks
100  // that have no overrides to still be considered equivalent for sharing.
101  return !node.IsDueToAncestor() && node.HasSpecs();
102 }
103 
104 inline bool
105 Pcp_ChildNodeInstanceableChanged(
106  const PcpNodeRef& node)
107 {
108  return !node.IsDueToAncestor()
109  && (PcpComposeSiteHasPrimSpecs(node) != node.HasSpecs());
110 }
111 
112 template <class Visitor>
113 inline void
114 Pcp_TraverseInstanceableStrongToWeakHelper(
115  const PcpNodeRef& node,
116  Visitor* visitor)
117 {
118  // If the node is culled, the entire subtree rooted at this node
119  // does not contribute to the prim index, so we can prune the
120  // traversal.
121  if (node.IsCulled()) {
122  return;
123  }
124 
125  if (!visitor->Visit(node, Pcp_ChildNodeIsInstanceable(node))) {
126  return;
127  }
128 
129  TF_FOR_ALL(childIt, Pcp_GetChildrenRange(node)) {
130  const PcpNodeRef& childNode = *childIt;
131  Pcp_TraverseInstanceableStrongToWeakHelper(childNode, visitor);
132  }
133 }
134 
135 template <class Visitor>
136 inline void
137 Pcp_TraverseInstanceableStrongToWeak(
138  const PcpPrimIndex& primIndex,
139  Visitor* visitor)
140 {
141  const PcpNodeRef& rootNode = primIndex.GetRootNode();
142  if (!visitor->Visit(rootNode, /* nodeIsInstanceable = */ false)) {
143  return;
144  }
145 
146  TF_FOR_ALL(childIt, Pcp_GetChildrenRange(rootNode)) {
147  const PcpNodeRef& childNode = *childIt;
148  Pcp_TraverseInstanceableStrongToWeakHelper(childNode, visitor);
149  }
150 }
151 
152 template <class Visitor>
153 inline void
154 Pcp_TraverseInstanceableWeakToStrongHelper(
155  const PcpNodeRef& node,
156  Visitor* visitor)
157 {
158  // If the node is culled, the entire subtree rooted at this node
159  // does not contribute to the prim index, so we can prune the
160  // traversal.
161  if (node.IsCulled()) {
162  return;
163  }
164 
165  TF_REVERSE_FOR_ALL(childIt, Pcp_GetChildrenRange(node)) {
166  const PcpNodeRef& childNode = *childIt;
167  Pcp_TraverseInstanceableWeakToStrongHelper(childNode, visitor);
168  }
169 
170  visitor->Visit(node, Pcp_ChildNodeIsInstanceable(node));
171 }
172 
173 template <class Visitor>
174 inline void
175 Pcp_TraverseInstanceableWeakToStrong(
176  const PcpPrimIndex& primIndex,
177  Visitor* visitor)
178 {
179  const PcpNodeRef& rootNode = primIndex.GetRootNode();
180  TF_REVERSE_FOR_ALL(childIt, Pcp_GetChildrenRange(rootNode)) {
181  const PcpNodeRef& childNode = *childIt;
182  Pcp_TraverseInstanceableWeakToStrongHelper(childNode, visitor);
183  }
184 
185  visitor->Visit(rootNode, /* nodeIsInstanceable = */ false);
186 }
187 
188 PXR_NAMESPACE_CLOSE_SCOPE
189 
190 #endif // PCP_INSTANCING_H
PCP_API bool IsDueToAncestor() const
Returns true if this node is due to an ancestral opinion.
PcpPrimIndex is an index of the all sites of scene description that contribute opinions to a specific...
Definition: primIndex.h:77
PcpNode represents a node in an expression tree for compositing scene description.
Definition: node.h:65
#define TF_FOR_ALL(iter, c)
Macro for iterating over a container.
Definition: iterator.h:390
PCP_API PcpNodeRef GetRootNode() const
Returns the root node of the prim index graph.
#define TF_REVERSE_FOR_ALL(iter, c)
Macro for iterating over a container in reverse.
Definition: iterator.h:399
PCP_API bool PcpComposeSiteHasPrimSpecs(PcpLayerStackRefPtr const &layerStack, SdfPath const &path)
Has prim specs.