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

Fix UDIM path resolution for scene index plugins #3494

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
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
79 changes: 79 additions & 0 deletions pxr/usdImaging/usdImaging/dataSourceAttribute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,78 @@

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

#include "pxr/usd/usdShade/udimUtils.h"

PXR_NAMESPACE_OPEN_SCOPE

namespace {

// We need to find the first layer that changes the value
// of the parameter so that we anchor relative paths to that.
static
SdfLayerHandle
_FindLayerHandle(const UsdAttribute& attr, const UsdTimeCode& time) {
for (const auto& spec: attr.GetPropertyStack(time)) {
if (spec->HasDefaultValue() ||
spec->GetLayer()->GetNumTimeSamplesForPath(
spec->GetPath()) > 0) {
return spec->GetLayer();
}
}
return TfNullPtr;
}

class UsdImagingDataSourceAssetPathAttribute :
public UsdImagingDataSourceAttribute<SdfAssetPath>
{
public:
HD_DECLARE_DATASOURCE(UsdImagingDataSourceAssetPathAttribute);

/// Returns the extracted SdfAssetPath value of the attribute at
/// \p shutterOffset, with proper handling for UDIM paths.
SdfAssetPath
GetTypedValue(HdSampledDataSource::Time shutterOffset) override
{
// Zero-initialization for numerical types.
SdfAssetPath result{};
UsdTimeCode time = _stageGlobals.GetTime();
if (time.IsNumeric()) {
time = UsdTimeCode(time.GetValue() + shutterOffset);
}
_usdAttrQuery.Get<SdfAssetPath>(&result, time);
if (UsdShadeUdimUtils::IsUdimIdentifier(result.GetAssetPath())) {
const std::string resolvedPath =
UsdShadeUdimUtils::ResolveUdimPath(result.GetAssetPath(),
_FindLayerHandle(_usdAttrQuery.GetAttribute(), time));
if (!resolvedPath.empty()) {
result = SdfAssetPath(result.GetAssetPath(), resolvedPath);
}
}
return result;
}

protected:
UsdImagingDataSourceAssetPathAttribute(
const UsdAttribute &usdAttr,
const UsdImagingDataSourceStageGlobals &stageGlobals,
const SdfPath &sceneIndexPath = SdfPath::EmptyPath(),
const HdDataSourceLocator &timeVaryingFlagLocator =
HdDataSourceLocator::EmptyLocator())
: UsdImagingDataSourceAttribute<SdfAssetPath>(usdAttr,
stageGlobals, sceneIndexPath, timeVaryingFlagLocator)
{ }

UsdImagingDataSourceAssetPathAttribute(
const UsdAttributeQuery &usdAttrQuery,
const UsdImagingDataSourceStageGlobals &stageGlobals,
const SdfPath &sceneIndexPath = SdfPath::EmptyPath(),
const HdDataSourceLocator &timeVaryingFlagLocator =
HdDataSourceLocator::EmptyLocator())
: UsdImagingDataSourceAttribute<SdfAssetPath>(usdAttrQuery,
stageGlobals, sceneIndexPath, timeVaryingFlagLocator)
{ }
};

typedef HdSampledDataSourceHandle (*_DataSourceFactory)(
const UsdAttributeQuery &usdAttrQuery,
const UsdImagingDataSourceStageGlobals &stageGlobals,
Expand All @@ -32,6 +100,17 @@ HdSampledDataSourceHandle _FactoryImpl(
usdAttrQuery, stageGlobals, sceneIndexPath, timeVaryingFlagLocator);
}

template <>
HdSampledDataSourceHandle _FactoryImpl<SdfAssetPath>(
const UsdAttributeQuery &usdAttrQuery,
const UsdImagingDataSourceStageGlobals &stageGlobals,
const SdfPath &sceneIndexPath,
const HdDataSourceLocator &timeVaryingFlagLocator)
{
return UsdImagingDataSourceAssetPathAttribute::New(
usdAttrQuery, stageGlobals, sceneIndexPath, timeVaryingFlagLocator);
}

static _FactoryMap _CreateFactoryMap()
{
_FactoryMap map;
Expand Down
6 changes: 4 additions & 2 deletions pxr/usdImaging/usdImaging/dataSourceAttribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,10 @@ class UsdImagingDataSourceAttribute : public HdTypedSampledDataSource<T>
return outSampleTimes->size() > 1;
}

private:
protected:
/// Constructors and member data are protected instead of private
/// for use by a specialized subclass for accessing SdfAssetPath
/// attributes which need special handling for UDIMs.

/// Constructs a new UsdImagingDataSourceAttribute for the given \p usdAttr
///
Expand Down Expand Up @@ -137,7 +140,6 @@ class UsdImagingDataSourceAttribute : public HdTypedSampledDataSource<T>
const HdDataSourceLocator &timeVaryingFlagLocator =
HdDataSourceLocator::EmptyLocator());

private:
UsdAttributeQuery _usdAttrQuery;
const UsdImagingDataSourceStageGlobals &_stageGlobals;
};
Expand Down