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 4 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
43 changes: 41 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,33 @@ _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 = asset->GetFileUnsafe().first;
if (fileHandle && ftell(fileHandle) == 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the offset that's returned by GetFileUnsafe().second instead of calling ftell?

It would be good to explain why the check against the file position is needed. I'm guessing it's to ensure that the .abc file we're looking at isn't embedded in a .usdz or other package, since the Alembic code itself won't know what to do with that.

  • sunya

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

{
// 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 +921,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 +1545,7 @@ _ReaderContext::_Clear()
_allTimeSamples.clear();
_instanceSources.clear();
_instances.clear();
_assetHolders.clear();
}

const _ReaderContext::Prim*
Expand Down