1 //
2 // Copyright 2018 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_IMAGING_USD_IMAGING_INDEX_PROXY_H
25 #define PXR_USD_IMAGING_USD_IMAGING_INDEX_PROXY_H
26 
27 /// \file usdImaging/indexProxy.h
28 
29 #include "pxr/pxr.h"
30 #include "pxr/usdImaging/usdImaging/api.h"
31 #include "pxr/usdImaging/usdImaging/delegate.h"
32 
33 #include "pxr/usd/sdf/path.h"
34 #include "pxr/usd/usd/prim.h"
35 
36 #include "pxr/base/tf/token.h"
37 
38 
39 PXR_NAMESPACE_OPEN_SCOPE
40 
41 
42 /// \class UsdImagingIndexProxy
43 ///
44 /// This proxy class exposes a subset of the private Delegate API to
45 /// PrimAdapters.
46 ///
47 class UsdImagingIndexProxy {
48 public:
49     /// A note on paths/prims: the core function of UsdImagingIndexProxy and
50     /// UsdImagingDelegate is to maintain a set of mappings between USD prims
51     /// and hydra prims (and a set of adapters that know how to translate
52     /// USD properties to hydra buffers).  A USD prim can represent multiple
53     /// hydra prims (e.g. point instancer prototypes that are referenced twice),
54     /// and a hydra prim can represent multiple USD prims (e.g. a single hydra
55     /// instancer prim representing multiple native instances).
56     ///
57     /// There are three different prim "namespaces" that the delegate works
58     /// with: "USD paths", which represent paths to USD prims; "index paths",
59     /// which represent paths to hydra prims in the render index; and
60     /// "cache paths", which represent paths to buffers in the value cache
61     /// backing hydra prims.  Cache paths and index paths are the same,
62     /// except that index paths have the "delegateID" prefixed onto their path.
63     ///
64     /// Index paths are only used in the interface to hydra.  In IndexProxy
65     /// and the adapters, the pattern is to use "cachePath" as a key to look
66     /// up state for a hydra prim; and pass "usdPrim" when we additionally
67     /// need to specify the related USD prim.  The naming helps clarify them,
68     /// and the fact that we pass a UsdPrim and not an SdfPath further ensures
69     /// that we pass valid USD paths instead of passing cache paths by mistake.
70 
71 
72     /// Adds a dependency from the given usdPrim to the given cache path.
73     /// Insert* will automatically add a dependency, so this is for hydra prims
74     /// that may depend on more than one usd prim (e.g. subsets, instancers)
75     USDIMAGING_API
76     void AddDependency(SdfPath const& cachePath,
77                        UsdPrim const& usdPrim);
78 
79     /// Insert a hydra prim with the specified cache path.  As mentioned above,
80     /// the delegateID will be prepended before adding the prim in hydra, but
81     /// cachePath will be the key into all internal usdImaging datastructures.
82     /// usdPrim is the USD prim this hydra prim is representing (e.g. the
83     /// UsdGeomMesh for which we are inserting a hydra mesh).  If no
84     /// adapter is specified, UsdImagingDelegate will choose based on Usd
85     /// prim type; some clients (e.g. instancing) want to override the adapter
86     /// choice but this should be used sparingly.
87     ///
88     /// For Rprims and Instancers, "parentPath" is the parent instancer.
89     USDIMAGING_API
90     void InsertRprim(TfToken const& primType,
91                      SdfPath const& cachePath,
92                      UsdPrim const& usdPrim,
93                      UsdImagingPrimAdapterSharedPtr adapter =
94                         UsdImagingPrimAdapterSharedPtr());
95 
96     USDIMAGING_API
97     void InsertSprim(TfToken const& primType,
98                      SdfPath const& cachePath,
99                      UsdPrim const& usdPrim,
100                      UsdImagingPrimAdapterSharedPtr adapter =
101                         UsdImagingPrimAdapterSharedPtr());
102 
103     USDIMAGING_API
104     void InsertBprim(TfToken const& primType,
105                      SdfPath const& cachePath,
106                      UsdPrim const& usdPrim,
107                      UsdImagingPrimAdapterSharedPtr adapter =
108                         UsdImagingPrimAdapterSharedPtr());
109 
110     USDIMAGING_API
111     void InsertInstancer(SdfPath const& cachePath,
112                          UsdPrim const& usdPrim,
113                          UsdImagingPrimAdapterSharedPtr adapter =
114                             UsdImagingPrimAdapterSharedPtr());
115 
116     // Mark a prim as needing follow-up work by the delegate
117     // (e.g. TrackVariability); this is automatically called on Insert*, but
118     // needs to manually be called in some special cases like native
119     // instancer population.
120     USDIMAGING_API
121     void Refresh(SdfPath const& cachePath);
122 
123     //
124     // All removals are deferred to avoid surprises during change processing.
125     //
126 
127     // Removes the Rprim at the specified cache path.
RemoveRprim(SdfPath const & cachePath)128     void RemoveRprim(SdfPath const& cachePath) {
129         _rprimsToRemove.push_back(cachePath);
130         _hdPrimInfoToRemove.push_back(cachePath);
131         _RemoveDependencies(cachePath);
132     }
133 
134     // Removes the Sprim at the specified cache path.
RemoveSprim(TfToken const & primType,SdfPath const & cachePath)135     void RemoveSprim(TfToken const& primType, SdfPath const& cachePath) {
136         _TypeAndPath primToRemove = {primType, cachePath};
137         _sprimsToRemove.push_back(primToRemove);
138         _hdPrimInfoToRemove.push_back(cachePath);
139         _RemoveDependencies(cachePath);
140     }
141 
142     // Removes the Bprim at the specified cache path.
RemoveBprim(TfToken const & primType,SdfPath const & cachePath)143     void RemoveBprim(TfToken const& primType, SdfPath const& cachePath) {
144         _TypeAndPath primToRemove = {primType, cachePath};
145         _bprimsToRemove.push_back(primToRemove);
146         _hdPrimInfoToRemove.push_back(cachePath);
147         _RemoveDependencies(cachePath);
148     }
149 
150     // Removes the HdInstancer at the specified cache path.
RemoveInstancer(SdfPath const & cachePath)151     void RemoveInstancer(SdfPath const& cachePath) {
152         _instancersToRemove.push_back(cachePath);
153         _hdPrimInfoToRemove.push_back(cachePath);
154         _RemoveDependencies(cachePath);
155     }
156 
157     USDIMAGING_API
158     void MarkRprimDirty(SdfPath const& cachePath, HdDirtyBits dirtyBits);
159 
160     USDIMAGING_API
161     void MarkSprimDirty(SdfPath const& cachePath, HdDirtyBits dirtyBits);
162 
163     USDIMAGING_API
164     void MarkBprimDirty(SdfPath const& cachePath, HdDirtyBits dirtyBits);
165 
166     USDIMAGING_API
167     void MarkInstancerDirty(SdfPath const& cachePath, HdDirtyBits dirtyBits);
168 
169     USDIMAGING_API
170     bool IsRprimTypeSupported(TfToken const& typeId) const;
171 
172     USDIMAGING_API
173     bool IsSprimTypeSupported(TfToken const& typeId) const;
174 
175     USDIMAGING_API
176     bool IsBprimTypeSupported(TfToken const& typeId) const;
177 
178     // Check if the given path has been populated yet.
179     USDIMAGING_API
180     bool IsPopulated(SdfPath const& cachePath) const;
181 
182     // Recursively repopulate the specified usdPath into the render index.
183     USDIMAGING_API
184     void Repopulate(SdfPath const& usdPath);
185 
186     USDIMAGING_API
187     UsdImagingPrimAdapterSharedPtr GetMaterialAdapter(
188         UsdPrim const& materialPrim);
189 
190     // XXX: This is a workaround for some bugs in USD edit processing, and
191     // the weird use of HdPrimInfo by instanced prims. It removes the dependency
192     // between a hydra prim and whatever USD prim is in its primInfo, since this
193     // dependency is automatically inserted and for instanced prims will
194     // erroneously add a dependency between a hydra prototype and
195     // a USD instancer.
196     //
197     // Pending some refactoring, hopefully this API will disappear.
198     USDIMAGING_API
199     void RemovePrimInfoDependency(SdfPath const& cachePath);
200 
201 private:
202     friend class UsdImagingDelegate;
UsdImagingIndexProxy(UsdImagingDelegate * delegate,UsdImagingDelegate::_Worker * worker)203     UsdImagingIndexProxy(UsdImagingDelegate* delegate,
204                             UsdImagingDelegate::_Worker* worker)
205         : _delegate(delegate)
206         , _worker(worker)
207     {}
208 
209     // Sort and de-duplicate "repopulate" paths to prevent double-inserts.
210     // Called by UsdImagingDelegate::ApplyPendingUpdates.
211     void _UniqueifyPathsToRepopulate();
212 
213     UsdImagingDelegate::_HdPrimInfo*
214         _AddHdPrimInfo(SdfPath const& cachePath,
215                        UsdPrim const& usdPrim,
216                        UsdImagingPrimAdapterSharedPtr const& adapter);
217 
218     USDIMAGING_API
219     void _RemoveDependencies(SdfPath const& cachePath);
220 
_GetUsdPathsToRepopulate()221     SdfPathVector const& _GetUsdPathsToRepopulate() {
222         return _usdPathsToRepopulate;
223     }
224     void _ProcessRemovals();
225 
226     void _AddTask(SdfPath const& usdPath);
227 
228     struct _TypeAndPath {
229         TfToken primType;
230         SdfPath cachePath;
231     };
232 
233     typedef std::vector<_TypeAndPath> _TypeAndPathVector;
234 
235     typedef std::vector<UsdImagingDelegate::_DependencyMap::value_type>
236         _DependencyVector;
237 
238     UsdImagingDelegate* _delegate;
239     UsdImagingDelegate::_Worker* _worker;
240     SdfPathVector _usdPathsToRepopulate;
241     SdfPathVector _rprimsToRemove;
242     _TypeAndPathVector _sprimsToRemove;
243     _TypeAndPathVector _bprimsToRemove;
244     SdfPathVector _instancersToRemove;
245     SdfPathVector _hdPrimInfoToRemove;
246     _DependencyVector _dependenciesToRemove;
247 };
248 
249 
250 PXR_NAMESPACE_CLOSE_SCOPE
251 
252 #endif //PXR_USD_IMAGING_USD_IMAGING_INDEX_PROXY_H
253