#usda 1.0
(
    "This file describes the USD primitive schemata and drives code generation."
)

def "GLOBAL" (
    customData = {
        string libraryName      = "usd"
        string libraryPath      = "pxr/usd/usd"
        # string libraryPrefix  = "Usd"
        # string tokensPrefix   = "Usd"
        dictionary libraryTokens = {
            dictionary apiSchemas = {
                string doc = """
                A listop metadata containing the API schemas which have
                been applied to this prim, using the Apply() method on
                the particular schema class. 
                """
            }
        }
    }
)
{
}

class "Typed" 
(
    doc = """The base class for all \\em typed schemas (those that can impart a
    typeName to a UsdPrim), and therefore the base class for all
    concrete, instantiable "IsA" schemas.
       
    UsdTyped implements a typeName-based query for its override of
    UsdSchemaBase::_IsCompatible().  It provides no other behavior."""
)
{
}

class "APISchemaBase"
(
    doc = """The base class for all \\em API schemas.

    An API schema provides an interface to a prim's qualities, but does not
    specify a typeName for the underlying prim. The prim's qualities include 
    its inheritance structure, attributes, relationships etc. Since it cannot
    provide a typeName, an API schema is considered to be non-concrete. 
    
    To auto-generate an API schema using usdGenSchema, simply leave the 
    typeName empty and make it inherit from "/APISchemaBase" or from another 
    API schema. See UsdModelAPI, UsdClipsAPI and UsdCollectionAPI for examples.
    
    API schemas are classified into applied and non-applied API schemas. 
    The author of an API schema has to decide on the type of API schema 
    at the time of its creation by setting customData['apiSchemaType'] in the 
    schema definition (i.e. in  the associated primSpec inside the schema.usda 
    file).  UsdAPISchemaBase implements methods that are used to record the 
    application of an API schema on a USD prim.

    If an API schema only provides an interface to set certain core bits of 
    metadata (like UsdModelAPI, which sets model kind and UsdClipsAPI, which 
    sets clips-related metadata) OR if the API schema can apply to any type of 
    prim or only to a known fixed set of prim types OR if there is no use of 
    recording the application of the API schema, in such cases, it would be 
    better to make it a non-applied API schema. Examples of non-applied API 
    schemas include UsdModelAPI, UsdClipsAPI, UsdShadeConnectableAPI and
    UsdGeomPrimvarsAPI.

    If there is a need to discover (or record) whether a prim contains or 
    subscribes to a given API schema, it would be advantageous to make the API 
    schema be "applied". In general, API schemas that add one or more properties 
    to a prim should be tagged as applied API schemas. A public Apply() (or 
    private _Apply()) method is generated for applied API schemas by 
    usdGenSchema. An applied API schema must be applied to a prim via a call to 
    the generated Apply() method, for the schema object to evaluate to true when
    converted to a bool using the explicit bool conversion operator. Examples of
    applied API schemas include  UsdCollectionAPI, UsdGeomModelAPI and 
    UsdGeomMotionAPI

    \\anchor UsdAPISchemaBase_SingleVsMultipleApply
    \\name 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 
    can only be applied once to a prim. A multiple-apply API schema can be 
    applied multiple times with different 'instanceName' values. An example of 
    a multiple-apply API schema is UsdCollectionAPI, where the API schema is 
    applied to a prim once for every collection owned by the prim. 
    
    \\note An applied API schema can only inherit from another applied API 
    schema or directly from APISchemaBase. Similarly, a non-applied API schema 
    can only inherit from a non-applied API Schema or directly from 
    APISchemaBase. 'usdGenSchema' attempts to issue a warning if it detects 
    an incompability.

    \\note A multiple-apply API schema may not inherit from a single-apply API 
    schema and vice versa. 

    \\note When the bool-conversion operator is invoked on an applied API 
    schema, it evaluates to true only if the application of the API schema has
    been recorded on the prim via a call to the auto-generated Apply() method.
    
    """
    customData = {
        string fileName = "apiSchemaBase"
    }
)
{
}

