Skip to content

Commit

Permalink
UsdImagingDataSourceMapped: extending to also work for relationships.
Browse files Browse the repository at this point in the history
(Internal change: 2356388)
  • Loading branch information
unhyperbolic authored and pixar-oss committed Feb 11, 2025
1 parent 9b566e6 commit 2231250
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 95 deletions.
16 changes: 9 additions & 7 deletions pxr/usdImaging/usdImaging/dataSourceImplicits-Impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ class UsdImagingDataSourceImplicitsPrim : public UsdImagingDataSourceGprim

private:
static
std::vector<UsdImagingDataSourceMapped::AttributeMapping>
_GetAttributeMappings() {
std::vector<UsdImagingDataSourceMapped::AttributeMapping> result;
std::vector<UsdImagingDataSourceMapped::PropertyMapping>
_GetPropertyMappings() {
std::vector<UsdImagingDataSourceMapped::PropertyMapping> result;

for (const TfToken &usdName :
UsdSchemaType::GetSchemaAttributeNames(
Expand All @@ -77,16 +77,18 @@ class UsdImagingDataSourceImplicitsPrim : public UsdImagingDataSourceGprim
// in UsdImagingDataSourcePrim::Get.
continue;
}
result.push_back({ usdName, HdDataSourceLocator(usdName)});
result.push_back(
UsdImagingDataSourceMapped::AttributeMapping{
usdName, HdDataSourceLocator(usdName)});
}
return result;
}

static
const UsdImagingDataSourceMapped::AttributeMappings &
const UsdImagingDataSourceMapped::PropertyMappings &
_GetMappings() {
static const UsdImagingDataSourceMapped::AttributeMappings result(
_GetAttributeMappings(), HdSchemaType::GetDefaultLocator());
static const UsdImagingDataSourceMapped::PropertyMappings result(
_GetPropertyMappings(), HdSchemaType::GetDefaultLocator());
return result;
}

Expand Down
188 changes: 157 additions & 31 deletions pxr/usdImaging/usdImaging/dataSourceMapped.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,30 @@

#include "pxr/usdImaging/usdImaging/dataSourceMapped.h"

#include <variant>
#include "pxr/usd/usd/relationship.h"

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

PXR_NAMESPACE_OPEN_SCOPE

namespace UsdImagingDataSourceMapped_Impl
{

using AttributeMapping =
UsdImagingDataSourceMapped::AttributeMapping;
using RelationshipMapping =
UsdImagingDataSourceMapped::RelationshipMapping;
using DataSourceRelationshipFactoryFn =
UsdImagingDataSourceMapped::DataSourceRelationshipFactoryFn;

// For a given location within UsdImagingDataSourceMapped,
// information what data source to create.
//
// Such a data source is either an HdSampledDataSource giving
// the value of an Usd attribute. Or a container data source.
using _DataSourceInfo =
std::variant<UsdImagingDataSourceMapped::AttributeMapping,
std::variant<AttributeMapping,
RelationshipMapping,
_ContainerMappingsSharedPtr>;

// Data for a container data source.
Expand All @@ -37,14 +47,69 @@ struct _ContainerMappings
std::vector<_DataSourceInfo> dataSourceInfos;
};

HdDataSourceBaseHandle
_PathFromRelationshipFactory(
const UsdRelationship &rel,
const UsdImagingDataSourceStageGlobals &,
const SdfPath &,
const HdDataSourceLocator &)
{
SdfPathVector result;
rel.GetForwardedTargets(&result);
if (result.empty()) {
return nullptr;
}
return HdRetainedTypedSampledDataSource<SdfPath>::New(std::move(result[0]));
}

VtArray<SdfPath>
_ToArray(SdfPathVector &&v)
{
return VtArray<SdfPath>(
std::make_move_iterator(v.begin()),
std::make_move_iterator(v.end()));
}

HdDataSourceBaseHandle
_PathArrayFromRelationshipFactory(
const UsdRelationship &rel,
const UsdImagingDataSourceStageGlobals &,
const SdfPath &,
const HdDataSourceLocator &)
{
SdfPathVector result;
rel.GetForwardedTargets(&result);
return
HdRetainedTypedSampledDataSource<VtArray<SdfPath>>::New(
_ToArray(std::move(result)));
}

}

using namespace UsdImagingDataSourceMapped_Impl;

