From d2c1126c91c0d762727dac741e15e75d5c12f472 Mon Sep 17 00:00:00 2001 From: tallytalwar Date: Tue, 12 Sep 2023 10:13:48 -0700 Subject: [PATCH] Adds logic to extract info about "includeSchemaFamily" from 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) --- pxr/usdImaging/usdImaging/adapterRegistry.cpp | 126 +++++++++++++----- 1 file changed, 90 insertions(+), 36 deletions(-) diff --git a/pxr/usdImaging/usdImaging/adapterRegistry.cpp b/pxr/usdImaging/usdImaging/adapterRegistry.cpp index a03955a810..30930cb3d4 100644 --- a/pxr/usdImaging/usdImaging/adapterRegistry.cpp +++ b/pxr/usdImaging/usdImaging/adapterRegistry.cpp @@ -69,7 +69,14 @@ UsdImagingAdapterRegistry::UsdImagingAdapterRegistry() { PlugRegistry& plugReg = PlugRegistry::GetInstance(); std::set types; PlugRegistry::GetAllDerivedTypes(*_adapterBaseType, &types); - std::vector 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> includeSchemaFamilies; TF_FOR_ALL(typeIt, types) { @@ -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()) { TF_RUNTIME_ERROR("[PluginDiscover] includeDerivedPrimTypes " @@ -154,6 +162,51 @@ UsdImagingAdapterRegistry::UsdImagingAdapterRegistry() { continue; } else if (includeDerivedIt->second.Get()){ 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()) { + 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()){ + 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); + } } } } @@ -161,49 +214,50 @@ UsdImagingAdapterRegistry::UsdImagingAdapterRegistry() { // 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 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 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);