OpenAsset with custom ArResolver

Hi. I have implemented a small custom Asset Resolver plugin which successfully registers and ‘resolves’ when usdview opens a usd file containing my URI asset reference e.g. @steve:someID@. _Resolve() is called with the id, and if i map this to a test file and retune this as the resolved path, the file will load.

Ideally would like my data service (represented by URI steve:*) to be able to deliver its content directly into an asset, instead of redirecting to a file that i must download/write somewhere. I have, so far, been unable to find way to get virtual override _OpenAsset() to be called from my plugin.

Elsewhere in this community I found references to an example saying that _Resolve() should only check the asset and then return the unresolved asset id; the thread implies that _OpenAsset() would then be called to finalise the Asset generation.

If I follow this approach, i see _Resolve() called followed by _GetExtension() but I never see _OpenAsset() called :frowning: Has anyone encountered this before and could advise me please on what steps i might have missed.

Many thanks.
-steve

I assume you’re using a recent USD version with ARResolver 2.0? (I forget when it was introduced but anytime in the last year+ should be fine)

This is what we have stripped down

Header:


class MyResolver : public ArDefaultResolver {

protected: // Override the base class
    AR_API
    std::string _CreateIdentifier(
            const std::string &assetPath,
            const ArResolvedPath &anchorAssetPath) const final;


    AR_API
    std::shared_ptr<ArAsset> _OpenAsset(const ArResolvedPath &resolvedPath) const final;

    AR_API
    ArTimestamp _GetModificationTimestamp(
            const std::string &path,
            const ArResolvedPath &resolvedPath) const final;

    AR_API
    ArResolvedPath _Resolve(const std::string &assetPath) const final;

    AR_API
    std::string _GetExtension(const std::string &path) const final;

private: // New methods
   std::shared_ptr<std::vector<char>>
   FetchFile(const std::string &assetPath, ArResolverContext &context) const final;

};

Body , where MyAsset is a subclass of ArAsset


AR_DEFINE_RESOLVER(MyResolver, ArResolver)

std::shared_ptr<ArAsset> MyResolver::_OpenAsset(const ArResolvedPath &resolvedPath) const {
    auto context = GetCurrentContext();
    auto buffer  = FetchFile(resolvedPath.GetPathString(), context);
    return std::make_shared<MyAsset>(buffer);
}

ArTimestamp
MyResolver::_GetModificationTimestamp(
        const std::string &path,
        const ArResolvedPath &resolvedPath) const {
    // Calculate the modified timestamp here or return 0
    return 0;
}


std::string
MyResolver::_CreateIdentifier(
        const std::string &assetPath,
        const ArResolvedPath &anchorAssetPath) const {
    // Create the unique, full identifier by combining inputs
    return "anchorAssetPath/assetPath";
}

ArResolvedPath
MyResolver::_Resolve(
        const std::string &assetPath) const {
    // This just bypasses the automatic filtering that the default resolver does
    return ArResolvedPath(assetPath);
}

std::string MyResolver::_GetExtension(const std::string &path) const {
    return ".usdc"; // or whatever you calculate from the path
}

Thank you. I can now see _OpenAsset being called.
-steve

Glad that worked out!