/* static */
const DataSourceRelationshipFactoryFn&
UsdImagingDataSourceMapped::GetPathFromRelationshipDataSourceFactory()
{
static const DataSourceRelationshipFactoryFn result(
_PathFromRelationshipFactory);
return result;
}

/* static */
const DataSourceRelationshipFactoryFn&
UsdImagingDataSourceMapped::GetPathArrayFromRelationshipDataSourceFactory()
{
static const DataSourceRelationshipFactoryFn result(
_PathArrayFromRelationshipFactory);
return result;
}

UsdImagingDataSourceMapped::UsdImagingDataSourceMapped(
UsdPrim const &usdPrim,
const SdfPath &sceneIndexPath,
const AttributeMappings &mappings,
const PropertyMappings &mappings,
const UsdImagingDataSourceStageGlobals &stageGlobals)
: UsdImagingDataSourceMapped(
usdPrim,
Expand Down Expand Up @@ -94,20 +159,53 @@ UsdImagingDataSourceMapped::Get(const TfToken &name)
(itName - _containerMappings->hdNames.begin());

const _DataSourceInfo &info = *itInfo;
if (auto const mapping = std::get_if<AttributeMapping>(&info)) {
if (auto const attrMapping = std::get_if<AttributeMapping>(&info)) {
// We create a data source from the UsdAttribute.
UsdAttribute attr = _usdPrim.GetAttribute(mapping->usdName);
const UsdAttribute attr = _usdPrim.GetAttribute(attrMapping->usdName);
if (!attr) {
TF_CODING_ERROR(
"Expected usd attribute '%s' on prim '%s' to serve "
"data source at locator '%s'.",
mapping->usdName.GetText(),
attrMapping->usdName.GetText(),
_usdPrim.GetPath().GetText(),
mapping->hdLocator.GetString().c_str());
attrMapping->hdLocator.GetString().c_str());
return nullptr;
}
return mapping->factory(
attr, _stageGlobals, _sceneIndexPath, mapping->hdLocator);
if (!attrMapping->factory) {
TF_CODING_ERROR(
"No factory given to convert usd attribute '%s' on prim '%s' "
"to serve data source at locator '%s'.",
attrMapping->usdName.GetText(),
_usdPrim.GetPath().GetText(),
attrMapping->hdLocator.GetString().c_str());
return nullptr;
}
return attrMapping->factory(
attr, _stageGlobals, _sceneIndexPath, attrMapping->hdLocator);
} else if (auto const relMapping =
std::get_if<RelationshipMapping>(&info)) {
const UsdRelationship rel =
_usdPrim.GetRelationship(relMapping->usdName);
if (!rel) {
TF_CODING_ERROR(
"Expected usd relationship '%s' on prim '%s' to serve "
"data source at locator '%s'.",
relMapping->usdName.GetText(),
_usdPrim.GetPath().GetText(),
relMapping->hdLocator.GetString().c_str());
return nullptr;
}
if (!relMapping->factory) {
TF_CODING_ERROR(
"No factory given to convert usd relationship '%s' on prim '%s' "
"to serve data source at locator '%s'.",
relMapping->usdName.GetText(),
_usdPrim.GetPath().GetText(),
relMapping->hdLocator.GetString().c_str());
return nullptr;
}
return relMapping->factory(
rel, _stageGlobals, _sceneIndexPath, relMapping->hdLocator);
} else {
// We are in the nested case.
return UsdImagingDataSourceMapped::New(
Expand All @@ -120,12 +218,12 @@ UsdImagingDataSourceMapped::Get(const TfToken &name)

HdDataSourceLocatorSet
UsdImagingDataSourceMapped::Invalidate(
const TfTokenVector &usdNames, const AttributeMappings &mappings)
const TfTokenVector &usdNames, const PropertyMappings &mappings)
{
HdDataSourceLocatorSet locators;

for (const TfToken &usdName : usdNames) {
for (const AttributeMapping &mapping : mappings._absoluteMappings) {
for (const PropertyMappingBase &mapping : mappings._absoluteMappings) {
if (mapping.usdName == usdName) {
locators.insert(mapping.hdLocator);
}
Expand All @@ -135,8 +233,22 @@ UsdImagingDataSourceMapped::Invalidate(
return locators;
}

static
TfToken
_GetUsdName(const _DataSourceInfo &info)
{
if (auto const attrMapping = std::get_if<AttributeMapping>(&info)) {
return attrMapping->usdName;
}
if (auto const relMapping = std::get_if<RelationshipMapping>(&info)) {
return relMapping->usdName;
}
return TfToken("<UNKNOWN>");
}

// Find or add name as key to given containerMappings - returning the
// _ContainerMappings at that key.
static
_ContainerMappingsSharedPtr
_FindOrCreateChild(const TfToken &name,
_ContainerMappingsSharedPtr const &containerMappings)
Expand All @@ -153,12 +265,10 @@ _FindOrCreateChild(const TfToken &name,
const _DataSourceInfo &info = *itInfo;
auto * const child = std::get_if<_ContainerMappingsSharedPtr>(&info);
if (!child) {
const auto &mapping =
std::get<UsdImagingDataSourceMapped::AttributeMapping>(info);
TF_CODING_ERROR(
"Adding data source locator when there was already an "
"ascendant locator added for a Usd attribute with name '%s'.",
mapping.usdName.GetText());
_GetUsdName(info).GetText());
return nullptr;
}
return *child;
Expand All @@ -174,15 +284,16 @@ _FindOrCreateChild(const TfToken &name,
}

// Add mapping to containerMappins at given locator.
static
void
_Add(const HdDataSourceLocator &locator,
const UsdImagingDataSourceMapped::AttributeMapping &mapping,
_DataSourceInfo &&info,
_ContainerMappingsSharedPtr containerMappings)
{
const size_t n = locator.GetElementCount();
if (n == 0) {
TF_CODING_ERROR("Expected non-trivial data source locator for "
"attribute %s.", mapping.usdName.GetText());
"attribute %s.", _GetUsdName(info).GetText());
return;
}

Expand All @@ -195,7 +306,7 @@ _Add(const HdDataSourceLocator &locator,
}
}

const TfToken &name = mapping.hdLocator.GetLastElement();
const TfToken &name = locator.GetLastElement();

// And add the AttributeMapping as leaf.
const auto itName = std::lower_bound(
Expand All @@ -207,29 +318,44 @@ _Add(const HdDataSourceLocator &locator,
(itName - containerMappings->hdNames.begin());

containerMappings->hdNames.insert(itName, name);
containerMappings->dataSourceInfos.insert(itInfo, mapping);
containerMappings->dataSourceInfos.insert(itInfo, std::move(info));
}

UsdImagingDataSourceMapped::AttributeMappings::AttributeMappings(
const std::vector<AttributeMapping> &mappings,
UsdImagingDataSourceMapped::PropertyMappings::PropertyMappings(
const std::vector<PropertyMapping> &mappings,
const HdDataSourceLocator &dataSourcePrefix)
{
_absoluteMappings.reserve(mappings.size());
_containerMappings = std::make_shared<_ContainerMappings>();

for (const AttributeMapping &mapping : mappings) {
// Making locator absolute.
const AttributeMapping absoluteMapping{
mapping.usdName,
dataSourcePrefix.Append(mapping.hdLocator),
mapping.factory};

_absoluteMappings.push_back(absoluteMapping);

_Add(mapping.hdLocator, absoluteMapping, _containerMappings);
for (const PropertyMapping &mapping : mappings) {
if (auto const attrMapping = std::get_if<AttributeMapping>(&mapping)) {
// Making locator absolute.
const HdDataSourceLocator locator =
dataSourcePrefix.Append(attrMapping->hdLocator);
_absoluteMappings.push_back(
{ attrMapping->usdName, locator });
_Add(
attrMapping->hdLocator,
AttributeMapping{
attrMapping->usdName, locator, attrMapping->factory },
_containerMappings);
} else if (auto const &relMapping =
std::get_if<RelationshipMapping>(&mapping)) {
// Making locator absolute.
const HdDataSourceLocator locator =
dataSourcePrefix.Append(relMapping->hdLocator);
_absoluteMappings.push_back(
{ relMapping->usdName, locator });
_Add(
relMapping->hdLocator,
RelationshipMapping{
relMapping->usdName, locator, relMapping->factory },
_containerMappings);
}
}
}

UsdImagingDataSourceMapped::AttributeMappings::~AttributeMappings() = default;
UsdImagingDataSourceMapped::PropertyMappings::~PropertyMappings() = default;

PXR_NAMESPACE_CLOSE_SCOPE
Loading

0 comments on commit 2231250

Please sign in to comment.