//
// Copyright 2023 Pixar
//
// Licensed under the terms set forth in the LICENSE.txt file available at
// https://openusd.org/license.
//
////////////////////////////////////////////////////////////////////////

/* ************************************************************************** */
/* **                                                                      ** */
/* ** This file is generated by a script.                                  ** */
/* **                                                                      ** */
/* ** Do not edit it directly (unless it is within a CUSTOM CODE section)! ** */
/* ** Edit hdSchemaDefs.py instead to make changes.                        ** */
/* **                                                                      ** */
/* ************************************************************************** */

#ifndef PXR_IMAGING_HD_INSTANCE_SCHEMA_H
#define PXR_IMAGING_HD_INSTANCE_SCHEMA_H

/// \file

#include "pxr/imaging/hd/api.h"

#include "pxr/imaging/hd/schema.h"

// --(BEGIN CUSTOM CODE: Includes)--
// --(END CUSTOM CODE: Includes)--

PXR_NAMESPACE_OPEN_SCOPE

// --(BEGIN CUSTOM CODE: Declares)--
// --(END CUSTOM CODE: Declares)--

#define HD_INSTANCE_SCHEMA_TOKENS \
    (instance) \
    (instancer) \
    (prototypeIndex) \
    (instanceIndex) \

TF_DECLARE_PUBLIC_TOKENS(HdInstanceSchemaTokens, HD_API,
    HD_INSTANCE_SCHEMA_TOKENS);

//-----------------------------------------------------------------------------


/// \class HdInstanceSchema
///
/// This schema can be considered the opposite of instancerTopology's
/// "instanceLocations". When the scene coalesces scene prims into multiple
/// instances of a single prototype, it inserts "instance" prims at the site of
/// de-duplication. The instancer prim added to manage the prototype uses
/// "instanceLocations" to point back to all of these instance prims.
///
/// The instance prims aren't directly useful for rendering but can be useful
/// for scene processing and data aggregation.
///
class HdInstanceSchema : public HdSchema
{
public:
    /// \name Schema retrieval
    /// @{

    HdInstanceSchema(HdContainerDataSourceHandle container)
      : HdSchema(container) {}

    /// Retrieves a container data source with the schema's default name token
    /// "instance" from the parent container and constructs a
    /// HdInstanceSchema instance.
    /// Because the requested container data source may not exist, the result
    /// should be checked with IsDefined() or a bool comparison before use.
    HD_API
    static HdInstanceSchema GetFromParent(
        const HdContainerDataSourceHandle &fromParentContainer);

    /// @}

// --(BEGIN CUSTOM CODE: Schema Methods)--
// --(END CUSTOM CODE: Schema Methods)--

    /// \name Member accessor
    /// @{

    /// Path to instancer for which a (sub-)entry was added to its
    /// instancerTopology's instanceIndices during instance aggregation to
    /// account for this instance. Note that instanceIndices is nested, that
    /// is a vector data source containing integer arrays, one for each
    /// prototype the instancer is instancing. Thus, we need two indices to
    /// identify the entry: prototypeIndex is the outer index and
    /// instanceIndex the inner index.
    HD_API
    HdPathDataSourceHandle GetInstancer() const;

    /// Index into vector data source at instancer's instancerTopology's
    /// instanceIndices to find entry corresponding to this instance.
    HD_API
    HdIntDataSourceHandle GetPrototypeIndex() const;

    /// Index into int array within the vector data source at instancer's
    /// instancerTopology's instanceIndices to find entry corresponding to
    /// this instance.
    HD_API
    HdIntDataSourceHandle GetInstanceIndex() const; 

    /// @}

    /// \name Schema location
    /// @{

    /// Returns a token where the container representing this schema is found in
    /// a container by default.
    HD_API
    static const TfToken &GetSchemaToken();

    /// Returns an HdDataSourceLocator (relative to the prim-level data source)
    /// where the container representing this schema is found by default.
    HD_API
    static const HdDataSourceLocator &GetDefaultLocator();

    /// @} 

    /// \name Schema construction
    /// @{

    /// \deprecated Use Builder instead.
    ///
    /// Builds a container data source which includes the provided child data
    /// sources. Parameters with nullptr values are excluded. This is a
    /// low-level interface. For cases in which it's desired to define
    /// the container with a sparse set of child fields, the Builder class
    /// is often more convenient and readable.
    HD_API
    static HdContainerDataSourceHandle
    BuildRetained(
        const HdPathDataSourceHandle &instancer,
        const HdIntDataSourceHandle &prototypeIndex,
        const HdIntDataSourceHandle &instanceIndex
    );

    /// \class HdInstanceSchema::Builder
    /// 
    /// Utility class for setting sparse sets of child data source fields to be
    /// filled as arguments into BuildRetained. Because all setter methods
    /// return a reference to the instance, this can be used in the "builder
    /// pattern" form.
    class Builder
    {
    public:
        HD_API
        Builder &SetInstancer(
            const HdPathDataSourceHandle &instancer);
        HD_API
        Builder &SetPrototypeIndex(
            const HdIntDataSourceHandle &prototypeIndex);
        HD_API
        Builder &SetInstanceIndex(
            const HdIntDataSourceHandle &instanceIndex);

        /// Returns a container data source containing the members set thus far.
        HD_API
        HdContainerDataSourceHandle Build();

    private:
        HdPathDataSourceHandle _instancer;
        HdIntDataSourceHandle _prototypeIndex;
        HdIntDataSourceHandle _instanceIndex;

    };

    /// @}
};

PXR_NAMESPACE_CLOSE_SCOPE

#endif