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  // Structure returned by CanApplyEdits that stores errors and warnings
42  // encountered while processing the edits. This struct evaluates to false
43  // if any errors were found, and true otherwise (even if there are warnings).
45  {
46  std::vector<std::string> errors;
47  std::vector<std::string> warnings;
48 
49  operator bool() const
50  {
51  return errors.empty();
52  }
53  };
54 
55  USD_API
56  explicit UsdNamespaceEditor(const UsdStageRefPtr &stage);
57 
58  USD_API
60  const UsdStageRefPtr &stage,
61  EditOptions &&editOptions);
62 
63  USD_API
65  const UsdStageRefPtr &stage,
66  const EditOptions &editOptions);
67 
68  /// \name Dependent Stages
69  ///
70  /// Dependent stages are additional stages that may have composition
71  /// dependencies on the layer edits made for the editor's primary stage.
72  /// By adding dependent stages, the editor can make additional edits so that
73  /// affected composition arcs and specs that depend on affected composition
74  /// in composed prims on these stages are updated to compose with the moved
75  /// prim specs or, in the case of deletions, removed when the specs they
76  /// depend on are removed.
77  ///
78  /// Dependencies in the dependent stages are based only what is currently
79  /// loaded for those stages. In other words, the editor cannot find and
80  /// edit dependencies from unloaded payloads, inactive prim children,
81  /// prims that are load mask filtered, unselected variants, etc. The primary
82  /// stage of this editor is always a dependent stage, meaning that edits
83  /// will always be made to maintain affected composition dependencies in the
84  /// primary stage.
85  ///
86  /// @{
87 
88  /// Adds the given \p stage as a dependent stage of this namespace editor.
89  USD_API
90  void AddDependentStage(const UsdStageRefPtr &stage);
91 
92  /// Removes the given \p stage as a dependent stage of this namespace editor.
93  USD_API
94  void RemoveDependentStage(const UsdStageRefPtr &stage);
95 
96  /// Sets the list of dependent stages for this namespace editor to
97  /// \p stages.
98  USD_API
99  void SetDependentStages(const UsdStageRefPtrVector &stages);
100 
101  /// @}
102 
103  /// Adds an edit operation to delete the composed prim at the given \p path
104  /// from this namespace editor's stage.
105  ///
106  /// Returns true if the path is a valid possible composed prim path; returns
107  /// false and emits a coding error if not.
108  USD_API
109  bool DeletePrimAtPath(
110  const SdfPath &path);
111 
112  /// Adds an edit operation to move the composed prim at the given \p path
113  /// on this namespace editor's stage to instead be at the path \p newPath.
114  ///
115  /// Returns true if both paths are valid possible composed prim path;
116  /// returns false and emits a coding error if not.
117  USD_API
118  bool MovePrimAtPath(
119  const SdfPath &path,
120  const SdfPath &newPath);
121 
122  /// Adds an edit operation to delete the composed prim at the path of
123  /// \p prim from this namespace editor's stage. This is equivalent to
124  /// calling DeletePrimAtPath(prim.GetPath())
125  ///
126  /// Returns true if the prim provides a valid possible composed prim path;
127  /// returns false and emits a coding error if not.
128  USD_API
129  bool DeletePrim(
130  const UsdPrim &prim);
131 
132  /// Adds an edit operation to rename the composed prim at the path of
133  /// \p prim on this namespace editor's stage to instead have the name
134  /// \p newName.
135  ///
136  /// Returns true if the prim provides a valid possible composed prim path
137  /// and the new name is a valid possible prim name; returns false and emits
138  /// a coding error if not.
139  USD_API
140  bool RenamePrim(
141  const UsdPrim &prim,
142  const TfToken &newName);
143 
144  /// Adds an edit operation to reparent the composed prim at the path of
145  /// \p prim on this namespace editor's stage to instead be a namespace
146  /// child of the composed prim at the path of \p newParent.
147  ///
148  /// Returns true if the both the prim and the new parent prim provide a
149  /// valid possible composed prim paths; returns false and emits a coding
150  /// error if not.
151  USD_API
152  bool ReparentPrim(
153  const UsdPrim &prim,
154  const UsdPrim &newParent);
155 
156  /// Adds an edit operation to reparent the composed prim at the path of
157  /// \p prim on this namespace editor's stage to instead be a prim named
158  /// \p newName that is a namespace child of the composed prim at the
159  /// path of \p newParent.
160  ///
161  /// Returns true if the both the prim and the new parent prim provide a
162  /// valid possible composed prim paths and the new name is a valid prim
163  /// name; returns false and emits a coding error if not.
164  USD_API
165  bool ReparentPrim(
166  const UsdPrim &prim,
167  const UsdPrim &newParent,
168  const TfToken &newName);
169 
170  /// Adds an edit operation to delete the composed property at the given
171  /// \p path from this namespace editor's stage.
172  ///
173  /// Returns true if the path is a valid possible composed property path;
174  /// returns false and emits a coding error if not.
175  USD_API
177  const SdfPath &path);
178 
179  /// Adds an edit operation to move the composed property at the given
180  /// \p path on this namespace editor's stage to instead be at the path
181  /// \p newPath.
182  ///
183  /// Returns true if both paths are valid possible composed property path;
184  /// returns false and emits a coding error if not.
185  USD_API
186  bool MovePropertyAtPath(
187  const SdfPath &path,
188  const SdfPath &newPath);
189 
190  /// Adds an edit operation to delete the composed property at the path of
191  /// \p property from this namespace editor's stage. This is equivalent to
192  /// calling DeletePropertyAtPath(property.GetPath())
193  ///
194  /// Returns true if the property provides a valid possible composed property
195  /// path; returns false and emits a coding error if not.
196  USD_API
197  bool DeleteProperty(
198  const UsdProperty &property);
199 
200  /// Adds an edit operation to rename the composed property at the path of
201  /// \p property on this namespace editor's stage to instead have the name
202  /// \p newName.
203  ///
204  /// Returns true if the property provides a valid possible composed property
205  /// path and the new name is a valid possible property name; returns false
206  /// and emits a coding error if not.
207  USD_API
208  bool RenameProperty(
209  const UsdProperty &property,
210  const TfToken &newName);
211 
212  /// Adds an edit operation to reparent the composed property at the path of
213  /// \p property on this namespace editor's stage to instead be a namespace
214  /// child of the composed property at the path of \p newParent.
215  ///
216  /// Returns true if the both the property and the new parent prim provide a
217  /// valid possible composed paths; returns false and emits a coding
218  /// error if not.
219  USD_API
220  bool ReparentProperty(
221  const UsdProperty &property,
222  const UsdPrim &newParent);
223 
224  /// Adds an edit operation to reparent the composed property at the path of
225  /// \p property on this namespace editor's stage to instead be a property
226  /// named \p newName that is a namespace child of the composed prim at the
227  /// path of \p newParent.
228  ///
229  /// Returns true if the both the property and the new parent prim provide a
230  /// valid possible composed paths and the new name is a valid property
231  /// name; returns false and emits a coding error if not.
232  USD_API
233  bool ReparentProperty(
234  const UsdProperty &property,
235  const UsdPrim &newParent,
236  const TfToken &newName);
237 
238  /// Applies all the added namespace edits stored in this to namespace editor
239  /// to its stage by authoring all scene description in the layer stack of
240  /// the current edit target necessary to move or delete the composed
241  /// objects that the edit paths refer to..
242  ///
243  /// Returns true if all the necessary edits are successfully performed;
244  /// returns false and emits a coding error otherwise.
245  USD_API
246  bool ApplyEdits();
247 
248  /// \deprecated Use CanApplyEdits() overload below.
249  /// Returns whether all the added namespace edits stored in this to
250  /// namespace editor can be applied to its stage.
251  ///
252  /// In other words, this returns whether ApplyEdits should be successful if
253  /// it were called right now. If this would return false and \p whyNot is
254  /// provided, the reasons ApplyEdits would fail will be copied to whyNot.
255  USD_API
256  bool CanApplyEdits(std::string *whyNot) const;
257 
258  /// Returns whether all the added namespace edits stored in this to
259  /// namespace editor can be applied to its stage.
260  ///
261  /// In other words, this returns whether ApplyEdits should be successful if
262  /// it were called right now. If that call would return false, the reasons
263  /// ApplyEdits would fail will be copied to the return struct's errors field.
264  /// If the call would return true, but the edit might create a result
265  /// that is confusing to the user due to split opinions, the return struct's
266  /// warnings field will contain information about the sources of confusion.
267  USD_API
268  CanApplyResult CanApplyEdits() const;
269 
270  /// Returns the list of layers that will be edited if ApplyEdits() is called.
271  /// This function can only be called if CanApplyEdits() returns true and
272  /// will throw a coding error if not.
273  USD_API
274  SdfLayerHandleVector GetLayersToEdit();
275 
276 private:
277 
278  // The type of edit that an edit description is describing.
279  enum class _EditType {
280  Invalid,
281 
282  Delete,
283  Rename,
284  Reparent
285  };
286 
287  // Description of an edit added to this namespace editor.
288  struct _EditDescription {
289  // Path to the existing object.
290  SdfPath oldPath;
291  // New path of the object after the edit is performed. An empty path
292  // indicates that the edit operation will delete the object.
293  SdfPath newPath;
294 
295  // Type of the edit as determined by the oldPath and the newPath.
296  _EditType editType = _EditType::Invalid;
297 
298  // Whether this describes a property edit or, otherwise, a prim edit.
299  bool IsPropertyEdit() const { return oldPath.IsPrimPropertyPath(); }
300  };
301 
302  // Struct representing the Sdf layer edits necessary to apply an edit
303  // description to the stage. We need this to gather all the information we
304  // can about what layer edits need to be performed before we start editing
305  // any specs so that we can avoid partial edits when a composed stage level
306  // namespace would fail.
307  struct _ProcessedEdit
308  {
309  // List of errors encountered that would prevent the overall namespace
310  // edit of the composed stage object from being completed successfully.
311  std::vector<std::string> errors;
312 
313  // List of warnings encountered that will not prevent the main edit from
314  // being completed but indicate that some supporting operations may not
315  // have been performed.
316  std::vector<std::string> warnings;
317 
318  // The edit description of the primary edit.
319  _EditDescription editDescription;
320 
321  // The list of layers that have specs that need to have the Sdf
322  // namespace edit applied.
323  SdfLayerHandleVector layersToEdit;
324 
325  // Whether performing the edit will author new relocates.
326  bool willAuthorRelocates = false;
327 
328  // Layer edits that need to be performed to update connection and
329  // relationship targets of other properties in order to keep them
330  // targeting the same object after applying this processed edit.
332  // Property spec to author the new targets value to. Note that we
333  // store the spec handle for the property as the property spec's
334  // path could change if the property is moved or deleted by the
335  // primary namespace edit.
336  SdfPropertySpecHandle propertySpec;
337 
338  // Name of the field that holds the path targets for the property
339  // which differs for attributes vs relationships.
341 
342  // Updated list op value to set for the property spec.
344  };
345  std::vector<TargetPathListOpEdit> targetPathListOpEdits;
346 
347  // Full set of namespace edits that need to be performed for all the
348  // dependent stages of this editor as a result of dependencies on the
349  // initial spec move edits.
350  PcpDependentNamespaceEdits dependentStageNamespaceEdits;
351 
352  // Applies this processed edit, performing the individual edits
353  // necessary to each layer that needs to be updated.
354  bool Apply();
355 
356  // Returns whether this processed edit can be applied and any errors
357  // or warnings that it would produce.
358  UsdNamespaceEditor::CanApplyResult CanApply() const;
359  };
360 
361  // Adds an edit description for a prim delete operation.
362  bool _AddPrimDelete(const SdfPath &oldPath);
363 
364  // Adds an edit description for a prim rename or reparent operation.
365  bool _AddPrimMove(const SdfPath &oldPath, const SdfPath &newPath);
366 
367  // Adds an edit description for a property delete operation.
368  bool _AddPropertyDelete(const SdfPath &oldPath);
369 
370  // Adds an edit description for a property rename or reparent operation.
371  bool _AddPropertyMove(const SdfPath &oldPath, const SdfPath &newPath);
372 
373  // Clears the current procesed edits.
374  void _ClearProcessedEdits();
375 
376  // Processes and caches the layer edits necessary for the current edit
377  // operation if there is no cached processecd edit.
378  void _ProcessEditsIfNeeded() const;
379 
380  // Helper class for _ProcessEditsIfNeeded. Defined entirely in
381  // implementation. Declared here for private access to the editor
382  // structures.
383  class _EditProcessor;
384 
385  UsdStageRefPtr _stage;
386  // Dependent stage order should be arbitrary but we want don't want
387  // duplicates which can cause unnecessary work.
388  using _StageSet = std::unordered_set<UsdStageRefPtr, TfHash>;
389  _StageSet _dependentStages;
390  EditOptions _editOptions;
391  _EditDescription _editDescription;
392  mutable std::optional<_ProcessedEdit> _processedEdit;
393 };
394 
396 
397 #endif // PXR_USD_USD_NAMESPACE_EDITOR_H
398 
#define USD_API
Definition: api.h:23
GLbitfield stages
Definition: glcorearb.h:1931
#define PXR_NAMESPACE_OPEN_SCOPE
Definition: pxr.h:73
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
USD_API SdfLayerHandleVector GetLayersToEdit()
OutGridT const XformOp bool bool
class SdfListOp< class SdfPath > SdfPathListOp
Definition: listOp.h:377
USD_API void SetDependentStages(const UsdStageRefPtrVector &stages)
Definition: token.h:70
USD_API bool MovePrimAtPath(const SdfPath &path, const SdfPath &newPath)
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)
USD_API CanApplyResult CanApplyEdits() const
Definition: prim.h:116
Definition: path.h:280
USD_API bool DeletePropertyAtPath(const SdfPath &path)
std::vector< std::string > warnings
USD_API bool MovePropertyAtPath(const SdfPath &path, const SdfPath &newPath)
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)
std::vector< std::string > errors
USD_API bool ReparentProperty(const UsdProperty &property, const UsdPrim &newParent)
USD_API bool DeletePrimAtPath(const SdfPath &path)
USD_API bool ApplyEdits()