primDefinition.h
1 //
2 // Copyright 2020 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_USD_PRIM_DEFINITION_H
25 #define PXR_USD_USD_PRIM_DEFINITION_H
26 
27 #include "pxr/pxr.h"
28 #include "pxr/usd/usd/api.h"
29 #include "pxr/usd/usd/schemaRegistry.h"
30 
31 #include "pxr/usd/sdf/layer.h"
35 #include "pxr/base/tf/hash.h"
36 
37 #include <unordered_map>
38 
39 PXR_NAMESPACE_OPEN_SCOPE
40 
41 class UsdPrim;
42 
49 {
50 public:
51  ~UsdPrimDefinition() = default;
52 
54  const TfTokenVector &GetPropertyNames() const { return _properties; }
55 
59  return _appliedAPISchemas;
60  }
61 
65  SdfSpecType GetSpecType(const TfToken &propName) const
66  {
67  if (const _LayerAndPath *layerAndPath =
68  _GetPropertyLayerAndPath(propName)) {
69  return layerAndPath->GetSpecType();
70  }
71  return SdfSpecTypeUnknown;
72  }
73 
77  USD_API
78  SdfPropertySpecHandle GetSchemaPropertySpec(
79  const TfToken& propName) const;
80 
84  USD_API
85  SdfAttributeSpecHandle GetSchemaAttributeSpec(
86  const TfToken& attrName) const;
87 
91  USD_API
92  SdfRelationshipSpecHandle GetSchemaRelationshipSpec(
93  const TfToken& relName) const;
94 
100  template <class T>
101  bool GetAttributeFallbackValue(const TfToken &attrName, T *value) const
102  {
103  return _HasField(attrName, SdfFieldKeys->Default, value);
104  }
105 
109  {
110  return _ListMetadataFields(TfToken());
111  }
112 
119  template <class T>
120  bool GetMetadata(const TfToken &key, T* value) const
121  {
123  return false;
124  }
125  return _HasField(TfToken(), key, value);
126  }
127 
136  template <class T>
137  bool GetMetadataByDictKey(const TfToken &key,
138  const TfToken &keyPath, T* value) const
139  {
141  return false;
142  }
143  return _HasFieldDictKey(TfToken(), key, keyPath, value);
144  }
145 
148  USD_API
149  std::string GetDocumentation() const;
150 
155  {
156  return propName.IsEmpty() ?
157  TfTokenVector() : _ListMetadataFields(propName);
158  }
159 
166  template <class T>
168  const TfToken &propName, const TfToken &key, T* value) const
169  {
170  if (propName.IsEmpty() || UsdSchemaRegistry::IsDisallowedField(key)) {
171  return false;
172  }
173  return _HasField(propName, key, value);
174  }
175 
184  template <class T>
186  const TfToken &propName, const TfToken &key,
187  const TfToken &keyPath, T* value) const
188  {
189  if (propName.IsEmpty() || UsdSchemaRegistry::IsDisallowedField(key)) {
190  return false;
191  }
192  return _HasFieldDictKey(propName, key, keyPath, value);
193  }
194 
197  USD_API
198  std::string GetPropertyDocumentation(const TfToken &propName) const;
199 
223  USD_API
224  bool FlattenTo(const SdfLayerHandle &layer,
225  const SdfPath &path,
226  SdfSpecifier newSpecSpecifier = SdfSpecifierOver) const;
227 
232  USD_API
233  UsdPrim FlattenTo(const UsdPrim &parent,
234  const TfToken &name,
235  SdfSpecifier newSpecSpecifier = SdfSpecifierOver) const;
236 
240  USD_API
241  UsdPrim FlattenTo(const UsdPrim &prim,
242  SdfSpecifier newSpecSpecifier = SdfSpecifierOver) const;
243 
244 
245 private:
246  // Only the UsdSchemaRegistry can construct prim definitions.
247  friend class UsdSchemaRegistry;
248 
249  // Friended private accessor for use by UsdStage when composing metadata
250  // values for value resolution. The public GetMetadata functions perform
251  // the extra step of filtering out disallowed or private metadata fields
252  // from the SdfSpecs before retrieving metadata. Value resolution does not
253  // want to pay that extra cost so uses this function instead.
254  template <class T>
255  friend bool Usd_GetFallbackValue(const UsdPrimDefinition &primDef,
256  const TfToken &propName,
257  const TfToken &fieldName,
258  const TfToken &keyPath,
259  T *value)
260  {
261  // Try to read fallback value.
262  return keyPath.IsEmpty() ?
263  primDef._HasField(propName, fieldName, value) :
264  primDef._HasFieldDictKey(propName, fieldName, keyPath, value);
265  }
266 
267  // Prim definitions store property access via a pointer to the schematics
268  // layer and a path to the property spec on that layer.
269  struct _LayerAndPath {
270  // Note that we use a raw pointer to the layer (for efficiency) as only
271  // the schema registry can create a UsdPrimDefinition and is responsible
272  // for making sure any schematics layers are alive throughout the
273  // life-time of any UsdPrimDefinition it creates.
274  const SdfLayer *layer = nullptr;
275  SdfPath path;
276 
277  // Accessors for the common data we extract from the schematics, inline
278  // for efficiency during value resolution (with the exception of
279  // ListMetadataFields).
280  SdfSpecType GetSpecType() const {
281  return layer->GetSpecType(path);
282  }
283 
284  template <class T>
285  bool HasField(const TfToken& fieldName, T* value) const {
286  return layer->HasField(path, fieldName, value);
287  }
288 
289  template <class T>
290  bool HasFieldDictKey(
291  const TfToken& fieldName, const TfToken& keyPath, T* value) const {
292  return layer->HasFieldDictKey(path, fieldName, keyPath, value);
293  }
294 
295  USD_API
297  };
298 
302  template <class T>
303  bool _HasField(const TfToken& propName,
304  const TfToken& fieldName,
305  T* value) const
306  {
307  if (const _LayerAndPath *layerAndPath =
308  _GetPropertyLayerAndPath(propName)) {
309  return layerAndPath->HasField(fieldName, value);
310  }
311  return false;
312  }
313 
314  template <class T>
315  bool _HasFieldDictKey(const TfToken& propName,
316  const TfToken& fieldName,
317  const TfToken& keyPath,
318  T* value) const
319  {
320  if (const _LayerAndPath *layerAndPath =
321  _GetPropertyLayerAndPath(propName)) {
322  return layerAndPath->HasFieldDictKey(fieldName, keyPath, value);
323  }
324  return false;
325  }
326 
327  UsdPrimDefinition() = default;
328 
329  USD_API
330  void _IntializeForTypedSchema(
331  const SdfLayerHandle &schematicsLayer,
332  const SdfPath &schematicsPrimPath,
333  const VtTokenArray &propertiesToIgnore);
334 
335  USD_API
336  void _IntializeForAPISchema(
337  const TfToken &apiSchemaName,
338  const SdfLayerHandle &schematicsLayer,
339  const SdfPath &schematicsPrimPath,
340  const VtTokenArray &propertiesToIgnore);
341 
342  // Only used by the two _Initialize methods.
343  bool _MapSchematicsPropertyPaths(
344  const VtTokenArray &propertiesToIgnore);
345 
346  // Accessors for looking property spec paths by name.
347  const _LayerAndPath *_GetPropertyLayerAndPath(const TfToken& propName) const
348  {
349  return TfMapLookupPtr(_propLayerAndPathMap, propName);
350  }
351 
352  _LayerAndPath *_GetPropertyLayerAndPath(const TfToken& propName)
353  {
354  return TfMapLookupPtr(_propLayerAndPathMap, propName);
355  }
356 
357  USD_API
358  TfTokenVector _ListMetadataFields(const TfToken &propName) const;
359 
360  // Helpers for constructing the prim definition.
361  USD_API
362  void _ComposePropertiesFromPrimDef(
363  const UsdPrimDefinition &weakerPrimDef,
364  bool useWeakerPropertyForTypeConflict = false);
365 
366  USD_API
367  void _ComposePropertiesFromPrimDefInstance(
368  const UsdPrimDefinition &weakerPrimDef,
369  const std::string &instanceName);
370 
371  USD_API
372  void _ComposeOverAndReplaceExistingProperty(
373  const TfToken &propName,
374  const SdfLayerRefPtr &overLayer,
375  const SdfPath &overPrimPath);
376 
377  using _FamilyAndInstanceToVersionMap =
378  std::unordered_map<std::pair<TfToken, TfToken>, UsdSchemaVersion, TfHash>;
379 
380  USD_API
381  bool _ComposeWeakerAPIPrimDefinition(
382  const UsdPrimDefinition &apiPrimDef,
383  const TfToken &instanceName,
384  _FamilyAndInstanceToVersionMap *alreadyAppliedSchemaFamilyVersions,
385  bool allowDupes = false);
386 
387  USD_API
388  static bool _PropertyTypesMatch(
389  const _LayerAndPath &strongerProp,
390  const _LayerAndPath &weakerProp);
391 
392  // Path to the prim in the schematics for this prim definition.
393  _LayerAndPath _primLayerAndPath;
394 
395  // Map for caching the paths to each property spec in the schematics by
396  // property name.
397  using _PrimTypePropNameToPathMap =
398  std::unordered_map<TfToken, _LayerAndPath, TfToken::HashFunctor>;
399  _PrimTypePropNameToPathMap _propLayerAndPathMap;
400  TfTokenVector _appliedAPISchemas;
401 
402  // Cached list of property names.
403  TfTokenVector _properties;
404 };
405 
406 PXR_NAMESPACE_CLOSE_SCOPE
407 
408 #endif //PXR_USD_USD_PRIM_DEFINITION_H
A scene description container that can combine with other such containers to form simple component as...
Definition: layer.h:94
bool IsEmpty() const
Returns true iff this token contains the empty string "".
Definition: token.h:302
const TfTokenVector & GetPropertyNames() const
Return the list of names of builtin properties for this prim definition.
SdfSpecType GetSpecType(const TfToken &propName) const
Return the SdfSpecType for propName if it is a builtin property of the prim type represented by this ...
TfTokenVector ListPropertyMetadataFields(const TfToken &propName) const
Returns the list of names of metadata fields that are defined by this prim definition for property pr...
SDF_API bool HasFieldDictKey(const SdfPath &path, const TfToken &fieldName, const TfToken &keyPath, VtValue *value=NULL) const
Return whether a value exists for the given path and fieldName and keyPath.
bool GetPropertyMetadataByDictKey(const TfToken &propName, const TfToken &key, const TfToken &keyPath, T *value) const
Retrieves the value at keyPath from the fallback dictionary value for the dictionary metadata field n...
USD_API std::string GetPropertyDocumentation(const TfToken &propName) const
Returns the documentation metadata defined by the prim definition for the property named propName if ...
A user-extensible hashing mechanism for use with runtime hash tables.
Definition: hash.h:504
Token for efficient comparison, assignment, and hashing of known strings.
Definition: token.h:87
const TfTokenVector & GetAppliedAPISchemas() const
Return the list of names of the API schemas that have been applied to this prim definition in order.
USD_API std::string GetDocumentation() const
Returns the documentation metadata defined by the prim definition for the prim itself.
SDF_API bool HasField(const SdfPath &path, const TfToken &fieldName, VtValue *value=NULL) const
Return whether a value exists for the given path and fieldName.
USD_API bool FlattenTo(const SdfLayerHandle &layer, const SdfPath &path, SdfSpecifier newSpecSpecifier=SdfSpecifierOver) const
Copies the contents of this prim definition to a prim spec on the given layer at the given path.
bool GetPropertyMetadata(const TfToken &propName, const TfToken &key, T *value) const
Retrieves the fallback value for the metadata field named key, that is defined by this prim definitio...
UsdPrim is the sole persistent scenegraph object on a UsdStage, and is the embodiment of a "Prim" as ...
Definition: prim.h:135
SdfSpecifier
An enum that identifies the possible specifiers for an SdfPrimSpec.
Definition: types.h:123
std::vector< TfToken > TfTokenVector
Convenience types.
Definition: token.h:442
A path value used to locate objects in layers or scenegraphs.
Definition: path.h:290
USD_API SdfPropertySpecHandle GetSchemaPropertySpec(const TfToken &propName) const
Return the property spec that defines the fallback for the property named propName on prims of this p...
bool GetMetadataByDictKey(const TfToken &key, const TfToken &keyPath, T *value) const
Retrieves the value at keyPath from the fallback dictionary value for the dictionary metadata field n...
bool GetMetadata(const TfToken &key, T *value) const
Retrieves the fallback value for the metadata field named key, that is defined by this prim definitio...
static USD_API bool IsDisallowedField(const TfToken &fieldName)
Returns true if the field fieldName cannot have fallback values specified in schemas.
SdfSpecType
An enum that specifies the type of an object.
Definition: types.h:91
USD_API SdfRelationshipSpecHandle GetSchemaRelationshipSpec(const TfToken &relName) const
This is a convenience method.
Class representing the builtin definition of a prim given the schemas registered in the schema regist...
Container::mapped_type * TfMapLookupPtr(Container &map, Key const &key)
Checks if an item exists in a map or TfHashMap, without copying it.
Definition: stl.h:141
TfTokenVector ListMetadataFields() const
Returns the list of names of metadata fields that are defined by this prim definition for the prim it...
USD_API SdfAttributeSpecHandle GetSchemaAttributeSpec(const TfToken &attrName) const
This is a convenience method.
Singleton registry that provides access to schema type information and the prim definitions for regis...
SDF_API SdfSpecType GetSpecType(const SdfPath &path) const
Return the spec type for path.
bool GetAttributeFallbackValue(const TfToken &attrName, T *value) const
Retrieves the fallback value for the attribute named attrName and stores it in value if possible.