class "ModelAPI" 
(
    inherits = </APISchemaBase>
    doc = """UsdModelAPI is an API schema that provides an interface to a prim's
    model qualities, if it does, in fact, represent the root prim of a model.
    
    The first and foremost model quality is its \\em kind, i.e. the metadata 
    that establishes it as a model (See KindRegistry).  UsdModelAPI provides
    various methods for setting and querying the prim's kind, as well as
    queries (also available on UsdPrim) for asking what category of model
    the prim is.  See \\ref Usd_ModelKind "Kind and Model-ness".
    
    UsdModelAPI also provides access to a prim's \\ref Usd_Model_AssetInfo "assetInfo"
    data.  While any prim \\em can host assetInfo, it is common that published
    (referenced) assets are packaged as models, therefore it is convenient
    to provide access to the one from the other.
    
    \\todo establish an _IsCompatible() override that returns IsModel()
    \\todo GetModelInstanceName()
    """
    customData = {
        string apiSchemaType = "nonApplied"
    }
)
{
}

class "CollectionAPI"
(
    inherits = </APISchemaBase>
    doc = """ 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 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
    &lt;/&gt;.  If such a collection also includes paths that are not
    descendants of the excluded paths, it is considered invalid, since
    the intention is ambiguous.

    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:

    <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>
        <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>
        <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>
        </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.
    <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.
    Such a property may not (and typically does not) exist on the UsdStage, but 
    it is the path that is used to refer to the collection.
    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></ul>

    <b>Implicit inclusion</b>

    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;.

    <b>Creating collections in C++</b>
    
    \\snippet examples.cpp ApplyCollections
    """

    customData = {
        string extraIncludes = """
#include "pxr/usd/usd/collectionMembershipQuery.h"
#include "pxr/usd/usd/primFlags.h"
#include "pxr/usd/usd/tokens.h"
"""
        token apiSchemaType = "multipleApply"
        bool isPrivateApply  = true
        token propertyNamespacePrefix  = "collection"
        dictionary schemaTokens = {
            dictionary exclude = {
                string doc = """
                This is the token used to exclude a path from a collection. 
                Although it is not a possible value for the "expansionRule"
                attribute, it is used as the expansionRule for excluded paths 
                in UsdCollectionAPI::MembershipQuery::IsPathIncluded.
                """
            }
        }
    }
)
{
    uniform token expansionRule = "expandPrims" (
        allowedTokens = ["explicitOnly", "expandPrims", "expandPrimsAndProperties"]
        doc = """Specifies how the paths that are included in
        the collection must be expanded to determine its members."""
    )
    uniform bool includeRoot (
        doc = """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."""
    )
    rel includes (
        doc = """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"""
    )
    rel excludes (
        doc = """Specifies a list of targets that are excluded below
        the included paths in this collection. This can target prims or
        properties directly, but cannot target another collection. 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)."""
    )
}

