Skip to content

Commit

Permalink
usd: Revise UsdCollectionAPI documentation to explain what makes an i…
Browse files Browse the repository at this point in the history
…nstance be

in relationship-mode vs expression-mode, and how the built-in properties affect
membership determination in each mode.

(Internal change: 2330762)
  • Loading branch information
gitamohr authored and pixar-oss committed Jun 11, 2024
1 parent 2ada719 commit 9562005
Show file tree
Hide file tree
Showing 4 changed files with 362 additions and 241 deletions.
3 changes: 1 addition & 2 deletions pxr/usd/usd/apiSchemaBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ class SdfAssetPath;
/// explicit bool conversion operator. Examples of applied API schemas include
/// UsdCollectionAPI, UsdGeomModelAPI and UsdGeomMotionAPI
///
/// \anchor UsdAPISchemaBase_SingleVsMultipleApply
/// \name Single vs. Multiple Apply API Schemas
/// \subsection usd_apischemabase_single_vs_multiple_apply Single vs. Multiple Apply API Schemas
///
/// Applied API schemas can further be classified into single-apply and
/// multiple-apply API schemas. As the name suggests, a single-apply API schema
Expand Down
196 changes: 118 additions & 78 deletions pxr/usd/usd/collectionAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,95 +41,137 @@ class SdfAssetPath;

