HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
namespaceEditor.h
Go to the documentation of this file.
1 //
2 // Copyright 2023 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_USD_USD_NAMESPACE_EDITOR_H
8 #define PXR_USD_USD_NAMESPACE_EDITOR_H
9 
10 /// \file usd/namespaceEditor.h
11 
12 #include "pxr/pxr.h"
13 #include "pxr/usd/usd/api.h"
14 #include "pxr/usd/usd/common.h"
15 #include "pxr/usd/usd/stage.h"
18 
20 
21 /// @warning
22 /// This code is a work in progress and should not be used in production
23 /// scenarios. It is currently not feature-complete and subject to change.
24 ///
25 /// Provides namespace editing operations
27 {
28 public:
29  /// Structure for holding the options for how the namespace editor will
30  /// behave when trying to perform edits.
31  struct EditOptions {
32 
33  /// Whether the namespace editor will allow the authoring of relocates
34  /// in order to perform edits that would otherwise not be possible
35  /// because of opinions across composition arcs. By default this is set
36  /// to true. If set to false the namespace editor will consider edits
37  /// that require relocates as errors and will not apply the edit.
39  };
40 
41  USD_API
42  explicit UsdNamespaceEditor(const UsdStageRefPtr &stage);
43 
44  USD_API
46  const UsdStageRefPtr &stage,
47  EditOptions &&editOptions);
48 
49  USD_API
51  const UsdStageRefPtr &stage,
52  const EditOptions &editOptions);
53 
54  /// \name Dependent Stages
55  ///
56  /// Dependent stages are additional stages that may have composition
57  /// dependencies on the layer edits made for the editor's primary stage.
58  /// By adding dependent stages, the editor can make additional edits so that
59  /// affected composition arcs and specs that depend on affected composition
60  /// in composed prims on these stages are updated to compose with the moved
61  /// prim specs or, in the case of deletions, removed when the specs they
62  /// depend on are removed.
63  ///
64  /// Dependencies in the dependent stages are based only what is currently
65  /// loaded for those stages. In other words, the editor cannot find and
66  /// edit dependencies from unloaded payloads, inactive prim children,
67  /// prims that are load mask filtered, unselected variants, etc. The primary
68  /// stage of this editor is always a dependent stage, meaning that edits
69  /// will always be made to maintain affected composition dependencies in the
70  /// primary stage.
71  ///
72  /// @{
73 
74  /// Adds the given \p stage as a dependent stage of this namespace editor.
75  USD_API
76  void AddDependentStage(const UsdStageRefPtr &stage);
77 
78  /// Removes the given \p stage as a dependent stage of this namespace editor.
79  USD_API
80  void RemoveDependentStage(const UsdStageRefPtr &stage);
81 
82  /// Sets the list of dependent stages for this namespace editor to
83  /// \p stages.
84  USD_API
85  void SetDependentStages(const UsdStageRefPtrVector &stages);
86 
87  /// @}
88 
89  /// Adds an edit operation to delete the composed prim at the given \p path
90  /// from this namespace editor's stage.
91  ///
92  /// Returns true if the path is a valid possible composed prim path; returns
93  /// false and emits a coding error if not.
94  USD_API
95  bool DeletePrimAtPath(
96  const SdfPath &path);
97 
98  /// Adds an edit operation to move the composed prim at the given \p path
99  /// on this namespace editor's stage to instead be at the path \p newPath.
100  ///
101  /// Returns true if both paths are valid possible composed prim path;
102  /// returns false and emits a coding error if not.
103  USD_API
104  bool MovePrimAtPath(
105  const SdfPath &path,
106  const SdfPath &newPath);
107 
108  /// Adds an edit operation to delete the composed prim at the path of
109  /// \p prim from this namespace editor's stage. This is equivalent to
110  /// calling DeletePrimAtPath(prim.GetPath())
111  ///
112  /// Returns true if the prim provides a valid possible composed prim path;
113  /// returns false and emits a coding error if not.
114  USD_API
115  bool DeletePrim(
116  const UsdPrim &prim);
117 
118  /// Adds an edit operation to rename the composed prim at the path of
119  /// \p prim on this namespace editor's stage to instead have the name
120  /// \p newName.
121  ///
122  /// Returns true if the prim provides a valid possible composed prim path
123  /// and the new name is a valid possible prim name; returns false and emits
124  /// a coding error if not.
125  USD_API
126  bool RenamePrim(
127  const UsdPrim &prim,
128  const TfToken &newName);
129 
130  /// Adds an edit operation to reparent the composed prim at the path of
131  /// \p prim on this namespace editor's stage to instead be a namespace
132  /// child of the composed prim at the path of \p newParent.
133  ///
134  /// Returns true if the both the prim and the new parent prim provide a
135  /// valid possible composed prim paths; returns false and emits a coding
136  /// error if not.
137  USD_API
138  bool ReparentPrim(
139  const UsdPrim &prim,
140  const UsdPrim &newParent);
141 
142  /// Adds an edit operation to reparent the composed prim at the path of
143  /// \p prim on this namespace editor's stage to instead be a prim named
144  /// \p newName that is a namespace child of the composed prim at the
145  /// path of \p newParent.
146  ///
147  /// Returns true if the both the prim and the new parent prim provide a
148  /// valid possible composed prim paths and the new name is a valid prim
149  /// name; returns false and emits a coding error if not.
150  USD_API
151  bool ReparentPrim(
152  const UsdPrim &prim,
153  const UsdPrim &newParent,
154  const TfToken &newName);
155 
156  /// Adds an edit operation to delete the composed property at the given
157  /// \p path from this namespace editor's stage.
158  ///
159  /// Returns true if the path is a valid possible composed property path;
160  /// returns false and emits a coding error if not.
161  USD_API
163  const SdfPath &path);
164 
165  /// Adds an edit operation to move the composed property at the given
166  /// \p path on this namespace editor's stage to instead be at the path
167  /// \p newPath.
168  ///
169  /// Returns true if both paths are valid possible composed property path;
170  /// returns false and emits a coding error if not.
171  USD_API
172  bool MovePropertyAtPath(
173  const SdfPath &path,
174  const SdfPath &newPath);
175 
176  /// Adds an edit operation to delete the composed property at the path of
177  /// \p property from this namespace editor's stage. This is equivalent to
178  /// calling DeletePropertyAtPath(property.GetPath())
179  ///
180  /// Returns true if the property provides a valid possible composed property
181  /// path; returns false and emits a coding error if not.
182  USD_API
183  bool DeleteProperty(
184  const UsdProperty &property);
185 
186  /// Adds an edit operation to rename the composed property at the path of
187  /// \p property on this namespace editor's stage to instead have the name
188  /// \p newName.
189  ///
190  /// Returns true if the property provides a valid possible composed property
191  /// path and the new name is a valid possible property name; returns false
192  /// and emits a coding error if not.
193  USD_API
194  bool RenameProperty(
195  const UsdProperty &property,
196  const TfToken &newName);
197 
198  /// Adds an edit operation to reparent the composed property at the path of
199  /// \p property on this namespace editor's stage to instead be a namespace
200  /// child of the composed property at the path of \p newParent.
201  ///
202  /// Returns true if the both the property and the new parent prim provide a
203  /// valid possible composed paths; returns false and emits a coding
204  /// error if not.
205  USD_API
206  bool ReparentProperty(
207  const UsdProperty &property,
208  const UsdPrim &newParent);
209 
210  /// Adds an edit operation to reparent the composed property at the path of
211  /// \p property on this namespace editor's stage to instead be a property
212  /// named \p newName that is a namespace child of the composed prim at the
213  /// path of \p newParent.
214  ///
215  /// Returns true if the both the property and the new parent prim provide a
216  /// valid possible composed paths and the new name is a valid property
217  /// name; returns false and emits a coding error if not.
218  USD_API
219  bool ReparentProperty(
220  const UsdProperty &property,
221  const UsdPrim &newParent,
222  const TfToken &newName);
223 
224  /// Applies all the added namespace edits stored in this to namespace editor
225  /// to its stage by authoring all scene description in the layer stack of
226  /// the current edit target necessary to move or delete the composed
227  /// objects that the edit paths refer to..
228  ///
229  /// Returns true if all the necessary edits are successfully performed;
230  /// returns false and emits a coding error otherwise.
231  USD_API
232  bool ApplyEdits();
233 
234  /// Returns whether all the added namespace edits stored in this to
235  /// namespace editor can be applied to its stage.
236  ///
237  /// In other words, this returns whether ApplyEdits should be successful if
238  /// it were called right now. If this would return false and \p whyNot is
239  /// provided, the reasons ApplyEdits would fail will be copied to whyNot.
240  USD_API
241  bool CanApplyEdits(std::string *whyNot = nullptr) const;
242 
243 private:
244 
245  // The type of edit that an edit description is describing.
246  enum class _EditType {
247  Invalid,
248 
249  Delete,
250  Rename,
251  Reparent
252  };
253 
254  // Description of an edit added to this namespace editor.
255  struct _EditDescription {
256  // Path to the existing object.
257  SdfPath oldPath;
258  // New path of the object after the edit is performed. An empty path
259  // indicates that the edit operation will delete the object.
260  SdfPath newPath;
261 
262  // Type of the edit as determined by the oldPath and the newPath.
263  _EditType editType = _EditType::Invalid;
264 
265  // Whether this describes a property edit or, otherwise, a prim edit.
266  bool IsPropertyEdit() const { return oldPath.IsPrimPropertyPath(); }
267  };
268 
269  // Struct representing the Sdf layer edits necessary to apply an edit
270  // description to the stage. We need this to gather all the information we
271  // can about what layer edits need to be performed before we start editing
272  // any specs so that we can avoid partial edits when a composed stage level
273  // namespace would fail.
274  struct _ProcessedEdit
275  {
276  // List of errors encountered that would prevent the overall namespace
277  // edit of the composed stage object from being completed successfully.
278  std::vector<std::string> errors;
279 
280  // The edit description of the primary edit.
281  _EditDescription editDescription;
282 
283  // The list of layers that have specs that need to have the Sdf
284  // namespace edit applied.
285  SdfLayerHandleVector layersToEdit;
286 
287  // Whether performing the edit will author new relocates.
288  bool willAuthorRelocates = false;
289 
290  // Layer edits that need to be performed to update connection and
291  // relationship targets of other properties in order to keep them
292  // targeting the same object after applying this processed edit.
294  // Property spec to author the new targets value to. Note that we
295  // store the spec handle for the property as the property spec's
296  // path could change if the property is moved or deleted by the
297  // primary namespace edit.
298  SdfPropertySpecHandle propertySpec;
299 
300  // Name of the field that holds the path targets for the property
301  // which differs for attributes vs relationships.
303 
304  // Updated list op value to set for the property spec.
306  };
307  std::vector<TargetPathListOpEdit> targetPathListOpEdits;
308 
309  // Full set of namespace edits that need to be performed for all the
310  // dependent stages of this editor as a result of dependencies on the
311  // initial spec move edits.
312  PcpDependentNamespaceEdits dependentStageNamespaceEdits;
313 
314  // List of errors encountered that would prevent connection and
315  // relationship target edits from being performed in response to the
316  // namespace edits.
317  std::vector<std::string> targetPathListOpErrors;
318 
319  // Applies this processed edit, performing the individual edits
320  // necessary to each layer that needs to be updated.
321  bool Apply();
322 
323  // Returns whether this processed edit can be applied.
324  bool CanApply(std::string *whyNot) const;
325  };
326 
327  // Adds an edit description for a prim delete operation.
328  bool _AddPrimDelete(const SdfPath &oldPath);
329 
330  // Adds an edit description for a prim rename or reparent operation.
331  bool _AddPrimMove(const SdfPath &oldPath, const SdfPath &newPath);
332 
333  // Adds an edit description for a property delete operation.
334  bool _AddPropertyDelete(const SdfPath &oldPath);
335 
336  // Adds an edit description for a property rename or reparent operation.
337  bool _AddPropertyMove(const SdfPath &oldPath, const SdfPath &newPath);
338 
339  // Clears the current procesed edits.
340  void _ClearProcessedEdits();
341 
342  // Processes and caches the layer edits necessary for the current edit
343  // operation if there is no cached processecd edit.
344  void _ProcessEditsIfNeeded() const;
345 
346  // Helper class for _ProcessEditsIfNeeded. Defined entirely in
347  // implementation. Declared here for private access to the editor
348  // structures.
349  class _EditProcessor;
350 
351  UsdStageRefPtr _stage;
352  // Dependent stage order should be arbitrary but we want don't want
353  // duplicates which can cause unnecessary work.
354  using _StageSet = std::unordered_set<UsdStageRefPtr, TfHash>;
355  _StageSet _dependentStages;
356  EditOptions _editOptions;
357  _EditDescription _editDescription;
358  mutable std::optional<_ProcessedEdit> _processedEdit;
359 };
360 
362 
363 #endif // PXR_USD_USD_NAMESPACE_EDITOR_H
364 
#define USD_API
Definition: api.h:23
GLbitfield stages
Definition: glcorearb.h:1931
USD_API void RemoveDependentStage(const UsdStageRefPtr &stage)
Removes the given stage as a dependent stage of this namespace editor.
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
class SdfListOp< class SdfPath > SdfPathListOp
Definition: listOp.h:372
USD_API void SetDependentStages(const UsdStageRefPtrVector &stages)
Definition: token.h:70
USD_API bool MovePrimAtPath(const SdfPath &path, const SdfPath &newPath)
USD_API bool CanApplyEdits(std::string *whyNot=nullptr) const
USD_API bool RenamePrim(const UsdPrim &prim, const TfToken &newName)
USD_API bool DeletePrim(const UsdPrim &prim)
USD_API bool RenameProperty(const UsdProperty &property, const TfToken &newName)
Definition: prim.h:116
Definition: path.h:273
USD_API bool DeletePropertyAtPath(const SdfPath &path)
USD_API bool MovePropertyAtPath(const SdfPath &path, const SdfPath &newPath)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
USD_API bool ReparentPrim(const UsdPrim &prim, const UsdPrim &newParent)
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
USD_API void AddDependentStage(const UsdStageRefPtr &stage)
Adds the given stage as a dependent stage of this namespace editor.
USD_API bool DeleteProperty(const UsdProperty &property)
USD_API UsdNamespaceEditor(const UsdStageRefPtr &stage)
USD_API bool ReparentProperty(const UsdProperty &property, const UsdPrim &newParent)
USD_API bool DeletePrimAtPath(const SdfPath &path)
USD_API bool ApplyEdits()