# Trying to Understand this Warning: UsdImagingStageSceneIndex adapter invoked for UsdImagingDelegate skipping

**URL:** <https://forum.aousd.org/t/trying-to-understand-this-warning-usdimagingstagesceneindex-adapter-invoked-for-usdimagingdelegate-skipping/2896>\
**Category:** Hydra\
**Created:** [April 10, 2026, 4:22pm UTC](https://forum.aousd.org/t/trying-to-understand-this-warning-usdimagingstagesceneindex-adapter-invoked-for-usdimagingdelegate-skipping/2896 "2026-04-10T16:22:45Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![hamed](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/hamed/32/677_2.png) [@hamed](https://forum.aousd.org/u/hamed)\
**Post date:** [April 10, 2026, 4:22pm UTC](https://forum.aousd.org/t/trying-to-understand-this-warning-usdimagingstagesceneindex-adapter-invoked-for-usdimagingdelegate-skipping/2896/1 "2026-04-10T16:22:45Z")

</div>

Hi,

I’m currently migrating a custom UsdImaging adapter from Hydra 1.0 to Hydra 2.0 API for a custom schema prim. This prim is visualized as `HdBasisCurves`. However, I keep encountering the following warning and am trying to understand what it implies:

```auto
// Warning: UsdImagingStageSceneIndex adapter invoked for UsdImagingDelegate for prim </transform1>, skipping...

```

There are not many examples out there but I think I have implemented everything correctly based on my current understanding":

So first, I created a custom data source to provide the point data:

```cpp
constexpr const auto kSegmentsPerRing = 16; 
constexpr const auto kNumRings = 1;
constexpr const auto kPointsPerSeg = 3; // cubic Bezier: p0, cp1, cp2
constexpr const auto kVertsPerRing = kSegmentsPerRing * kPointsPerSeg;
constexpr const auto kTotalPoints = kNumRings * kVertsPerRing;
constexpr const auto kRadius = 1.0f;
const auto kKappa = (4.0f / 3.0f) * std::tan(std::numbers::pi / (2.0f * kSegmentsPerRing));

class RingNodePointsDataSource : public HdTypedSampledDataSource
{
public:
HD_DECLARE_DATASOURCE(RingNodePointsDataSource);

PXR_NS::VtValue GetValue(HdSampledDataSource::Time shutterOffset) override {
  return PXR_NS::VtValue(GetTypedValue(shutterOffset));
}

bool GetContributingSampleTimesForInterval(
    HdSampledDataSource::Time startTime, 
    HdSampledDataSource::Time endTime, 
    std::vector<HdSampledDataSource::Time> *outSampleTimes) override 
{
    return false; 
}

PXR_NS::VtVec3fArray GetTypedValue(HdSampledDataSource::Time shutterOffset) override
{
    PXR_NS::VtVec3fArray points;
    points.reserve(kTotalPoints);

    ...

    return points;
}

};

```

My adapter then derives from `UsdImagingSceneIndexPrimAdapter` and implements all required functions.

In `GetImagingSubprimData`, I construct:

- HdBasisCurves topology (cubic, bezier, periodic)

- points primvar via my custom data source

```cpp
class RingNodeAdapter : public PXR_NS::UsdImagingSceneIndexPrimAdapter
{
public:
using BaseAdapter = PXR_NS::UsdImagingSceneIndexPrimAdapter;

PXR_NS::TfTokenVector GetImagingSubprims(const PXR_NS::UsdPrim& prim) override;

PXR_NS::TfToken GetImagingSubprimType(const PXR_NS::UsdPrim& prim, 
                                      const PXR_NS::TfToken& subprim) override;

PXR_NS::HdContainerDataSourceHandle GetImagingSubprimData(
    const PXR_NS::UsdPrim& prim,
    const PXR_NS::TfToken& subprim,
    const PXR_NS::UsdImagingDataSourceStageGlobals& stageGlobals) override;

PXR_NS::HdDataSourceLocatorSet InvalidateImagingSubprim(
    const PXR_NS::UsdPrim& prim,
    const PXR_NS::TfToken& subprim,
    const PXR_NS::TfTokenVector& properties,
    PXR_NS::UsdImagingPropertyInvalidationType invalidationType) override;

};

TfTokenVector 
RingNodeAdapter::GetImagingSubprims(const UsdPrim& prim) {
    return { TfToken() };
}

TfToken 
RingNodeAdapter::GetImagingSubprimType(const UsdPrim& prim, const TfToken& subprim) 
{
    return HdPrimTypeTokens->basisCurves;
}

PXR_NS::HdContainerDataSourceHandle
RingNodeAdapter::GetImagingSubprimData(PXR_NS::UsdPrim const& prim,
    PXR_NS::TfToken const& subprim,
    const PXR_NS::UsdImagingDataSourceStageGlobals& stageGlobals)
{
    // Build Topology
    auto topologySource = PXR_NS::HdBasisCurvesTopologySchema::Builder()
        .SetCurveVertexCounts(PXR_NS::HdRetainedTypedSampledDataSource<PXR_NS::VtIntArray>::New(
            PXR_NS::VtIntArray(kNumRings, kVertsPerRing)))
        .SetBasis(PXR_NS::HdRetainedTypedSampledDataSource<PXR_NS::TfToken>::New(PXR_NS::HdTokens->bezier))
        .SetType(PXR_NS::HdRetainedTypedSampledDataSource<PXR_NS::TfToken>::New(PXR_NS::HdTokens->cubic))
        .SetWrap(PXR_NS::HdRetainedTypedSampledDataSource<PXR_NS::TfToken>::New(PXR_NS::HdTokens->periodic))
        .Build();

    // Build Primvars using RingNodePointsDataSource
    auto pointsPrimvar = PXR_NS::HdPrimvarSchema::Builder()
        .SetPrimvarValue(RingNodePointsDataSource::New())
        .SetInterpolation(PXR_NS::HdRetainedTypedSampledDataSource<PXR_NS::TfToken>::New(
            PXR_NS::HdPrimvarSchemaTokens->vertex))
        .SetRole(PXR_NS::HdRetainedTypedSampledDataSource<PXR_NS::TfToken>::New(
            PXR_NS::HdPrimvarSchemaTokens->point))
        .Build();

    auto primvars = PXR_NS::HdRetainedContainerDataSource::New(
        PXR_NS::HdPrimvarsSchemaTokens->points,
        pointsPrimvar
    );

    PXR_NS::UsdTimeCode time(stageGlobals.GetTime());
    PXR_NS::GfMatrix4d mat(1.0);
    PXR_NS::UsdGeomXformable xformable(prim);
    if (xformable) {
        bool resetsXformStack = false;
        xformable.GetLocalTransformation(&mat, &resetsXformStack, time);
    }

    return PXR_NS::HdRetainedContainerDataSource::New(
        PXR_NS::HdBasisCurvesSchemaTokens->basisCurves,
        PXR_NS::HdBasisCurvesSchema::Builder()
            .SetTopology(topologySource)
            .Build(),

        PXR_NS::HdPrimvarsSchemaTokens->primvars,
        primvars,

        // XFORM
        PXR_NS::HdXformSchemaTokens->xform,
        PXR_NS::HdXformSchema::Builder()
        .SetMatrix(
            PXR_NS::HdRetainedTypedSampledDataSource<
            PXR_NS::GfMatrix4d>::New(mat))
        .Build(),

        // VISIBILITY
        PXR_NS::HdVisibilitySchemaTokens->visibility,
        PXR_NS::HdVisibilitySchema::Builder()
            .SetVisibility(
                PXR_NS::HdRetainedTypedSampledDataSource<bool>::New(
                    PXR_NS::UsdGeomImageable(prim)
                        .ComputeVisibility(
                            PXR_NS::UsdTimeCode::Default()) 
                        != PXR_NS::UsdGeomTokens->invisible))
            .Build()
    );
}

PXR_NS::HdDataSourceLocatorSet RingNodeAdapter::InvalidateImagingSubprim(
    const PXR_NS::UsdPrim& prim,
    const PXR_NS::TfToken& subprim,
    const PXR_NS::TfTokenVector& properties,
    PXR_NS::UsdImagingPropertyInvalidationType invalidationType)
{
    PXR_NS::HdDataSourceLocatorSet locators;
        
    for (const PXR_NS::TfToken& propertyName : properties) {
        if (PXR_NS::UsdGeomXformable::IsTransformationAffectedByAttrNamed(propertyName)) {
            locators.insert(PXR_NS::HdXformSchema::GetDefaultLocator());
        } else if (propertyName == PXR_NS::UsdGeomTokens->visibility) {
            locators.insert(PXR_NS::HdVisibilitySchema::GetDefaultLocator());
        }
    }
    return locators;
}

```

I’ve registered the adapter as follows:

```cpp
TF_REGISTRY_FUNCTION(TfType) {
    TfType t = TfType::Define<RingNodeAdapter, TfType::Bases<RingNodeAdapter::BaseAdapter>>();
    t.SetFactory<UsdImagingPrimAdapterFactory<RingNodeAdapter>>();
}

```

And in plugInfo.json:

```cpp
"RingNodeAdapter": {
    "bases": [
        "UsdImagingSceneIndexPrimAdapter"
    ],
    "primTypeName": "RingNode"
}

```

and here is a minimal usd example:

```python
#usda 1.0
(
    defaultPrim = "transform1"
)

def RingNode "transform1" (
)
{
}

```

Am I missing something required for Hydra 2.0 adapter registration? Is there an additional step that I am missing?

Any help is really appreciated.

-H

---

<div class="post-metadata">

**Author:** ![hamed](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/hamed/32/677_2.png) [@hamed](https://forum.aousd.org/u/hamed)\
**Post date:** [April 10, 2026, 4:29pm UTC](https://forum.aousd.org/t/trying-to-understand-this-warning-usdimagingstagesceneindex-adapter-invoked-for-usdimagingdelegate-skipping/2896/2 "2026-04-10T16:29:47Z")

</div>

FWIW, this is my Hydra 1.0 implementation:

```cpp
class RingNodeAdapter: public PXR_NS::UsdImagingPrimAdapter

```

```cpp
PXR_NS::VtValue RingNodeAdapter::Get(const PXR_NS::UsdPrim& prim,
const PXR_NS::SdfPath& cachePath,
const PXR_NS::TfToken& key,
PXR_NS::UsdTimeCode time,
PXR_NS::VtIntArray* outIndices) const
{
if (key == PXR_NS::HdTokens->points) {
return PointsData(prim, time);
}

return BaseAdapter::Get(prim, cachePath, key, time, outIndices);

}

PXR_NS::VtValue RingNodeAdapter::GetTopology(const PXR_NS::UsdPrim& prim,
const PXR_NS::SdfPath& cachePath,
PXR_NS::UsdTimeCode time) const
{
PXR_NS::VtIntArray curveVertexCounts(kNumRings, kVertsPerRing);
PXR_NS::HdBasisCurvesTopology topo( PXR_NS::HdTokens->cubic,
PXR_NS::HdTokens->bezier,
PXR_NS::HdTokens->periodic,
curveVertexCounts,
PXR_NS::VtIntArray());
return PXR_NS::VtValue(topo);
}

PXR_NS::VtValue RingNodeAdapter::PointsData(const PXR_NS::UsdPrim& prim,
PXR_NS::UsdTimeCode timeCode) const
{
PXR_NS::VtVec3fArray points;
points.reserve(kTotalPoints);

....

return PXR_NS::VtValue(points);

}

```

this is what the rings looks like

 ![Screenshot 2026-04-10 032854](https://us1.discourse-cdn.com/flex016/uploads/aousd/original/2X/0/09e664075c7ae0897088d4f00cf924ef54c13f13.png)

---

<div class="post-metadata">

**Author:** ![hamed](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.aousd.org/hamed/32/677_2.png) [@hamed](https://forum.aousd.org/u/hamed)\
**Post date:** [April 13, 2026, 12:46pm UTC](https://forum.aousd.org/t/trying-to-understand-this-warning-usdimagingstagesceneindex-adapter-invoked-for-usdimagingdelegate-skipping/2896/3 "2026-04-13T12:46:50Z")

</div>

Nvm, I figured it out. I needed to enable `USDIMAGINGGL_ENGINE_ENABLE_TASK_SCENE_INDEX`