/// \class UsdCollectionAPI
///
/// This is a general purpose API schema, used to describe a
/// collection of heterogeneous objects within the scene. "Objects" here may be
/// prims or properties belonging to prims or other collections. It's an add-on
/// schema that can be applied many times to a prim with different collection
/// names.
/// A general purpose API schema used to describe a collection of prims
/// and properties within a scene. This API schema can be applied to a prim
/// multiple times with different instance names to define several collections
/// on a single prim.
///
/// A collection allows an enumeration of a set of paths to include and a
/// set of paths to exclude. Whether the descendants of an included
/// path are members of a collection are decided by its expansion rule
/// (see below). If the collection excludes paths that are not descendents
/// of included paths, the collection implicitly includes the root path
/// </>. If such a collection also includes paths that are not
/// descendants of the excluded paths, it is considered invalid, since
/// the intention is ambiguous.
/// A collection's membership is specified one of two ways. The first way uses
/// the built-in relationships `includes` and `excludes`, and the attribute
/// `includeRoot` to determine membership. The second way is termed a
/// pattern-based collection, and uses the built-in attribute
/// `membershipExpression` to determine membership. Here we will refer to
/// collections using `includes`, `excludes` and `includeRoot` as being in
/// *relationship-mode* and those using the `membershipExpression` as being in
/// *expression-mode*.
///
/// All the properties authored by the schema are namespaced under
/// "collection:". The given name of the collection provides additional
/// namespacing for the various per-collection properties, which include the
/// following:
/// A collection is determined to be in *relationship-mode* when either or both
/// of its `includes` and `excludes` relationships have valid targets, or the
/// `includeRoot` attribute is set `true`. In this case, the pattern-based
/// `membershipExpression` attribute is ignored. Otherwise, the collection is
/// in *expression-mode* and the `membershipExpression` attribute applies.
///
/// In *relationship-mode* the `includes` and `excludes` relationships specify
/// the collection members as a set of paths to include and a set of paths to
/// exclude. Whether or not the descendants of an included path belong to a
/// collection is decided by its expansion rule (see below). If the collection
/// excludes paths that are not descendent to included paths, the collection
/// implicitly includes the root path `</>`. If such a collection also
/// includes paths that are not descendent to the excluded paths, it is
/// considered invalid since the intent is ambiguous.
///
/// In *expression-mode*, the pattern-based `membershipExpression` attribute is
/// used with the `expansionRule` attribute to determine collection membership.
/// See the detailed descriptions of the built-in properties below for more
/// details.
///
/// \section usd_collectionapi_properties Collection API Properties
///
/// The built-in properties for this schema are in the `collection:instanceName`
/// namespace, where `instanceName` is the user-provided applied API schema
/// instance name.
///
/// <ul><li><b>uniform token collection:<i>collectionName</i>:expansionRule</b> -
/// specified how the paths that are included in the collection must be expanded
/// to determine its members. Possible values include:
/// <ul>
/// <li><b>explicitOnly</b> - only paths in the includes rel targets and not
/// in the excludes rel targets belong to the collection.
/// <li>`uniform token collection:instanceName:expansionRule` - in
/// *relationship-mode*, specifies how to expand the `includes` and `excludes`
/// relationship targets to determine the collection's members. In
/// *expression-mode*, specifies how matching scene objects against the
/// `membershipExpression` proceeds. Possible values include:
/// <ul>
/// <li>`expandPrims` - in *relationship-mode*, all the prims descendent
/// to the `includes` relationship targets (and not descendent to `excludes`
/// relationship targets) belong to the collection. Any `includes`-targeted
/// property paths also belong to the collection. This is the default
/// behavior. In *expression-mode*, the functions
/// UsdComputeIncludedObjectsFromCollection() and
/// UsdComputeIncludedPathsFromCollection() only test prims against the
/// `membershipExpression` to determine membership.
/// </li>
/// <li><b>expandPrims</b> - all the prims at or below the includes rel-
/// targets (and not under the excludes rel-targets) belong to the
/// collection. Any property paths included in the collection would, of
/// course, also be honored. This is the default behavior as it satisfies
/// most use cases.
/// <li>`expandPrimsAndProperties` - like `expandPrims`, but in
/// *relationship-mode*, all properties on all included prims also belong to
/// the collection. In *expression-mode*, the functions
/// UsdComputeIncludedObjectsFromCollection() and
/// UsdComputeIncludedPathsFromCollection() test both prims and
/// properties against the `membershipExpression` to determine membership.
/// </li>
/// <li><b>expandPrimsAndProperties</b> - like expandPrims, but also
/// includes all properties on all matched prims. We're still not quite
/// sure what the use cases are for this, but you can use it to capture a
/// whole lot of UsdObjects very concisely.
/// <li>`explicitOnly` - in *relationship-mode*, only paths in the
/// `includes` relationship targets and not those in the `excludes`
/// relationship targets belong to the collection. Does not apply to
/// *expression-mode*. If set in *expression-mode*, the functions
/// UsdComputeIncludedObjectsFromCollection() and
/// UsdComputeIncludedPathsFromCollection() return no results.
/// </li>
/// </ul>
/// </li>
/// <li><b>bool collection:<i>collectionName</i>:includeRoot</b> - boolean
/// attribute indicating whether the pseudo-root path &lt;/&gt; should
/// be counted as one of the included target paths. The fallback is false.
/// This separate attribute is required because relationships cannot
/// directly target the root. When expansionRule is explicitOnly, this
/// attribute is ignored.
/// <li><b>rel collection:<i>collectionName</i>:includes</b> - specifies a list
/// of targets that are included in the collection. This can target prims or
/// properties directly. A collection can insert the rules of another
/// collection by making its <i>includes</i> relationship target the
/// <b>collection:{collectionName}</b> property on the owning prim of the
/// collection to be included (see UsdCollectionAPI::GetCollectionAttr).
/// It is important to note that including another collection does not
/// guarantee the contents of that collection will be in the final collection;
/// instead, the rules are merged. This means, for example, an exclude
/// entry may exclude a portion of the included collection.
/// When a collection includes one or more collections, the order in which
/// targets are added to the includes relationship may become significant, if
/// there are conflicting opinions about the same path. Targets that are added
/// later are considered to be stronger than earlier targets for the same path.
/// </li>
/// <li><b>rel collection:<i>collectionName</i>:excludes</b> - specifies a list
/// of targets that are excluded below the <b>included</b> paths in this
/// collection. This can target prims or properties directly, but <b>cannot
/// target another collection</b>. This is to keep the membership determining
/// logic simple, efficient and easier to reason about. Finally, it is invalid
/// for a collection to exclude paths that are not included in it. The presence
/// of such "orphaned" excluded paths will not affect the set of paths included
/// in the collection, but may affect the performance of querying membership of
/// a path in the collection (see UsdCollectionAPI::MembershipQuery::IsPathIncluded)
/// or of enumerating the objects belonging to the collection (see
/// UsdCollectionAPI::GetIncludedObjects).
/// </li>
/// <li><b>uniform opaque collection:<i>collectionName</i></b> - opaque
///
/// <li>`bool collection:instanceName:includeRoot` - boolean attribute
/// indicating whether the pseudo-root path `</>` should be counted as one
/// of the included target paths in *relationship-mode*. This separate attribute
/// is required because relationships cannot directly target the root. When
/// `expansionRule` is `explicitOnly`, this attribute is ignored. The fallback
/// value is false. When set to `true`, this collection is in
/// *relationship-mode*. This attribute is ignored in *expression-mode*. </li>
///
/// <li>`rel collection:instanceName:includes` - in *relationship-mode*,
/// specifies a list of targets that are included in the collection. This can
/// target prims or properties directly. A collection can insert the rules of
/// another collection by making its `includes` relationship target the
/// `collection:otherInstanceName` property from the collection to be included
/// (see UsdCollectionAPI::GetCollectionAttr). Note that including another
/// collection does not guarantee the contents of that collection will be in the
/// final collection; instead, the rules are merged. This means, for example,
/// an exclude entry may exclude a portion of the included collection. When a
/// collection includes one or more collections, the order in which targets are
/// added to the includes relationship may become significant, if there are
/// conflicting opinions about the same path. Targets that are added later are
/// considered to be stronger than earlier targets for the same path. This
/// relationship is ignored in *expression-mode*.</li>
///
/// <li>`rel collection:instanceName:excludes` - in *relationship-mode*,
/// specifies a list of targets that are excluded below the <b>included</b>
/// paths in this collection. This can target prims or properties directly, but
/// <b>cannot target another collection</b>. This is to keep the membership
/// determining logic simple, efficient and easier to reason about. Finally, it
/// is invalid for a collection to exclude paths that are not included in
/// it. The presence of such "orphaned" excluded paths will not affect the set
/// of paths included in the collection, but may affect the performance of
/// querying membership of a path in the collection (see
/// UsdCollectionMembershipQuery::IsPathIncluded) or of enumerating the
/// objects belonging to the collection (see
/// UsdCollectionAPI::ComputeIncludedObjects). This relationship is ignored in
/// *expression-mode*.</li>
///
/// <li>`uniform opaque collection:instanceName` - opaque
/// attribute (meaning it can never have a value) that represents the collection
/// for the purpose of allowing another collection to include it. When this
/// property is targeted by another collection's <i>includes</i> relationship,
/// the rules of this collection will be inserted into the rules of the collection
/// that includes it.
/// </li></ul>
/// for the purpose of allowing another collection to include it in
/// *relationship-mode*. When this property is targeted by another collection's
/// `includes` relationship, the rules of this collection will be inserted
/// into the rules of the collection that includes it.</li>
///
/// <li>`uniform pathExpression collection:instanceName:membershipExpression` -
/// in *expression-mode*, defines the SdfPathExpression used to test
/// objects for collection membership.</li>
///
/// <b>Implicit inclusion</b>
/// </ul>
///
/// \subsection usd_collectionapi_implicit_inclusion Implicit Inclusion
///
/// In some scenarios it is useful to express a collection that includes
/// everything except certain paths. To support this, a collection
/// that has an exclude that is not a descendent of any include
/// will include the root path &lt;/&gt;.
/// everything except certain paths. To support this, a *relationship-mode*
/// collection that has an exclude that is not descendent to any include will
/// include the root path `</>`.
///
/// <b>Creating collections in C++</b>
/// \section usd_collectionapi_creating_cpp Creating Collections in C++
///
/// \snippet examples_usd.cpp ApplyCollections
///
Expand Down Expand Up @@ -331,7 +373,7 @@ class UsdCollectionAPI : public UsdAPISchemaBase
// INCLUDEROOT
// --------------------------------------------------------------------- //
/// Boolean attribute indicating whether the pseudo-root
/// path &lt;/&gt; should be counted as one of the included target
/// path `</>` should be counted as one of the included target
/// paths. The fallback is false. This separate attribute is
/// required because relationships cannot directly target the root.
///
Expand Down Expand Up @@ -556,8 +598,6 @@ class UsdCollectionAPI : public UsdAPISchemaBase
const UsdStageWeakPtr &stage,
const Usd_PrimFlagsPredicate &pred=UsdPrimDefaultPredicate);

/// @}

/// \anchor UsdCollectionAPI_AuthoringAPI
/// \name Collection Authoring API
///
Expand Down
Loading

0 comments on commit 9562005

Please sign in to comment.