HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
copyUtils.h
Go to the documentation of this file.
1 //
2 // Copyright 2017 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_SDF_COPY_UTILS_H
8 #define PXR_USD_SDF_COPY_UTILS_H
9 
10 /// \file sdf/copyUtils.h
11 
12 #include "pxr/pxr.h"
13 #include "pxr/usd/sdf/api.h"
14 
16 #include "pxr/usd/sdf/types.h"
17 
18 #include <functional>
19 #include <optional>
20 
22 
23 class SdfPath;
24 class TfToken;
25 class VtValue;
27 
28 /// \name Simple Spec Copying API
29 /// @{
30 
31 /// Utility function for copying spec data at \p srcPath in \p srcLayer to
32 /// \p destPath in \p destLayer.
33 ///
34 /// Copying is performed recursively: all child specs are copied as well.
35 /// Any destination specs that already exist will be overwritten.
36 ///
37 /// Parent specs of the destination are not created, and must exist before
38 /// SdfCopySpec is called, or a coding error will result. For prim parents,
39 /// clients may find it convenient to call SdfCreatePrimInLayer before
40 /// SdfCopySpec.
41 ///
42 /// As a special case, if the top-level object to be copied is a relationship
43 /// target or a connection, the destination spec must already exist. That is
44 /// because we don't want SdfCopySpec to impose any policy on how list edits are
45 /// made; client code should arrange for relationship targets and connections to
46 /// be specified as prepended, appended, deleted, and/or ordered, as needed.
47 ///
48 /// Variant specs may be copied to prim paths and vice versa. When copying a
49 /// variant to a prim, the specifier and typename from the variant's parent
50 /// prim will be used.
51 ///
52 /// Attribute connections, relationship targets, inherit and specializes paths,
53 /// and internal sub-root references that target an object beneath \p srcPath
54 /// will be remapped to target objects beneath \p dstPath.
55 ///
56 /// If \p srcLayer and \p dstLayer are the same, and either \p srcPath or \p
57 /// dstPath is a prefix of the other (see SdfPath::HasPrefix()), then the source
58 /// and destination overlap. In this case, to avoid modifying the source during
59 /// the copy operation, SdfCopySpec() first creates a temporary anonymous layer
60 /// and copies the source to it. Then it copies that temporary to the
61 /// destination.
62 SDF_API
63 bool
65  const SdfLayerHandle& srcLayer, const SdfPath& srcPath,
66  const SdfLayerHandle& dstLayer, const SdfPath& dstPath);
67 
68 /// @}
69 
70 /// \name Advanced Spec Copying API
71 /// @{
72 
73 /// Return true if \p field should be copied from the spec at \p srcPath in
74 /// \p srcLayer to the spec at \p dstPath in \p dstLayer. \p fieldInSrc and
75 /// \p fieldInDst indicates whether the field has values at the source and
76 /// destination specs. Return false otherwise.
77 ///
78 /// This function may modify the value that is copied by filling in
79 /// \p valueToCopy with the desired value. \p valueToCopy may also be a
80 /// SdfCopySpecsValueEdit that specifies an editing operation for this field.
81 /// If \p valueToCopy is not set, the field value from the source spec will be
82 /// used as-is. Setting \p valueToCopy to an empty VtValue indicates that the
83 /// field should be removed from the destination spec, if it already exists.
84 ///
85 /// Note that if this function returns true and the source spec has no value
86 /// for \p field (e.g., fieldInSrc == false), the field in the destination
87 /// spec will also be set to no value.
88 using SdfShouldCopyValueFn = std::function<
89  bool(SdfSpecType specType, const TfToken& field,
90  const SdfLayerHandle& srcLayer, const SdfPath& srcPath, bool fieldInSrc,
91  const SdfLayerHandle& dstLayer, const SdfPath& dstPath, bool fieldInDst,
92  std::optional<VtValue>* valueToCopy)>;
93 
94 /// \class SdfCopySpecsValueEdit
95 /// Value containing an editing operation for SdfCopySpecs.
96 ///
97 /// The SdfShouldCopyValueFn callback allows users to return a value to copy
98 /// into the destination spec via the \p valueToCopy parameter. However, there
99 /// may be cases where it would be more efficient to perform incremental edits
100 /// using specific SdfLayer API instead.
101 ///
102 /// To accommodate this, consumers may provide a callback that applies a
103 /// scene description edit in \p valueToCopy via an SdfCopySpecsValueEdit
104 /// object.
106 {
107 public:
108  /// Callback to apply a scene description edit to the specified layer and
109  /// spec path.
110  using EditFunction =
111  std::function<void(const SdfLayerHandle&, const SdfPath&)>;
112 
113  explicit SdfCopySpecsValueEdit(const EditFunction& edit) : _edit(edit) { }
114  const EditFunction& GetEditFunction() const { return _edit; }
115 
116  /// SdfCopySpecsValueEdit objects are not comparable, but must provide
117  /// operator== to be stored in a VtValue.
118  bool operator==(const SdfCopySpecsValueEdit& rhs) const { return false; }
119  bool operator!=(const SdfCopySpecsValueEdit& rhs) const { return true; }
120 
121 private:
122  EditFunction _edit;
123 };
124 
125 /// Return true if \p childrenField and the child objects the field represents
126 /// should be copied from the spec at \p srcPath in \p srcLayer to the spec at
127 /// \p dstPath in \p dstLayer. \p fieldInSrc and \p fieldInDst indicates
128 /// whether that field has values at the source and destination specs.
129 /// Return false otherwise.
130 ///
131 /// This function may modify which children are copied by filling in
132 /// \p srcChildren and \p dstChildren with the children to copy and their
133 /// destination. Both of these values must be set, and must contain the same
134 /// number of children.
135 ///
136 /// Note that if this function returns true and the source spec has no value
137 /// for \p childrenField (e.g., fieldInSrc == false), the field in the
138 /// destination spec will also be set to no value, causing any existing children
139 /// to be removed.
140 using SdfShouldCopyChildrenFn = std::function<
141  bool(const TfToken& childrenField,
142  const SdfLayerHandle& srcLayer, const SdfPath& srcPath, bool fieldInSrc,
143  const SdfLayerHandle& dstLayer, const SdfPath& dstPath, bool fieldInDst,
144  std::optional<VtValue>* srcChildren,
145  std::optional<VtValue>* dstChildren)>;
146 
147 /// SdfShouldCopyValueFn used by the simple version of SdfCopySpec.
148 ///
149 /// Copies all values from the source, transforming path-valued fields prefixed
150 /// with \p srcRootPath to have the prefix \p dstRootPath.
151 ///
152 /// Existing values in the destination will be overwritten by values in the
153 /// source. Any fields in the destination that aren't in the source will be
154 /// cleared.
155 SDF_API
156 bool
158  const SdfPath& srcRootPath, const SdfPath& dstRootPath,
159  SdfSpecType specType, const TfToken& field,
160  const SdfLayerHandle& srcLayer, const SdfPath& srcPath, bool fieldInSrc,
161  const SdfLayerHandle& dstLayer, const SdfPath& dstPath, bool fieldInDst,
162  std::optional<VtValue>* valueToCopy);
163 
164 /// SdfShouldCopyChildrenFn used by the simple version of SdfCopySpec.
165 ///
166 /// Copies all child values from the source, transforming path-valued fields
167 /// prefixed with \p srcRootPath to have the prefix \p dstRootPath.
168 ///
169 /// Existing values in the destination will be overwritten by values in the
170 /// source. Any fields in the destination that aren't in the source will be
171 /// cleared.
172 SDF_API
173 bool
175  const SdfPath& srcRootPath, const SdfPath& dstRootPath,
176  const TfToken& childrenField,
177  const SdfLayerHandle& srcLayer, const SdfPath& srcPath, bool fieldInSrc,
178  const SdfLayerHandle& dstLayer, const SdfPath& dstPath, bool fieldInDst,
179  std::optional<VtValue>* srcChildren,
180  std::optional<VtValue>* dstChildren);
181 
182 /// Utility function for copying spec data at \p srcPath in \p srcLayer to
183 /// \p destPath in \p destLayer. Various behaviors (such as which parts of the
184 /// spec to copy) are controlled by the supplied \p shouldCopyValueFn and
185 /// \p shouldCopyChildrenFn.
186 ///
187 /// Copying is performed recursively: all child specs are copied as well, except
188 /// where prevented by \p shouldCopyChildrenFn.
189 ///
190 /// Parent specs of the destination are not created, and must exist before
191 /// SdfCopySpec is called, or a coding error will result. For prim parents,
192 /// clients may find it convenient to call SdfCreatePrimInLayer before
193 /// SdfCopySpec.
194 ///
195 /// Variant specs may be copied to prim paths and vice versa. When copying a
196 /// variant to a prim, the specifier and typename from the variant's parent
197 /// prim will be used.
198 ///
199 /// As a special case, if the top-level object to be copied is a relationship
200 /// target or a connection, the destination spec must already exist. That is
201 /// because we don't want SdfCopySpec to impose any policy on how list edits are
202 /// made; client code should arrange for relationship targets and connections to
203 /// be specified as prepended, appended, deleted, and/or ordered, as needed.
204 ///
205 /// If \p srcLayer and \p dstLayer are the same, and either \p srcPath or \p
206 /// dstPath is a prefix of the other (see SdfPath::HasPrefix()), then the source
207 /// and destination overlap. In this case, to avoid modifying the source during
208 /// the copy operation, SdfCopySpec() first creates a temporary anonymous layer
209 /// and copies the source to it using the SdfCopySpec() overload that does not
210 /// take "shouldCopy" functions. Then it copies that temporary to the
211 /// destination. In this case the \p shouldCopyValueFn and \p
212 /// shouldCopyChildrenFn will be called with the temporary source layer rather
213 /// than the original source layer, but the source paths will be the same.
214 SDF_API
215 bool
217  const SdfLayerHandle& srcLayer, const SdfPath& srcPath,
218  const SdfLayerHandle& dstLayer, const SdfPath& dstPath,
219  const SdfShouldCopyValueFn& shouldCopyValueFn,
220  const SdfShouldCopyChildrenFn& shouldCopyChildrenFn);
221 
222 /// @}
223 
225 
226 #endif // PXR_USD_SDF_COPY_UTILS_H
Definition: layer.h:81
std::function< void(const SdfLayerHandle &, const SdfPath &)> EditFunction
Definition: copyUtils.h:111
OutGridT const XformOp bool bool
Definition: token.h:70
SDF_API bool SdfShouldCopyChildren(const SdfPath &srcRootPath, const SdfPath &dstRootPath, const TfToken &childrenField, const SdfLayerHandle &srcLayer, const SdfPath &srcPath, bool fieldInSrc, const SdfLayerHandle &dstLayer, const SdfPath &dstPath, bool fieldInDst, std::optional< VtValue > *srcChildren, std::optional< VtValue > *dstChildren)
bool operator==(const SdfCopySpecsValueEdit &rhs) const
Definition: copyUtils.h:118
bool operator!=(const SdfCopySpecsValueEdit &rhs) const
Definition: copyUtils.h:119
Definition: path.h:273
SDF_API bool SdfShouldCopyValue(const SdfPath &srcRootPath, const SdfPath &dstRootPath, SdfSpecType specType, const TfToken &field, const SdfLayerHandle &srcLayer, const SdfPath &srcPath, bool fieldInSrc, const SdfLayerHandle &dstLayer, const SdfPath &dstPath, bool fieldInDst, std::optional< VtValue > *valueToCopy)
const EditFunction & GetEditFunction() const
Definition: copyUtils.h:114
SdfCopySpecsValueEdit(const EditFunction &edit)
Definition: copyUtils.h:113
#define SDF_API
Definition: api.h:23
std::function< bool(SdfSpecType specType, const TfToken &field, const SdfLayerHandle &srcLayer, const SdfPath &srcPath, bool fieldInSrc, const SdfLayerHandle &dstLayer, const SdfPath &dstPath, bool fieldInDst, std::optional< VtValue > *valueToCopy)> SdfShouldCopyValueFn
Definition: copyUtils.h:92
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
SdfSpecType
Definition: types.h:68
SDF_API bool SdfCopySpec(const SdfLayerHandle &srcLayer, const SdfPath &srcPath, const SdfLayerHandle &dstLayer, const SdfPath &dstPath)
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
std::function< bool(const TfToken &childrenField, const SdfLayerHandle &srcLayer, const SdfPath &srcPath, bool fieldInSrc, const SdfLayerHandle &dstLayer, const SdfPath &dstPath, bool fieldInDst, std::optional< VtValue > *srcChildren, std::optional< VtValue > *dstChildren)> SdfShouldCopyChildrenFn
Definition: copyUtils.h:145
SDF_DECLARE_HANDLES(SdfLayer)
Definition: value.h:146