Skip to content

Commit

Permalink
Adds logic to extract info about "includeSchemaFamily" from
Browse files Browse the repository at this point in the history
pluginInfo.json

This allows one adapter to be used to render multiple different schema
versions.

This will be used in the subsequent change to use CylinderAdapter and
CapsuleAdapter respectively for UsdGeomCylinder_1 and UsdGeomCapsule_1
renders.

Changes split from #2596

(Internal change: 2294998)
  • Loading branch information
tallytalwar authored and pixar-oss committed Sep 18, 2023
1 parent 24acf5a commit d2c1126
Showing 1 changed file with 90 additions and 36 deletions.
126 changes: 90 additions & 36 deletions pxr/usdImaging/usdImaging/adapterRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,14 @@ UsdImagingAdapterRegistry::UsdImagingAdapterRegistry() {
PlugRegistry& plugReg = PlugRegistry::GetInstance();
std::set<TfType> types;
PlugRegistry::GetAllDerivedTypes(*_adapterBaseType, &types);
std::vector<TfToken> includeDerivedPrimTypes;
TfTokenVector includeDerivedPrimTypes;
// Set of schema families we have an adapter for; the boolean indicates
// whether we also need to include types which are derived from another
// type in the same family.
// Example: UsdGeomCylinder_1 belongs to UsdGeomCylinder schema family and
// share the same usdImaging adapter. Any derived type of Cylinder_1 will
// also share the same adapter unless explicitly provided.
std::vector<std::pair<TfToken,bool>> includeSchemaFamilies;

TF_FOR_ALL(typeIt, types) {

Expand Down Expand Up @@ -145,6 +152,7 @@ UsdImagingAdapterRegistry::UsdImagingAdapterRegistry() {
// through additional metadata.
JsObject::const_iterator includeDerivedIt =
metadata.find("includeDerivedPrimTypes");
bool includeDerived = false;
if (includeDerivedIt != metadata.end()) {
if (!includeDerivedIt->second.Is<bool>()) {
TF_RUNTIME_ERROR("[PluginDiscover] includeDerivedPrimTypes "
Expand All @@ -154,56 +162,102 @@ UsdImagingAdapterRegistry::UsdImagingAdapterRegistry() {
continue;
} else if (includeDerivedIt->second.Get<bool>()){
includeDerivedPrimTypes.push_back(primTypeName);
includeDerived = true;
}
}

// Adapters can opt in to being used as the adapter for any prim
// types in the same family
JsObject::const_iterator includeFamilyIt =
metadata.find("includeSchemaFamily");
if (includeFamilyIt != metadata.end()) {
if (!includeFamilyIt->second.Is<bool>()) {
TF_RUNTIME_ERROR("[PluginDiscover] includeSchemaFamily "
"metadata was corrupted for plugin '%s'; not holding "
"bool\n",
typeIt->GetTypeName().c_str());
continue;
} else if (includeFamilyIt->second.Get<bool>()){
includeSchemaFamilies.push_back(
std::make_pair(primTypeName, includeDerived));
}
}
}

for (auto const &pair : includeSchemaFamilies) {
const TfToken& familyName = std::get<0>(pair);
const bool includeDerived = std::get<1>(pair);
const TfType adapterType = _typeMap[familyName];
// Associate all schemas in the family with this adapter by emplacing it
// in the typeMap. Additionally if includeDerived is also specified,
// emplace it in the includeDerivedPrimTypes vector, so as to process
// any type which are derived from various versions of the schema.
for (const UsdSchemaRegistry::SchemaInfo* schemaInfo :
UsdSchemaRegistry::FindSchemaInfosInFamily(familyName)) {
if (_typeMap.emplace(schemaInfo->identifier, adapterType).second) {
const TfToken typeName =
UsdSchemaRegistry::GetSchemaTypeName(schemaInfo->type);
TF_DEBUG(USDIMAGING_PLUGINS).Msg(
"[PluginDiscover] Mapping adapter for family '%s' to type "
"'%s'\n", familyName.GetText(), typeName.GetText());

if (includeDerived) {
// This plugin has requested including both derived types
// and all types in the family. This will include the
// adaptor for any derived types in the family, too.
includeDerivedPrimTypes.push_back(typeName);
}
}
}
}

// Process the types whose derived types can use its adapter after all
// explicit prim type to adapter mappings have been found.
auto _ProcessDerivedTypes = [&includeDerivedPrimTypes](_TypeMap *tm) {
for (const TfToken &primTypeName : includeDerivedPrimTypes) {
const TfType primType =
UsdSchemaRegistry::GetTypeFromSchemaTypeName(primTypeName);
if (!primType) {
continue;
}
for (const TfToken &primTypeName : includeDerivedPrimTypes) {
const TfType primType =
UsdSchemaRegistry::GetTypeFromSchemaTypeName(primTypeName);
if (!primType) {
continue;
}

const TfType adapterType = (*tm)[primTypeName];
const TfType adapterType = (*tm)[primTypeName];

// Start with just the directly derived types; we'll continue to
// propagate the adapter type through derived prim types that do not
// have their own adapter already.
std::vector<TfType> derivedTypesStack =
PlugRegistry::GetDirectlyDerivedTypes(primType);
// Start with just the directly derived types; we'll continue to
// propagate the adapter type through derived prim types that do not
// have their own adapter already.
std::vector<TfType> derivedTypesStack =
PlugRegistry::GetDirectlyDerivedTypes(primType);

while (!derivedTypesStack.empty()) {
const TfType derivedType = derivedTypesStack.back();
derivedTypesStack.pop_back();
while (!derivedTypesStack.empty()) {
const TfType derivedType = derivedTypesStack.back();
derivedTypesStack.pop_back();

const TfToken typeName =
UsdSchemaRegistry::GetSchemaTypeName(derivedType);
if (typeName.IsEmpty()) {
continue;
}

// If the derived type name isn't already in the map, then the
// mapping to the ancestor's adapter is added and we'll continue
// propagating to the next depth of derived types. Otherwise, the
// derived type's adapter was already set and we skip its derived
// types regardless of whether they have adapters already or not.
if (tm->emplace(typeName, adapterType).second) {
TF_DEBUG(USDIMAGING_PLUGINS).Msg(
"[PluginDiscover] Mapping adapter for type '%s' to derived "
"type '%s'\n",
primTypeName.GetText(), typeName.GetText());
const TfToken typeName =
UsdSchemaRegistry::GetSchemaTypeName(derivedType);
if (typeName.IsEmpty()) {
continue;
}

for (const TfType &type :
PlugRegistry::GetDirectlyDerivedTypes(derivedType)) {
derivedTypesStack.push_back(type);
// If the derived type name isn't already in the map, then the
// mapping to the ancestor's adapter is added and we'll continue
// propagating to the next depth of derived types. Otherwise, the
// derived type's adapter was already set and we skip its derived
// types regardless of whether they have adapters already or not.
if (tm->emplace(typeName, adapterType).second) {
TF_DEBUG(USDIMAGING_PLUGINS).Msg(
"[PluginDiscover] Mapping adapter for type '%s' to derived "
"type '%s'\n",
primTypeName.GetText(), typeName.GetText());

for (const TfType &type :
PlugRegistry::GetDirectlyDerivedTypes(derivedType)) {
derivedTypesStack.push_back(type);
}
}
}
}
}};
};

_ProcessDerivedTypes(&_typeMap);

Expand Down

0 comments on commit d2c1126

Please sign in to comment.