Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Alembic plugin to read assets with ArResolver to support other sources except local files #3302

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 44 additions & 2 deletions pxr/usd/plugin/usdAbc/alembicReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,23 @@
/// \file alembicReader.cpp

#include "pxr/pxr.h"
#include "pxr/usd/ar/asset.h"
#include "pxr/usd/ar/resolvedPath.h"
#include "pxr/usd/ar/resolver.h"
#include "pxr/usd/plugin/usdAbc/alembicReader.h"
#include "pxr/usd/plugin/usdAbc/alembicUtil.h"
#include "pxr/usd/usdGeom/hermiteCurves.h"
#include "pxr/usd/usdGeom/tokens.h"
#include "pxr/usd/usdGeom/xformable.h"
#include "pxr/usd/sdf/schema.h"
#include "pxr/base/arch/fileSystem.h"
#include "pxr/base/work/threadLimits.h"
#include "pxr/base/trace/trace.h"
#include "pxr/base/tf/envSetting.h"
#include "pxr/base/tf/staticData.h"
#include "pxr/base/tf/staticTokens.h"
#include "pxr/base/tf/ostreamMethods.h"
#include "pxr/base/tf/fileUtils.h"
#include <Alembic/Abc/ArchiveInfo.h>
#include <Alembic/Abc/IArchive.h>
#include <Alembic/Abc/IObject.h>
Expand Down Expand Up @@ -801,6 +806,8 @@ class _ReaderContext {
const ISampleSelector& selector,
const UsdAbc_AlembicDataAny& value) const;

std::string _OpenAndGetMappedFilePath(const std::string& filePath);

// Custom auto-lock that safely ignores a NULL pointer.
class _Lock {
public:
Expand Down Expand Up @@ -853,6 +860,10 @@ class _ReaderContext {
_PrimMap _prims;
Prim* _pseudoRoot;
UsdAbc_TimeSamples _allTimeSamples;

// Asset holders to keep a reference alive so that resolver doesn't
// attempt to cleanup asset until the asset is no longer in use.
std::vector<std::shared_ptr<ArAsset>> _assetHolders;
};

static
Expand All @@ -872,6 +883,36 @@ _ReaderContext::_ReaderContext() :
// Do nothing
}

std::string
_ReaderContext::_OpenAndGetMappedFilePath(const std::string& filePath)
{
// Return as it is if it's a local path or symlink.
if (!TfIsFile(filePath, true))
{
// Open asset with Ar to support URLs other than local paths.
std::shared_ptr<ArAsset> asset =
ArGetResolver().OpenAsset(ArResolvedPath(filePath));
if (asset)
{
FILE* fileHandle; size_t fileOffset;
std::tie(fileHandle, fileOffset) = asset->GetFileUnsafe();
// Check file offset also to ensure that the .abc file
// we're looking at isn't embedded in a .usdz or other package
if (fileHandle && fileOffset == 0)
{
// If file handle is presented, use mapped file path instead of original one.
const std::string mappedFilePath = ArchGetFileName(fileHandle);
_assetHolders.emplace_back(std::move(asset));
roggiezhang-nv marked this conversation as resolved.
Show resolved Hide resolved

return mappedFilePath;
}
}
}

// Otherwise, fallback to original asset path.
return filePath;
}

bool
_ReaderContext::Open(const std::string& filePath, std::string* errorLog,
const SdfFileFormat::FileFormatArguments& args)
Expand All @@ -883,11 +924,11 @@ _ReaderContext::Open(const std::string& filePath, std::string* errorLog,
auto abcLayers = args.find("abcLayers");
if (abcLayers != args.end()) {
for (auto&& l : TfStringSplit(abcLayers->second, ",")) {
layeredABC.emplace_back(std::move(l));
layeredABC.emplace_back(_OpenAndGetMappedFilePath(l));
}
}
}
layeredABC.emplace_back(filePath);
layeredABC.emplace_back(_OpenAndGetMappedFilePath(filePath));

#if PXR_HDF5_SUPPORT_ENABLED && !H5_HAVE_THREADSAFE
// HDF5 may not be thread-safe.
Expand Down Expand Up @@ -1507,6 +1548,7 @@ _ReaderContext::_Clear()
_allTimeSamples.clear();
_instanceSources.clear();
_instances.clear();
_assetHolders.clear();
}

const _ReaderContext::Prim*
Expand Down