From ce1c44b38ca85f3f2220b72d62dd04fc9edf48ff Mon Sep 17 00:00:00 2001 From: Dhruv Govil Date: Mon, 19 Apr 2021 11:31:45 -0700 Subject: [PATCH 1/4] Add support to dynamically list all registered concrete prim types in UFE>Add Prim menu --- lib/mayaUsd/ufe/UsdContextOps.cpp | 72 +++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/lib/mayaUsd/ufe/UsdContextOps.cpp b/lib/mayaUsd/ufe/UsdContextOps.cpp index 4ade092f7d..be018a4f36 100644 --- a/lib/mayaUsd/ufe/UsdContextOps.cpp +++ b/lib/mayaUsd/ufe/UsdContextOps.cpp @@ -23,6 +23,8 @@ #include #include +#include +#include #include #include #include @@ -102,6 +104,8 @@ static const std::string kUSDCylinderPrimImage { "out_USD_Cylinder.png" }; static constexpr char kUSDSpherePrimItem[] = "Sphere"; static constexpr char kUSDSpherePrimLabel[] = "Sphere"; static const std::string kUSDSpherePrimImage { "out_USD_Sphere.png" }; +static constexpr char kAllRegisteredTypesItem[] = "All Registered"; +static constexpr char kAllRegisteredTypesLabel[] = "All Registered"; //! \brief Undoable command for loading a USD prim. class LoadUndoableCommand : public Ufe::UndoableCommand @@ -420,6 +424,26 @@ _computeLoadAndUnloadItems(const UsdPrim& prim) return itemLabelPairs; } +// Get all the currently registered prim types from USD +// so that we may display them in a UI list for users. +static const std::vector getConcretePrimTypes() +{ + std::vector primTypes; + + // Query all the available types + std::set schemaTypes; + PlugRegistry::GetAllDerivedTypes(&schemaTypes); + + for (auto t : schemaTypes) { + // Find the primType as it would be within the USD file + if (UsdSchemaRegistry::IsConcrete(t)) { + primTypes.emplace_back(UsdSchemaRegistry::GetConcreteSchemaTypeName(t)); + } + } + + return primTypes; +} + } // namespace namespace MAYAUSD_NS_DEF { @@ -537,19 +561,32 @@ Ufe::ContextOps::Items UsdContextOps::getItems(const Ufe::ContextOps::ItemPath& } // Variants of a variant set } // Variant sets else if (itemPath[0] == kUSDAddNewPrimItem) { - items.emplace_back( - kUSDDefPrimItem, kUSDDefPrimLabel, kUSDDefPrimImage); // typeless prim - items.emplace_back(kUSDScopePrimItem, kUSDScopePrimLabel, kUSDScopePrimImage); - items.emplace_back(kUSDXformPrimItem, kUSDXformPrimLabel, kUSDXformPrimImage); - items.emplace_back(Ufe::ContextItem::kSeparator); - items.emplace_back(kUSDCapsulePrimItem, kUSDCapsulePrimLabel, kUSDCapsulePrimImage); - items.emplace_back(kUSDConePrimItem, kUSDConePrimLabel, kUSDConePrimImage); - items.emplace_back(kUSDCubePrimItem, kUSDCubePrimLabel, kUSDCubePrimImage); - items.emplace_back(kUSDCylinderPrimItem, kUSDCylinderPrimLabel, kUSDCylinderPrimImage); - items.emplace_back(kUSDSpherePrimItem, kUSDSpherePrimLabel, kUSDSpherePrimImage); - } - } // Top-level items - + if (itemPath.size() == 1u) { // Root setup + items.emplace_back( + kUSDDefPrimItem, kUSDDefPrimLabel, kUSDDefPrimImage); // typeless prim + items.emplace_back(kUSDScopePrimItem, kUSDScopePrimLabel, kUSDScopePrimImage); + items.emplace_back(kUSDXformPrimItem, kUSDXformPrimLabel, kUSDXformPrimImage); + items.emplace_back(Ufe::ContextItem::kSeparator); + items.emplace_back(kUSDCapsulePrimItem, kUSDCapsulePrimLabel, kUSDCapsulePrimImage); + items.emplace_back(kUSDConePrimItem, kUSDConePrimLabel, kUSDConePrimImage); + items.emplace_back(kUSDCubePrimItem, kUSDCubePrimLabel, kUSDCubePrimImage); + items.emplace_back( + kUSDCylinderPrimItem, kUSDCylinderPrimLabel, kUSDCylinderPrimImage); + items.emplace_back(kUSDSpherePrimItem, kUSDSpherePrimLabel, kUSDSpherePrimImage); + items.emplace_back(Ufe::ContextItem::kSeparator); + items.emplace_back( + kAllRegisteredTypesItem, kAllRegisteredTypesLabel, Ufe::ContextItem::kHasChildren); + } else if (itemPath.size() == 2u) { // Sub Menus + if (itemPath[1] == kAllRegisteredTypesItem) { + auto primTypes = getConcretePrimTypes(); + std::sort(primTypes.begin(), primTypes.end()); + for (auto primType : primTypes) { + items.emplace_back(primType, primType); + } + } + } + } // Add New Prim Item + } // Top-level items return items; } @@ -592,14 +629,13 @@ Ufe::UndoableCommand::Ptr UsdContextOps::doOpCmd(const ItemPath& itemPath) } // ActiveState else if (!itemPath.empty() && (itemPath[0] == kUSDAddNewPrimItem)) { // Operation is to create a new prim of the type specified. - if (itemPath.size() != 2u) { + if (itemPath.size() < 2u) { TF_CODING_ERROR("Wrong number of arguments"); return nullptr; } - - // At this point we know we have 2 arguments to execute the operation. - // itemPath[1] contains the new prim type to create. - return UsdUndoAddNewPrimCommand::create(fItem, itemPath[1], itemPath[1]); + // At this point we know the last item in the itemPath is the prim type to create + auto primType = itemPath[itemPath.size() - 1]; + return UsdUndoAddNewPrimCommand::create(fItem, primType, primType); #ifdef WANT_QT_BUILD // When building without Qt there is no LayerEditor } else if (itemPath[0] == kUSDLayerEditorItem) { From 4868ffbbb11d29f2f7426027d3b9c0805212cac3 Mon Sep 17 00:00:00 2001 From: Dhruv Govil Date: Tue, 27 Apr 2021 11:25:43 -0700 Subject: [PATCH 2/4] Group registered types in the Add Prim UI options --- lib/mayaUsd/ufe/UsdContextOps.cpp | 134 ++++++++++++++++++++++++++---- lib/mayaUsd/ufe/UsdContextOps.h | 10 +++ 2 files changed, 126 insertions(+), 18 deletions(-) diff --git a/lib/mayaUsd/ufe/UsdContextOps.cpp b/lib/mayaUsd/ufe/UsdContextOps.cpp index be018a4f36..35589b4ca5 100644 --- a/lib/mayaUsd/ufe/UsdContextOps.cpp +++ b/lib/mayaUsd/ufe/UsdContextOps.cpp @@ -107,6 +107,38 @@ static const std::string kUSDSpherePrimImage { "out_USD_Sphere.png" }; static constexpr char kAllRegisteredTypesItem[] = "All Registered"; static constexpr char kAllRegisteredTypesLabel[] = "All Registered"; +// Grouping and name mapping for registered schema plugins +static const std::vector kSchemaPluginNames = { + "usdGeom", + "usdLux", + "mayaUsd_Schemas", + "usdMedia", + "usdRender", + "usdRi", + "usdShade", + "usdSkel", + "usdUI", + "usdVol", + "AL_USDMayaSchemasTest", + "AL_USDMayaSchemas", +}; +// clang-format off +static const std::vector kSchemaNiceNames = { + "Geometry", + "Lighting", + "Maya Reference", + "Media", + "Render", + "RenderMan", + "Shading", + "Skeleton", + "UI", + "Volumes", + "", // Skip legacy AL schemas + "", // Skip legacy AL schemas +}; +// clang-format on + //! \brief Undoable command for loading a USD prim. class LoadUndoableCommand : public Ufe::UndoableCommand { @@ -424,30 +456,76 @@ _computeLoadAndUnloadItems(const UsdPrim& prim) return itemLabelPairs; } -// Get all the currently registered prim types from USD -// so that we may display them in a UI list for users. -static const std::vector getConcretePrimTypes() +} // namespace + +namespace MAYAUSD_NS_DEF { +namespace ufe { + +std::vector UsdContextOps::fSchemaTypeGroups = {}; + +bool _schemaGroupSortCompare(const SchemaTypeGroup& a, const SchemaTypeGroup& b) +{ + return a.name < b.name; +} + +//! \brief Get groups of concrete schema prim types to list dynamically in the UI +static const std::vector getConcretePrimTypes(bool sorted) { - std::vector primTypes; + std::vector groups; // Query all the available types + PlugRegistry& plugReg = PlugRegistry::GetInstance(); std::set schemaTypes; - PlugRegistry::GetAllDerivedTypes(&schemaTypes); + plugReg.GetAllDerivedTypes(&schemaTypes); for (auto t : schemaTypes) { - // Find the primType as it would be within the USD file - if (UsdSchemaRegistry::IsConcrete(t)) { - primTypes.emplace_back(UsdSchemaRegistry::GetConcreteSchemaTypeName(t)); + if (!UsdSchemaRegistry::IsConcrete(t)) { + continue; + } + + auto plugin = plugReg.GetPluginForType(t); + if (!plugin) { + continue; + } + + // For every plugin we check if there's a nice name registered and use that instead + auto plugin_name = plugin->GetName(); + auto name_itr + = std::find(kSchemaPluginNames.begin(), kSchemaPluginNames.end(), plugin_name); + if (name_itr != kSchemaPluginNames.end()) { + plugin_name = kSchemaNiceNames[name_itr - kSchemaPluginNames.begin()]; + } + + // We don't list empty names. This allows hiding certain plugins too. + if (plugin_name.empty()) { + continue; + } + + auto type_name = UsdSchemaRegistry::GetConcreteSchemaTypeName(t); + + // Find or create the schema group and add to it + auto group_itr = find(begin(groups), end(groups), plugin_name); + if (group_itr == groups.end()) { + SchemaTypeGroup group { plugin_name }; + group.types.emplace_back(type_name); + groups.emplace_back(group); + } else { + groups[group_itr - groups.begin()].types.emplace_back(type_name); } } - return primTypes; -} + if (sorted) { + for (size_t i = 0; i < groups.size(); ++i) { + auto group = groups[i]; + std::sort(group.types.begin(), group.types.end()); + groups[i] = group; + } -} // namespace + std::sort(groups.begin(), groups.end(), _schemaGroupSortCompare); + } -namespace MAYAUSD_NS_DEF { -namespace ufe { + return groups; +} UsdContextOps::UsdContextOps(const UsdSceneItem::Ptr& item) : Ufe::ContextOps() @@ -575,13 +653,33 @@ Ufe::ContextOps::Items UsdContextOps::getItems(const Ufe::ContextOps::ItemPath& items.emplace_back(kUSDSpherePrimItem, kUSDSpherePrimLabel, kUSDSpherePrimImage); items.emplace_back(Ufe::ContextItem::kSeparator); items.emplace_back( - kAllRegisteredTypesItem, kAllRegisteredTypesLabel, Ufe::ContextItem::kHasChildren); + kAllRegisteredTypesItem, + kAllRegisteredTypesLabel, + Ufe::ContextItem::kHasChildren); } else if (itemPath.size() == 2u) { // Sub Menus if (itemPath[1] == kAllRegisteredTypesItem) { - auto primTypes = getConcretePrimTypes(); - std::sort(primTypes.begin(), primTypes.end()); - for (auto primType : primTypes) { - items.emplace_back(primType, primType); + // List the Registered schema plugins + // Load this each time the menu is called in case plugins were loaded + // in between invocations. + // However we cache it so the submenus don't need to re-query + fSchemaTypeGroups = getConcretePrimTypes(true); + for (auto schema : fSchemaTypeGroups) { + items.emplace_back( + schema.name.c_str(), + schema.name.c_str(), + Ufe::ContextItem::kHasChildren); + } + } + } else if (itemPath.size() == 3u) { + if (itemPath[1] == kAllRegisteredTypesItem) { + // List the items that belong to this schema plugin + for (auto schema : fSchemaTypeGroups) { + if (schema.name != itemPath[2]) { + continue; + } + for (auto t : schema.types) { + items.emplace_back(t, t); + } } } } diff --git a/lib/mayaUsd/ufe/UsdContextOps.h b/lib/mayaUsd/ufe/UsdContextOps.h index 469ff9b81e..96ee520cac 100644 --- a/lib/mayaUsd/ufe/UsdContextOps.h +++ b/lib/mayaUsd/ufe/UsdContextOps.h @@ -26,6 +26,13 @@ namespace MAYAUSD_NS_DEF { namespace ufe { +struct SchemaTypeGroup +{ + std::string name; + std::vector types; + bool operator==(const std::string rhs) const { return name == rhs; } +}; + //! \brief Interface for scene item context operations. /*! This class defines the interface that USD run-time implements to @@ -76,6 +83,9 @@ class MAYAUSD_CORE_PUBLIC UsdContextOps : public Ufe::ContextOps UsdSceneItem::Ptr fItem; bool fIsAGatewayType { false }; + // A cache to keep the dynamic listing of plugin types to a minimum + static std::vector fSchemaTypeGroups; + }; // UsdContextOps } // namespace ufe From f984375df2d046eb7baec00226f36eb7b47a978a Mon Sep 17 00:00:00 2001 From: Dhruv Govil Date: Tue, 27 Apr 2021 15:03:17 -0700 Subject: [PATCH 3/4] Registered Types: Address notes from Sean --- lib/mayaUsd/ufe/UsdContextOps.cpp | 66 +++++++++++++++++-------------- lib/mayaUsd/ufe/UsdContextOps.h | 12 ++++-- 2 files changed, 44 insertions(+), 34 deletions(-) diff --git a/lib/mayaUsd/ufe/UsdContextOps.cpp b/lib/mayaUsd/ufe/UsdContextOps.cpp index 35589b4ca5..7fbca0ea8c 100644 --- a/lib/mayaUsd/ufe/UsdContextOps.cpp +++ b/lib/mayaUsd/ufe/UsdContextOps.cpp @@ -104,8 +104,10 @@ static const std::string kUSDCylinderPrimImage { "out_USD_Cylinder.png" }; static constexpr char kUSDSpherePrimItem[] = "Sphere"; static constexpr char kUSDSpherePrimLabel[] = "Sphere"; static const std::string kUSDSpherePrimImage { "out_USD_Sphere.png" }; -static constexpr char kAllRegisteredTypesItem[] = "All Registered"; -static constexpr char kAllRegisteredTypesLabel[] = "All Registered"; + +#if PXR_VERSION >= 2008 +static constexpr char kAllRegisteredTypesItem[] = "All Registered"; +static constexpr char kAllRegisteredTypesLabel[] = "All Registered"; // Grouping and name mapping for registered schema plugins static const std::vector kSchemaPluginNames = { @@ -138,6 +140,7 @@ static const std::vector kSchemaNiceNames = { "", // Skip legacy AL schemas }; // clang-format on +#endif //! \brief Undoable command for loading a USD prim. class LoadUndoableCommand : public Ufe::UndoableCommand @@ -455,23 +458,11 @@ _computeLoadAndUnloadItems(const UsdPrim& prim) return itemLabelPairs; } - -} // namespace - -namespace MAYAUSD_NS_DEF { -namespace ufe { - -std::vector UsdContextOps::fSchemaTypeGroups = {}; - -bool _schemaGroupSortCompare(const SchemaTypeGroup& a, const SchemaTypeGroup& b) -{ - return a.name < b.name; -} - +#if PXR_VERSION >= 2008 //! \brief Get groups of concrete schema prim types to list dynamically in the UI -static const std::vector getConcretePrimTypes(bool sorted) +static const std::vector getConcretePrimTypes(bool sorted) { - std::vector groups; + std::vector groups; // Query all the available types PlugRegistry& plugReg = PlugRegistry::GetInstance(); @@ -506,26 +497,38 @@ static const std::vector getConcretePrimTypes(bool sorted) // Find or create the schema group and add to it auto group_itr = find(begin(groups), end(groups), plugin_name); if (group_itr == groups.end()) { - SchemaTypeGroup group { plugin_name }; - group.types.emplace_back(type_name); + MayaUsd::ufe::SchemaTypeGroup group { plugin_name }; + group._types.emplace_back(type_name); groups.emplace_back(group); } else { - groups[group_itr - groups.begin()].types.emplace_back(type_name); + groups[group_itr - groups.begin()]._types.emplace_back(type_name); } } if (sorted) { for (size_t i = 0; i < groups.size(); ++i) { auto group = groups[i]; - std::sort(group.types.begin(), group.types.end()); + std::sort(group._types.begin(), group._types.end()); groups[i] = group; } - std::sort(groups.begin(), groups.end(), _schemaGroupSortCompare); + std::sort(groups.begin(), groups.end(), [](const auto& lhs, const auto& rhs) { + return lhs._name < rhs._name; + }); } return groups; } +#endif + +} // namespace + +namespace MAYAUSD_NS_DEF { +namespace ufe { + +#if PXR_VERSION >= 2008 +std::vector UsdContextOps::schemaTypeGroups = {}; +#endif UsdContextOps::UsdContextOps(const UsdSceneItem::Ptr& item) : Ufe::ContextOps() @@ -651,6 +654,7 @@ Ufe::ContextOps::Items UsdContextOps::getItems(const Ufe::ContextOps::ItemPath& items.emplace_back( kUSDCylinderPrimItem, kUSDCylinderPrimLabel, kUSDCylinderPrimImage); items.emplace_back(kUSDSpherePrimItem, kUSDSpherePrimLabel, kUSDSpherePrimImage); +#if PXR_VERSION >= 2008 items.emplace_back(Ufe::ContextItem::kSeparator); items.emplace_back( kAllRegisteredTypesItem, @@ -662,27 +666,29 @@ Ufe::ContextOps::Items UsdContextOps::getItems(const Ufe::ContextOps::ItemPath& // Load this each time the menu is called in case plugins were loaded // in between invocations. // However we cache it so the submenus don't need to re-query - fSchemaTypeGroups = getConcretePrimTypes(true); - for (auto schema : fSchemaTypeGroups) { + schemaTypeGroups = getConcretePrimTypes(true); + for (auto schema : schemaTypeGroups) { items.emplace_back( - schema.name.c_str(), - schema.name.c_str(), + schema._name.c_str(), + schema._name.c_str(), Ufe::ContextItem::kHasChildren); } } } else if (itemPath.size() == 3u) { if (itemPath[1] == kAllRegisteredTypesItem) { // List the items that belong to this schema plugin - for (auto schema : fSchemaTypeGroups) { - if (schema.name != itemPath[2]) { + for (auto schema : schemaTypeGroups) { + if (schema._name != itemPath[2]) { continue; } - for (auto t : schema.types) { + for (auto t : schema._types) { items.emplace_back(t, t); } } } - } +#endif + } // If USD >= 20.08, submenus end here. Otherwise end of Root Setup + } // Add New Prim Item } // Top-level items return items; diff --git a/lib/mayaUsd/ufe/UsdContextOps.h b/lib/mayaUsd/ufe/UsdContextOps.h index 96ee520cac..2e4c5da125 100644 --- a/lib/mayaUsd/ufe/UsdContextOps.h +++ b/lib/mayaUsd/ufe/UsdContextOps.h @@ -26,12 +26,14 @@ namespace MAYAUSD_NS_DEF { namespace ufe { +#if PXR_VERSION >= 2008 struct SchemaTypeGroup { - std::string name; - std::vector types; - bool operator==(const std::string rhs) const { return name == rhs; } + std::string _name; + pxr::TfTokenVector _types; + bool operator==(const std::string rhs) const { return _name == rhs; } }; +#endif //! \brief Interface for scene item context operations. /*! @@ -83,8 +85,10 @@ class MAYAUSD_CORE_PUBLIC UsdContextOps : public Ufe::ContextOps UsdSceneItem::Ptr fItem; bool fIsAGatewayType { false }; +#if PXR_VERSION >= 2008 // A cache to keep the dynamic listing of plugin types to a minimum - static std::vector fSchemaTypeGroups; + static std::vector schemaTypeGroups; +#endif }; // UsdContextOps From 044b668c0f957f11c7d613a589a80d5d80e46c2c Mon Sep 17 00:00:00 2001 From: Dhruv Govil Date: Thu, 29 Apr 2021 09:39:46 -0700 Subject: [PATCH 4/4] Make call to IsConcrete non-static to support USD 20.08 --- lib/mayaUsd/ufe/UsdContextOps.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/mayaUsd/ufe/UsdContextOps.cpp b/lib/mayaUsd/ufe/UsdContextOps.cpp index 7fbca0ea8c..3f65790fd9 100644 --- a/lib/mayaUsd/ufe/UsdContextOps.cpp +++ b/lib/mayaUsd/ufe/UsdContextOps.cpp @@ -298,7 +298,7 @@ class ToggleActiveStateCommand : public Ufe::UndoableCommand const char* selectUSDFileScript = R"( global proc string SelectUSDFileForAddReference() { - string $result[] = `fileDialog2 + string $result[] = `fileDialog2 -fileMode 1 -caption "Add Reference to USD Prim" -fileFilter "USD Files (*.usd *.usda *.usdc);;*.usd;;*.usda;;*.usdc"`; @@ -314,7 +314,7 @@ SelectUSDFileForAddReference(); const char* clearAllReferencesConfirmScript = R"( global proc string ClearAllUSDReferencesConfirm() { - return `confirmDialog -title "Remove All References" + return `confirmDialog -title "Remove All References" -message "Removing all references from USD prim. Are you sure?" -button "Yes" -button "No" -defaultButton "Yes" -cancelButton "No" -dismissString "No"`; @@ -469,8 +469,9 @@ static const std::vector getConcretePrimTypes(boo std::set schemaTypes; plugReg.GetAllDerivedTypes(&schemaTypes); + UsdSchemaRegistry& schemaReg = UsdSchemaRegistry::GetInstance(); for (auto t : schemaTypes) { - if (!UsdSchemaRegistry::IsConcrete(t)) { + if (!schemaReg.IsConcrete(t)) { continue; }