class "ClipsAPI"
(
    inherits = </APISchemaBase>
    doc = """ UsdClipsAPI is an API schema that provides an interface to
    a prim's clip metadata. Clips are a "value resolution" feature that 
    allows one to specify a sequence of usd files (clips) to be consulted, 
    over time, as a source of varying overrides for the prims at and 
    beneath this prim in namespace.
            
    SetClipAssetPaths() establishes the set of clips that can be consulted.
    SetClipActive() specifies the ordering of clip application over time 
    (clips can be repeated), while SetClipTimes() specifies time-mapping
    from stage-time to clip-time for the clip active at a given stage-time,
    which allows for time-dilation and repetition of clips. 
    Finally, SetClipPrimPath() determines the path within each clip that will 
    map to this prim, i.e. the location within the clip at which we will look
    for opinions for this prim. 

    The clip asset paths, times and active metadata can also be specified 
    through template clip metadata. This can be desirable when your set of 
    assets is very large, as the template metadata is much more concise. 
    SetClipTemplateAssetPath() establishes the asset identifier pattern of the 
    set of clips to be consulted. SetClipTemplateStride(), 
    SetClipTemplateEndTime(), and SetClipTemplateStartTime() specify the range 
    in which USD will search, based on the template. From the set of resolved 
    asset paths, times and active will be derived internally.

    A prim may have multiple "clip sets" -- named sets of clips that each
    have their own values for the metadata described above. For example, 
    a prim might have a clip set named "Clips_1" that specifies some group
    of clip asset paths, and another clip set named "Clips_2" that uses
    an entirely different set of clip asset paths. These clip sets are 
    composed across composition arcs, so clip sets for a prim may be
    defined in multiple sublayers or references, for example. Individual
    metadata for a given clip set may be sparsely overridden.
                
    Important facts about clips:            
    \\li Within the layerstack in which clips are established, the           
    opinions within the clips will be \\em weaker than any local opinions
    in the layerstack, but \em stronger than varying opinions coming across
    references and variants.            
    \\li We will never look for metadata or default opinions in clips            
    when performing value resolution on the owning stage, since these           
    quantities must be time-invariant.          
            
    This leads to the common structure in which we reference a model asset
    on a prim, and then author clips at the same site: the asset reference
    will provide the topology and unvarying data for the model, while the 
    clips will provide the time-sampled animation.

    For further information, see \\ref Usd_Page_ValueClips
    """
    customData = {
        token apiSchemaType = "nonApplied"
        dictionary schemaTokens = {
            dictionary clipAssetPaths = {
              string doc = """
              List of asset paths to the clips for this prim. This list is
              unordered, but elements in this list are referred to by index in
              other clip-related fields.
              """
            }

            dictionary clipPrimPath = {
              string doc = """
              Path to the prim in the clips from which time samples will be read.
              This prim's path will be substituted with this value to determine
              the final path in the clip from which to read data. For instance,
              if this prims' path is '/Prim_1', the clip prim path is '/Prim', 
              and we want to get values for the attribute '/Prim_1.size'. The
              clip prim path will be substituted in, yielding '/Prim.size', and
              each clip will be examined for values at that path.
              """
            }

            dictionary clipManifestAssetPath = {
              string doc = """
              Asset path for the clip manifest. The clip manifest indicates which
              attributes have time samples authored in the clips specified on this
              prim. During value resolution, we will only look for time samples 
              in clips if the attribute exists and is declared as varying in the
              manifest. Note that the clip manifest is only consulted to check
              check if an attribute exists and what its variability is. Other values
              and metadata authored in the manifest will be ignored.
                                                                                     
              For instance, if this prims' path is '/Prim_1', the clip prim path is
              '/Prim', and we want values for the attribute '/Prim_1.size', we will
              only look within this prims' clips if the attribute '/Prim.size'
              exists and is varying in the manifest.
              """
            }

            dictionary clipTimes = {
              string doc = """
              List of pairs (stage time, clip time) indicating the time in the
              active clip that should be consulted for values at the corresponding
              stage time. 

              During value resolution, this list will be sorted by stage time; 
              times will then be linearly interpolated between consecutive entries.
              For instance, for clip times [(0.0, 0.0), (10.0, 20.0)], 
              at stage time 0, values from the active clip at time 0 will be used,
              at stage time 5, values from the active clip at time 10, and at stage 
              time 10, clip values at time 20.
              """
            }

            dictionary clipActive = {
              string doc = """
              List of pairs (time, clip index) indicating the time on the stage
              at which the clip specified by the clip index is active. For instance,
              a value of [(0.0, 0), (20.0, 1)] indicates that clip 0 is active
              at time 0 and clip 1 is active at time 20.
              """
            }

            dictionary clipTemplateAssetPath = {
              string doc = """
              A template string representing a set of assets. This string
              can be of two forms: path/basename.###.usd and path/basename.##.##.usd.
              In either case, the number of hash marks in each section is variable.
              These control the amount of padding USD will supply when looking up 
              the assets. For instance, a value of 'foo.###.usd', 
              with clipTemplateStartTime=11, clipTemplateEndTime=15, and clipTemplateStride=1:
              USD will look for: foo.011.usd, foo.012.usd, foo.013.usd, foo.014.usd and foo.015.usd.
              """
            }

            dictionary clipTemplateStride = {
              string doc = """
              A double representing the increment value USD will use when
              searching for asset paths. For example usage see clipTemplateAssetPath.
              """
            }

            dictionary clipTemplateStartTime = {
              string doc = """
              A double which indicates the start of the range USD will use 
              to search for asset paths. This value is inclusive in that range.
              For example usage see clipTemplateAssetPath.
              """
            }

            dictionary clipTemplateEndTime = {
              string doc = """
              A double which indicates the end of the range USD will use to
              to search for asset paths. This value is inclusive in that range.
              For example usage see clipTemplateAssetPath.
              """
            }

            dictionary clips = {
              string doc = """
              Dictionary that contains the definition of the clip sets on
              this prim. See \\ref UsdClipsAPI::GetClips.
              """
            }

            dictionary clipSets = {
              string doc = """
              ListOp that may be used to affect how opinions from
              clip sets are applied during value resolution. 
              See \\ref UsdClipsAPI::GetClipSets.
              """
            }
        }
    }
)
{
}
