HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
XUSD_Data.h
Go to the documentation of this file.
1 /*
2  * Copyright 2019 Side Effects Software Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17 
18 #ifndef __HUSD_Data_h__
19 #define __HUSD_Data_h__
20 
21 #include "HUSD_API.h"
22 #include "HUSD_DataHandle.h"
23 #include "HUSD_PostLayers.h"
24 #include "HUSD_Overrides.h"
25 #include "XUSD_DataLock.h"
26 #include "XUSD_LockedGeo.h"
27 #include "XUSD_PathSet.h"
28 #include "XUSD_RootLayerData.h"
29 #include <UT/UT_Color.h>
30 #include <UT/UT_StringArray.h>
31 #include <UT/UT_StringHolder.h>
32 #include <UT/UT_StringSet.h>
33 #include <UT/UT_IntrusivePtr.h>
34 #include <UT/UT_SharedPtr.h>
35 #include <UT/UT_UniquePtr.h>
36 #include <pxr/usd/usd/stage.h>
39 #include <pxr/usd/sdf/path.h>
40 
41 // `XUSD_LayerAtPath` has a `std::string` member variable, which is not
42 // generally considered trivially relocatable (and is definitely not T.R.
43 // in libstdc++ when using the CXX11 ABI). As such, it is not safe to use
44 // this in a `UT_Array` as-is, and we must "decorate" it first.
45 // See https://internal.sidefx.com/bugdb/#/view/135774 for an instance of
46 // `XUSD_LayerAtPathArray` causing issues in gcc11 builds when short paths
47 // (triggering short-string-optimisation) are used.
48 // If either the `std::string` member is removed, or we no longer use this
49 // class in a `UT_Array`, the following block can be removed.
51 class XUSD_LayerAtPath;
53 SYS_DECLARE_IS_NOT_TR(PXR_NS::XUSD_LayerAtPath)
54 
56 
57 // Control the addLayers method. Most of these values only affect the version
58 // of addLayer which takes a vector of file paths (instead of layers pointers).
60 {
61  // Simply add the layers "as-is" to the root layer's list of sublayers,
62  // using the layer's identifier or the provided file paths. The data
63  // handle's active layer is set to be created after all the added layers.
65  // Each layer is copied into an anonymous layer, and these anonymous
66  // layers get added to the sublayer list. This means these layers will
67  // we saved as new USD files during a save process. The last layer becomes
68  // the data handle's active layer for following edits.
70  // All layers are added "as-is", except the last layer in the list, which
71  // is copied to an anonymous layer. This last anonymous layer becomes the
72  // data handle's active layer for following edits.
74 
75  // Used only by HUSD_Stitch, layers authored by LOP nodes all get copied
76  // to new anonymous layers (so they can be safely modified when stitching
77  // in the next time sample of data, if there is one.). If the last layer
78  // is a LOP layer, it becomes the active layer modified by following LOP
79  // nodes.
81  // Used only by HUSD_Stitch, if the last layer was authored by LOP nodes,
82  // it gets copied to a new anonymous layer (so it can be modified by
83  // following LOP nodes as the active layer). Preceding layers are not
84  // copied, which is fine if this is the last time sample that will be
85  // stitched into this data handle.
87 };
88 
90 {
91 public:
93  explicit XUSD_LayerAtPath(const SdfLayerRefPtr &layer,
95  int layer_badge_index = 0);
96  explicit XUSD_LayerAtPath(const SdfLayerRefPtr &layer,
97  const std::string &filepath,
99  int layer_badge_index = 0);
100 
101  bool hasLayerColorIndex(int &clridx) const;
102  bool isLopLayer() const;
103 
110 };
111 
113 
115 {
116 public:
117  XUSD_OverridesInfo(const UsdStageRefPtr &stage);
119 
120  bool isEmpty() const
121  { return !myReadOverrides && !myWriteOverrides; }
122 
127 };
128 
130 {
131 public:
132  XUSD_PostLayersInfo(const UsdStageRefPtr &stage);
134 
135  bool isEmpty() const
136  { return !myPostLayers; }
137 
141 };
142 
143 class HUSD_API XUSD_Data : public UT_IntrusiveRefCounter<XUSD_Data>,
144  public UT_NonCopyable
145 {
146 public:
147  XUSD_Data(HUSD_MirroringType mirroring);
148  explicit XUSD_Data(const UsdStageRefPtr &stage);
149  ~XUSD_Data();
150 
151  // Return true if our stage value is set and has a valid root prim.
152  bool isStageValid() const;
153  // Returns our stage. Should only be accessed when this data is locked.
154  UsdStageRefPtr stage() const;
155  // Returns the active layer on our composed stage.
156  SdfLayerRefPtr activeLayer() const;
157  // Return true if the active layer of this data will be returned as the
158  // active layer when a downstream copy of this data is locked for writing.
159  bool activeLayerIsReusable() const;
160  // Return the on-stage identifiers of any layers that are marked in the
161  // source layers array to be removed due to a layer break.
162  std::set<std::string> getStageLayersToRemoveFromLayerBreak() const;
163  // Creates a layer by flattening all our source layers together. Also
164  // strips out any layers tagged by a Layer Break LOP.
165  SdfLayerRefPtr createFlattenedLayer(
166  HUSD_StripLayerResponse response) const;
167  // Creates a layer by flattening a stage consisting of our source layers
168  // after stripping out any layers tagged by a Layer Break LOP.
169  SdfLayerRefPtr createFlattenedStage(
170  HUSD_StripLayerResponse response) const;
171 
172  // Return the array of source layers that are combined to make our stage.
173  const XUSD_LayerAtPathArray &sourceLayers() const;
174  // Return the current session layer overrides set on our stage.
175  const HUSD_ConstOverridesPtr&overrides() const;
176  // Return the current session layer post layers set on our stage.
177  const HUSD_ConstPostLayersPtr&postLayers() const;
178  // Return a specific session layer object on our stage.
179  const SdfLayerRefPtr &sessionLayer(HUSD_OverridesLayerId id) const;
180  // Return the current load masks set on our stage.
181  const HUSD_LoadMasksPtr &loadMasks() const;
182  // Return the identifier of our stage's root layer. This can be used as
183  // a quick check as to whether we have created a brand new stage.
184  const std::string &rootLayerIdentifier() const;
185 
186  // Add a layer using a file path, layer pointer, or an empty layer.
187  // Files and layer pointers can be inserted at any position in the
188  // sublayer list (0 is strongest, -1 is weakest). The layer op value
189  // indicates whether the layer should be editable, which implies that
190  // it must be added to the strongest position (the only place where a
191  // layer can be edited).
192  bool addLayer(const std::string &filepath,
193  const SdfLayerOffset &offset,
194  int position,
195  XUSD_AddLayerOp add_layer_op,
196  bool copy_root_prim_metadata);
197  bool addLayer(const XUSD_LayerAtPath &layer,
198  int position,
199  XUSD_AddLayerOp add_layer_op,
200  bool copy_root_prim_metadata);
201  // Methods for adding a bunch of layers to our stage in one call. These
202  // methods only unlock and re-lock the data once (meaning only a single
203  // recomposition is required). The resulting behavior of this call is the
204  // same as calling addLayer on each individual layer in order.
205  bool addLayers(
206  const std::vector<std::string> &paths,
207  const std::vector<bool> &above_breaks,
209  int position,
210  XUSD_AddLayerOp add_layer_op,
211  bool copy_root_prim_metadata);
212  bool addLayers(
213  const std::vector<std::string> &paths,
214  const SdfLayerOffsetVector &offsets,
215  int position,
216  XUSD_AddLayerOp add_layer_op,
217  bool copy_root_prim_metadata);
218  bool addLayers(const XUSD_LayerAtPathArray &layers,
219  int position,
220  XUSD_AddLayerOp add_layer_op,
221  bool copy_root_prim_metadata);
222  // Add a single new empty layer.
223  bool addLayer();
224 
225  // Remove one or more of our source layers.
226  bool removeLayers(
227  const std::set<std::string> &filepaths);
228 
229  // Used to do something roughyl equivalent to a mirror operation, but on
230  // a data handle not meant for mirroring.
231  bool replaceAllSourceLayers(
232  const XUSD_LayerAtPathArray &layers,
233  const XUSD_LockedGeoSet &locked_geos,
234  const XUSD_LayerSet &held_layers,
235  const XUSD_LayerSet &replacement_layers,
236  const HUSD_LockedStageSet &locked_stages,
238  &root_layer_data,
239  bool last_sublayer_is_editable);
240 
241  // Apply a layer break, which tags all existing layers, and adds a new
242  // empty layer for holding future modification.
243  bool applyLayerBreak();
244 
245  // Set a piece of metadata on the root prim of the root layer of the
246  // stage. Also record this change to myRootLayerData so that we can
247  // restore this metadata value if we lock this stage to another state
248  // then return to this state.
249  void setStageRootPrimMetadata(const TfToken &field,
250  const VtValue &value);
251  void setStageRootLayerData(
253  &rootlayerdata);
254  void setStageRootLayerData(
255  const SdfLayerRefPtr &layer);
256 
257  // Store a lockedgeo in with this data to keep alive cooked sop data in the
258  // XUSD_LockedGeoRegistry as long as it might be referenced by our stage.
259  void addLockedGeo(
260  const XUSD_LockedGeoPtr &lockedgeo);
261  void addLockedGeos(
262  const XUSD_LockedGeoSet &lockedgeos);
263  const XUSD_LockedGeoSet &lockedGeos() const;
264 
265  // Store a reference to a layer with this data, to keep it alive.
266  // Anonymous layers can be dropped by the stage in certain circumstances
267  // if there are no external references to them.
268  void addHeldLayer(
269  const SdfLayerRefPtr &layer);
270  void addHeldLayers(
271  const XUSD_LayerSet &layers);
272  const XUSD_LayerSet &heldLayers() const;
273 
274  // Store pointers to arrays that were created automatically as part of a
275  // process of replacing a layer on disk with an anonymous layer.
276  void addReplacements(
277  const XUSD_LayerSet &replacements);
278  const XUSD_LayerSet &replacements() const;
279 
280  // Store a locked stage with this data to keep alive cooked lop data in the
281  // HUSD_LockedStageRegistry as long as it might be referenced by our stage.
282  void addLockedStage(
283  const HUSD_LockedStagePtr &stage);
284  void addLockedStages(
285  const HUSD_LockedStageSet &stages);
286  const HUSD_LockedStageSet &lockedStages() const;
287 
288  // Clear out all mirrored stages completely. They must be rebuilt from
289  // scratch the next time they are asked to mirror a stage.
290  static void clearAllMirroredData();
291 
292 private:
293  void reset();
294  void createNewData(const HUSD_LoadMasksPtr &load_masks,
295  int resolver_context_nodeid,
296  const UsdStageWeakPtr &resolver_context_stage,
297  const ArResolverContext *resolver_context);
298  void createHardCopy(const XUSD_Data &src);
299  void createSoftCopy(const XUSD_Data &src,
300  const HUSD_LoadMasksPtr &load_masks,
301  bool make_new_implicit_layer);
302  void createCopyWithReplacement(
303  const XUSD_Data &src,
304  const UT_StringRef &frompath,
305  const UT_StringRef &topath,
306  int nodeid,
307  HUSD_MakeNewPathFunc make_new_path,
308  UT_StringSet &replaced_layers);
309 
310  // Return the resolver context for our stage. Note that this method does
311  // not require that the stage be locked, because it is unchanging data set
312  // on the stage when it was created.
313  ArResolverContext resolverContext() const;
314 
315  // Return a layer created by flattening all source layers up to the
316  // strongest layer excluded by a Layer Break node.
317  void flattenLayers(const XUSD_Data &src,
318  int creator_node_id);
319  // Return a layer created by flattening the stage composed of all source
320  // layers up to the strongest layer excluded by a Layer Break node.
321  void flattenStage(const XUSD_Data &src,
322  int creator_node_id);
323  // Utility method used by the two flatten methods above to separate all
324  // layers preceding a layer break point. Optionally creates a warning if
325  // a layer break is found.
326  UsdStageRefPtr getOrCreateStageForFlattening(
327  HUSD_StripLayerResponse response,
328  UsdStage::InitialLoadSet loadset) const;
329 
330  void mirror(const XUSD_Data &src,
331  const HUSD_LoadMasks &load_masks);
332  bool mirrorUpdateRootLayer(
333  const HUSD_MirrorRootLayer &rootlayer);
334 
335  void afterLock(bool for_write,
337  &read_overrides = HUSD_ConstOverridesPtr(),
338  const HUSD_OverridesPtr
339  &write_overrides = HUSD_OverridesPtr(),
341  &postlayers = HUSD_ConstPostLayersPtr(),
342  bool remove_layer_breaks = false);
343  XUSD_LayerPtr editActiveSourceLayer(bool create_change_block);
344  void createInitialPlaceholderSublayers();
345  void applyRootLayerDataToStage();
346  void afterRelease();
347 
348  static void exitCallback(void *);
349 
350  UsdStageRefPtr myStage;
351  UT_SharedPtr<UT_StringArray> myStageLayerAssignments;
352  UT_SharedPtr<XUSD_LayerArray> myStageLayers;
353  UT_SharedPtr<int> myStageLayerCount;
354  UT_SharedPtr<XUSD_OverridesInfo> myOverridesInfo;
355  UT_SharedPtr<XUSD_PostLayersInfo> myPostLayersInfo;
356  UT_SharedPtr<XUSD_RootLayerData> myRootLayerData;
357  XUSD_LayerAtPathArray mySourceLayers;
358  HUSD_LoadMasksPtr myLoadMasks;
359  XUSD_DataLockPtr myDataLock;
360  XUSD_LockedGeoSet myLockedGeos;
361  XUSD_LayerSet myReplacementLayers;
362  HUSD_LockedStageSet myLockedStages;
363  XUSD_LayerSet myHeldLayers;
364  HUSD_MirroringType myMirroring;
365  UsdStageLoadRules myMirrorLoadRules;
366  UT_StringMap<UT_StringArray> myMirrorVariantSelectionFallbacks;
367  bool myMirrorLoadRulesChanged;
368  int myActiveLayerIndex;
369  bool myOwnsActiveLayer;
370 
371  friend class ::HUSD_DataHandle;
372 };
373 
374 class HUSD_API XUSD_Layer : public UT_IntrusiveRefCounter<XUSD_Layer>
375 {
376 public:
378  bool create_change_block)
379  : myLayer(layer),
380  myChangeBlock(nullptr)
381  {
382  if (create_change_block)
383  myChangeBlock.reset(
384  new SdfChangeBlock());
385  }
387  { }
388 
389  const SdfLayerRefPtr &layer() const
390  { return myLayer; }
391 
392 private:
393  SdfLayerRefPtr myLayer;
394  UT_UniquePtr<SdfChangeBlock> myChangeBlock;
395 };
396 
398 
399 #endif
400 
std::string myIdentifier
Definition: XUSD_Data.h:105
const SdfLayerRefPtr & layer() const
Definition: XUSD_Data.h:389
Definition: XUSD_Data.h:129
SdfLayerOffset myOffset
Definition: XUSD_Data.h:106
UT_SharedPtr< HUSD_LoadMasks > HUSD_LoadMasksPtr
GLbitfield stages
Definition: glcorearb.h:1931
HUSD_MirroringType
HUSD_OverridesPtr myWriteOverrides
Definition: XUSD_Data.h:124
exint myVersionId
Definition: XUSD_Data.h:140
bool isLopLayer() const
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
UT_IntrusivePtr< const HUSD_Overrides > HUSD_ConstOverridesPtr
int64 exint
Definition: SYS_Types.h:125
#define HUSD_API
Definition: HUSD_API.h:32
XUSD_Layer(const SdfLayerRefPtr &layer, bool create_change_block)
Definition: XUSD_Data.h:377
bool isEmpty() const
Definition: XUSD_Data.h:120
InitialLoadSet
Definition: stage.h:164
A reference counter base class for use with UT_IntrusivePtr.
UsdStagePtr UsdStageWeakPtr
Definition: common.h:55
UT_IntrusivePtr< const HUSD_PostLayers > HUSD_ConstPostLayersPtr
UT_IntrusivePtr< HUSD_Overrides > HUSD_OverridesPtr
bool myLayerIsMissingFile
Definition: XUSD_Data.h:109
GLenum GLuint GLint GLint layer
Definition: glcorearb.h:1299
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
GLuint GLsizei const GLuint const GLintptr * offsets
Definition: glcorearb.h:2621
HUSD_OverridesLayerId
Definition: HUSD_Utils.h:74
std::vector< SdfLayerOffset > SdfLayerOffsetVector
Definition: layerOffset.h:174
Definition: token.h:87
GLintptr offset
Definition: glcorearb.h:665
GLboolean reset
Definition: glad.h:5138
HUSD_ConstOverridesPtr myReadOverrides
Definition: XUSD_Data.h:123
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
std::vector< TfRefPtr< SdfLayer > > SdfLayerRefPtrVector
~XUSD_PostLayersInfo()
#define HUSD_OVERRIDES_NUM_LAYERS
Definition: HUSD_Utils.h:82
HUSD_ConstPostLayersPtr myPostLayers
Definition: XUSD_Data.h:138
HUSD_StripLayerResponse
Definition: HUSD_Utils.h:92
#define SYS_DECLARE_IS_NOT_TR(T)
Declare that that trivial relocation with type T is not guaranteed to be safe.
bool isEmpty() const
Definition: XUSD_Data.h:135
bool hasLayerColorIndex(int &clridx) const
UT_Function< UT_StringHolder(const UT_StringRef &oldpath)> HUSD_MakeNewPathFunc
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
UT_Array< XUSD_LayerAtPath > XUSD_LayerAtPathArray
Definition: XUSD_Data.h:112
XUSD_AddLayerOp
Definition: XUSD_Data.h:59
UT_SharedPtr< HUSD_LockedStage > HUSD_LockedStagePtr
SIM_API const UT_StringHolder position
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
SdfLayerRefPtr mySessionLayers[HUSD_OVERRIDES_NUM_LAYERS]
Definition: XUSD_Data.h:125
SdfLayerRefPtr myLayer
Definition: XUSD_Data.h:104
XUSD_PostLayersInfo(const UsdStageRefPtr &stage)
bool myRemoveWithLayerBreak
Definition: XUSD_Data.h:108
Definition: core.h:1131
SdfLayerRefPtrVector mySessionLayers
Definition: XUSD_Data.h:139
XUSD_OverridesInfo(const UsdStageRefPtr &stage)
Definition: value.h:164
GLenum src
Definition: glcorearb.h:1793