From 16fd8bef4b991b1b55ad4af08e6ff410e010e2b5 Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Mon, 12 Jun 2023 18:29:32 -0400 Subject: [PATCH 01/12] Add prediction function and update find function in primReader --- lib/mayaUsd/fileio/jobs/readJob.cpp | 2 +- lib/mayaUsd/fileio/primReader.cpp | 8 ++ lib/mayaUsd/fileio/primReader.h | 18 ++++ lib/mayaUsd/fileio/primReaderRegistry.cpp | 115 +++++++++++++++++++--- lib/mayaUsd/fileio/primReaderRegistry.h | 44 ++++++++- lib/mayaUsd/fileio/primUpdater.cpp | 6 +- lib/mayaUsd/fileio/shaderReader.h | 2 + 7 files changed, 180 insertions(+), 15 deletions(-) diff --git a/lib/mayaUsd/fileio/jobs/readJob.cpp b/lib/mayaUsd/fileio/jobs/readJob.cpp index 1577115b71..09c46fc3bd 100644 --- a/lib/mayaUsd/fileio/jobs/readJob.cpp +++ b/lib/mayaUsd/fileio/jobs/readJob.cpp @@ -513,7 +513,7 @@ void UsdMaya_ReadJob::_DoImportPrimIt( TfToken typeName = prim.GetTypeName(); if (UsdMayaPrimReaderRegistry::ReaderFactoryFn factoryFn - = UsdMayaPrimReaderRegistry::FindOrFallback(typeName)) { + = UsdMayaPrimReaderRegistry::FindOrFallback(typeName, mArgs)) { UsdMayaPrimReaderSharedPtr primReader = factoryFn(args); if (primReader) { TempNodeTrackerScope scope(readCtx); diff --git a/lib/mayaUsd/fileio/primReader.cpp b/lib/mayaUsd/fileio/primReader.cpp index e8e8a67175..4bc580efb6 100644 --- a/lib/mayaUsd/fileio/primReader.cpp +++ b/lib/mayaUsd/fileio/primReader.cpp @@ -22,6 +22,14 @@ UsdMayaPrimReader::UsdMayaPrimReader(const UsdMayaPrimReaderArgs& args) { } +/* static */ +UsdMayaPrimReader::ContextSupport UsdMayaPrimReader::CanImport(const UsdMayaJobImportArgs&) +{ + // Default value for all readers is Fallback. More specialized writers can + // override the base CanImport to report Supported/Unsupported as necessary. + return ContextSupport::Fallback; +} + bool UsdMayaPrimReader::HasPostReadSubtree() const { return false; } void UsdMayaPrimReader::PostReadSubtree(UsdMayaPrimReaderContext&) { } diff --git a/lib/mayaUsd/fileio/primReader.h b/lib/mayaUsd/fileio/primReader.h index 64a416b63f..91fff3c130 100644 --- a/lib/mayaUsd/fileio/primReader.h +++ b/lib/mayaUsd/fileio/primReader.h @@ -31,6 +31,24 @@ class UsdMayaPrimReader UsdMayaPrimReader(const UsdMayaPrimReaderArgs&); virtual ~UsdMayaPrimReader() {}; + /// The level of support a reader can offer for a given context + /// + /// A basic reader that gives correct results across most contexts should + /// report `Fallback`, while a specialized reader that really shines in a + /// given context should report `Supported` when the context is right and + /// `Unsupported` if the context is not as expected. + enum class ContextSupport + { + Supported, + Fallback, + Unsupported + }; + + /// This static function is expected for all shader readers and allows + /// declaring how well this class can support the current context: + MAYAUSD_CORE_PUBLIC + static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); + /// Reads the USD prim given by the prim reader args into a Maya shape, /// modifying the prim reader context as a result. /// Returns true if successful. diff --git a/lib/mayaUsd/fileio/primReaderRegistry.cpp b/lib/mayaUsd/fileio/primReaderRegistry.cpp index 6668491346..4164185d47 100644 --- a/lib/mayaUsd/fileio/primReaderRegistry.cpp +++ b/lib/mayaUsd/fileio/primReaderRegistry.cpp @@ -43,8 +43,46 @@ TF_DEFINE_PRIVATE_TOKENS( ); // clang-format on -typedef std::map _Registry; -static _Registry _reg; + +namespace { +struct _RegistryEntry +{ + UsdMayaPrimReaderRegistry::ContextPredicateFn _pred; + UsdMayaPrimReaderRegistry::ReaderFactoryFn _fn; + int _index; +}; + +// typedef std::map _Registry; +typedef std::unordered_multimap _Registry; +static _Registry _reg; +static int _indexCounter = 0; + +//TODO: Add pred function +_Registry::const_iterator _Find(const TfToken& typeName, const UsdMayaJobImportArgs& importArgs) +{ + using ContextSupport = UsdMayaPrimReader::ContextSupport; + + _Registry::const_iterator ret = _reg.cend(); + _Registry::const_iterator first, last; + + // Debug + // equal range will return the start and end pos for all elements that matches typename + // we need all matches because we are using a multimap, that each type can have multiple readers + std::tie(first, last) = _reg.equal_range(typeName); + while (first != last) { + ContextSupport support = first->second._pred(importArgs); + if (support == ContextSupport::Supported) { + ret = first; + break; + } else if (support == ContextSupport::Fallback && ret == _reg.end()) { + ret = first; + } + ++first; + } + + return ret; +} +} // namespace /* static */ void UsdMayaPrimReaderRegistry::Register( @@ -53,14 +91,59 @@ void UsdMayaPrimReaderRegistry::Register( bool fromPython) { TfToken tfTypeName(t.GetTypeName()); + int index = _indexCounter++; TF_DEBUG(PXRUSDMAYA_REGISTRY) .Msg("Registering UsdMayaPrimReader for TfType %s.\n", tfTypeName.GetText()); - std::pair<_Registry::iterator, bool> insertStatus = _reg.insert(std::make_pair(tfTypeName, fn)); + //std::pair<_Registry::iterator, bool> insertStatus = _reg.insert(std::make_pair(tfTypeName, fn)); + + // Debug: + // For backward compatiblity, can we create a emtry pred function that always return Fallback? + _reg.insert(std::make_pair( + tfTypeName, + _RegistryEntry { + [](const UsdMayaJobImportArgs&) { return UsdMayaPrimReader::ContextSupport::Fallback; }, + fn, + index })); + /* if (insertStatus.second) { UsdMaya_RegistryHelper::AddUnloader([tfTypeName]() { _reg.erase(tfTypeName); }, fromPython); } else { TF_CODING_ERROR("Multiple readers for type %s", tfTypeName.GetText()); } + */ +} + +/* static */ +void UsdMayaPrimReaderRegistry::Register( + const TfType& t, + UsdMayaPrimReaderRegistry::ContextPredicateFn pred, + UsdMayaPrimReaderRegistry::ReaderFactoryFn fn, + bool fromPython) +{ + TfToken tfTypeName(t.GetTypeName()); + int index = _indexCounter++; + TF_DEBUG(PXRUSDMAYA_REGISTRY) + .Msg("Registering UsdMayaPrimReader for TfType %s.\n", tfTypeName.GetText()); + //std::pair<_Registry::iterator, bool> insertStatus = _reg.insert(std::make_pair(tfTypeName, _RegistryEntry { pred, fn })); + _reg.insert(std::make_pair(tfTypeName, _RegistryEntry { pred, fn, index })); + + // The unloader uses the index to know which entry to erase when there are + // more than one for the same usdInfoId. + if (fn) { + UsdMaya_RegistryHelper::AddUnloader( + [tfTypeName, index]() { + _Registry::const_iterator it, itEnd; + std::tie(it, itEnd) = _reg.equal_range(tfTypeName); + for (; it != itEnd; ++it) { + if (it->second._index == index) { + _reg.erase(it); + break; + } + } + }, + fromPython); + } + } /* static */ @@ -71,7 +154,7 @@ void UsdMayaPrimReaderRegistry::RegisterRaw(const TfType& t, UsdMayaPrimReaderRe /* static */ UsdMayaPrimReaderRegistry::ReaderFactoryFn -UsdMayaPrimReaderRegistry::Find(const TfToken& usdTypeName) +UsdMayaPrimReaderRegistry::Find(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs) { TfRegistryManager::GetInstance().SubscribeTo(); @@ -81,8 +164,12 @@ UsdMayaPrimReaderRegistry::Find(const TfToken& usdTypeName) std::string typeNameStr = tfType.GetTypeName(); TfToken typeName(typeNameStr); ReaderFactoryFn ret = nullptr; - if (TfMapLookup(_reg, typeName, &ret)) { - return ret; + + // For that we are using unordered_multimap now, we can't use TfMapLookup anymore + _Registry::const_iterator it = _Find(typeName, importArgs); + + if (it != _reg.end()) { + return it->second._fn; } static const TfTokenVector SCOPE = { _tokens->UsdMaya, _tokens->PrimReader }; @@ -90,19 +177,25 @@ UsdMayaPrimReaderRegistry::Find(const TfToken& usdTypeName) // ideally something just registered itself. if not, we at least put it in // the registry in case we encounter it again. - if (!TfMapLookup(_reg, typeName, &ret)) { + + if (_reg.count(typeName) == 0) { TF_DEBUG(PXRUSDMAYA_REGISTRY) .Msg("No usdMaya reader plugin for TfType %s. No maya plugin.\n", typeName.GetText()); - _reg[typeName] = nullptr; + //_reg[typeName] = nullptr; + Register( + tfType, + [](const UsdMayaJobImportArgs&) { return UsdMayaPrimReader::ContextSupport::Fallback; }, + nullptr); } - return ret; + + return nullptr; } /* static */ UsdMayaPrimReaderRegistry::ReaderFactoryFn -UsdMayaPrimReaderRegistry::FindOrFallback(const TfToken& usdTypeName) +UsdMayaPrimReaderRegistry::FindOrFallback(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs) { - if (ReaderFactoryFn fn = Find(usdTypeName)) { + if (ReaderFactoryFn fn = Find(usdTypeName, importArgs)) { return fn; } diff --git a/lib/mayaUsd/fileio/primReaderRegistry.h b/lib/mayaUsd/fileio/primReaderRegistry.h index 7a991bc2e2..af6b872e36 100644 --- a/lib/mayaUsd/fileio/primReaderRegistry.h +++ b/lib/mayaUsd/fileio/primReaderRegistry.h @@ -54,6 +54,11 @@ struct UsdMayaPrimReaderRegistry /// for the given prim reader args. typedef std::function ReaderFactoryFn; + /// Predicate function, i.e. a function that can tell the level of support + /// the reader function will provide for a given context. + using ContextPredicateFn + = std::function; + /// Reader function, i.e. a function that reads a prim. This is the /// signature of the function declared in the PXRUSDMAYA_DEFINE_READER /// macro. @@ -63,6 +68,16 @@ struct UsdMayaPrimReaderRegistry MAYAUSD_CORE_PUBLIC static void Register(const TfType& type, ReaderFactoryFn fn, bool fromPython = false); + // Debug: + // overload a function for backward compatibility? + /// \brief Register \p fn as a reader provider for \p type. + MAYAUSD_CORE_PUBLIC + static void Register( + const TfType& type, + ContextPredicateFn pred, + ReaderFactoryFn fn, + bool fromPython = false); + /// \brief Register \p fn as a reader provider for \p T. /// /// Example for registering a reader factory in your custom plugin, assuming @@ -85,6 +100,30 @@ struct UsdMayaPrimReaderRegistry } } + // TODO: Write the sample code + /// \brief Register \p fn as a reader provider for \p T. + /// + /// Example for registering a reader factory in your custom plugin, assuming + /// that MyType is registered with the TfType system: + /// \code{.cpp} + /// class MyReader : public UsdMayaPrimReader { + /// static UsdMayaPrimReaderSharedPtr Create( + /// const UsdMayaPrimReaderArgs&); + /// }; + /// TF_REGISTRY_FUNCTION_WITH_TAG(UsdMayaPrimReaderRegistry, MyType) { + /// UsdMayaPrimReaderRegistry::Register(ContextSupport, MyReader::Create); + /// } + /// \endcode + template + static void Register(ContextPredicateFn pred, ReaderFactoryFn fn, bool fromPython = false) + { + if (TfType t = TfType::Find()) { + Register(t, pred, fn, fromPython); + } else { + TF_CODING_ERROR("Cannot register unknown TfType: %s.", ArchGetDemangled().c_str()); + } + } + /// \brief Wraps \p fn in a ReaderFactoryFn and registers that factory /// function as a reader provider for \p T. /// This is a helper method for the macro PXRUSDMAYA_DEFINE_READER; @@ -100,13 +139,14 @@ struct UsdMayaPrimReaderRegistry /// prim.GetTypeName() /// \endcode MAYAUSD_CORE_PUBLIC - static ReaderFactoryFn Find(const TfToken& usdTypeName); + static ReaderFactoryFn + Find(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs); /// Similar to Find(), but returns a "fallback" prim reader factory if none /// can be found for \p usdTypeName. Thus, this always returns a valid /// reader factory. MAYAUSD_CORE_PUBLIC - static ReaderFactoryFn FindOrFallback(const TfToken& usdTypeName); + static ReaderFactoryFn FindOrFallback(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs); }; // Lookup TfType by name instead of static C++ type when diff --git a/lib/mayaUsd/fileio/primUpdater.cpp b/lib/mayaUsd/fileio/primUpdater.cpp index 5184e634af..0803c63a14 100644 --- a/lib/mayaUsd/fileio/primUpdater.cpp +++ b/lib/mayaUsd/fileio/primUpdater.cpp @@ -72,7 +72,11 @@ bool UsdMayaPrimUpdater::canEditAsMaya() const // exporter (to USD) capability. auto prim = MayaUsd::ufe::ufePathToPrim(_path); TF_AXIOM(prim); - return (UsdMayaPrimReaderRegistry::Find(prim.GetTypeName()) != nullptr); + UsdMayaJobImportArgs jobArgs = UsdMayaJobImportArgs::CreateFromDictionary( + _context->GetUserArgs(), + /* importWithProxyShapes = */ false, + GfInterval::GetFullInterval()); + return (UsdMayaPrimReaderRegistry::Find(prim.GetTypeName(), jobArgs) != nullptr); } bool UsdMayaPrimUpdater::editAsMaya() { return true; } diff --git a/lib/mayaUsd/fileio/shaderReader.h b/lib/mayaUsd/fileio/shaderReader.h index 450519d50e..b6e2066a05 100644 --- a/lib/mayaUsd/fileio/shaderReader.h +++ b/lib/mayaUsd/fileio/shaderReader.h @@ -41,6 +41,7 @@ class UsdMayaShaderReader : public UsdMayaPrimReader MAYAUSD_CORE_PUBLIC UsdMayaShaderReader(const UsdMayaPrimReaderArgs&); + /* /// The level of support a reader can offer for a given context /// /// A basic reader that gives correct results across most contexts should @@ -53,6 +54,7 @@ class UsdMayaShaderReader : public UsdMayaPrimReader Fallback, Unsupported }; + */ /// This static function is expected for all shader readers and allows /// declaring how well this class can support the current context: From 78b49ad62f4787e70fbec2aca11ef7d9df514d06 Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Wed, 14 Jun 2023 17:22:50 -0400 Subject: [PATCH 02/12] Add summary to new function and update legacy register function --- lib/mayaUsd/fileio/primReaderRegistry.cpp | 47 +++++++++++------------ lib/mayaUsd/fileio/primReaderRegistry.h | 21 +++++----- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/lib/mayaUsd/fileio/primReaderRegistry.cpp b/lib/mayaUsd/fileio/primReaderRegistry.cpp index 4164185d47..655b0c729f 100644 --- a/lib/mayaUsd/fileio/primReaderRegistry.cpp +++ b/lib/mayaUsd/fileio/primReaderRegistry.cpp @@ -43,7 +43,6 @@ TF_DEFINE_PRIVATE_TOKENS( ); // clang-format on - namespace { struct _RegistryEntry { @@ -52,12 +51,10 @@ struct _RegistryEntry int _index; }; -// typedef std::map _Registry; typedef std::unordered_multimap _Registry; -static _Registry _reg; +static _Registry _reg; static int _indexCounter = 0; -//TODO: Add pred function _Registry::const_iterator _Find(const TfToken& typeName, const UsdMayaJobImportArgs& importArgs) { using ContextSupport = UsdMayaPrimReader::ContextSupport; @@ -65,12 +62,10 @@ _Registry::const_iterator _Find(const TfToken& typeName, const UsdMayaJobImportA _Registry::const_iterator ret = _reg.cend(); _Registry::const_iterator first, last; - // Debug - // equal range will return the start and end pos for all elements that matches typename - // we need all matches because we are using a multimap, that each type can have multiple readers std::tie(first, last) = _reg.equal_range(typeName); while (first != last) { ContextSupport support = first->second._pred(importArgs); + // Look for a "Supported" reader. If no "Supported" reader is found, use a "Fallback" reader if (support == ContextSupport::Supported) { ret = first; break; @@ -94,37 +89,42 @@ void UsdMayaPrimReaderRegistry::Register( int index = _indexCounter++; TF_DEBUG(PXRUSDMAYA_REGISTRY) .Msg("Registering UsdMayaPrimReader for TfType %s.\n", tfTypeName.GetText()); - //std::pair<_Registry::iterator, bool> insertStatus = _reg.insert(std::make_pair(tfTypeName, fn)); - // Debug: - // For backward compatiblity, can we create a emtry pred function that always return Fallback? + // Use default ContextSupport if not specified _reg.insert(std::make_pair( tfTypeName, _RegistryEntry { [](const UsdMayaJobImportArgs&) { return UsdMayaPrimReader::ContextSupport::Fallback; }, fn, index })); - /* - if (insertStatus.second) { - UsdMaya_RegistryHelper::AddUnloader([tfTypeName]() { _reg.erase(tfTypeName); }, fromPython); - } else { - TF_CODING_ERROR("Multiple readers for type %s", tfTypeName.GetText()); + + if (fn) { + UsdMaya_RegistryHelper::AddUnloader( + [tfTypeName, index]() { + _Registry::const_iterator it, itEnd; + std::tie(it, itEnd) = _reg.equal_range(tfTypeName); + for (; it != itEnd; ++it) { + if (it->second._index == index) { + _reg.erase(it); + break; + } + } + }, + fromPython); } - */ } /* static */ void UsdMayaPrimReaderRegistry::Register( - const TfType& t, + const TfType& t, UsdMayaPrimReaderRegistry::ContextPredicateFn pred, - UsdMayaPrimReaderRegistry::ReaderFactoryFn fn, - bool fromPython) + UsdMayaPrimReaderRegistry::ReaderFactoryFn fn, + bool fromPython) { TfToken tfTypeName(t.GetTypeName()); int index = _indexCounter++; TF_DEBUG(PXRUSDMAYA_REGISTRY) .Msg("Registering UsdMayaPrimReader for TfType %s.\n", tfTypeName.GetText()); - //std::pair<_Registry::iterator, bool> insertStatus = _reg.insert(std::make_pair(tfTypeName, _RegistryEntry { pred, fn })); _reg.insert(std::make_pair(tfTypeName, _RegistryEntry { pred, fn, index })); // The unloader uses the index to know which entry to erase when there are @@ -143,7 +143,6 @@ void UsdMayaPrimReaderRegistry::Register( }, fromPython); } - } /* static */ @@ -177,7 +176,6 @@ UsdMayaPrimReaderRegistry::Find(const TfToken& usdTypeName, const UsdMayaJobImpo // ideally something just registered itself. if not, we at least put it in // the registry in case we encounter it again. - if (_reg.count(typeName) == 0) { TF_DEBUG(PXRUSDMAYA_REGISTRY) .Msg("No usdMaya reader plugin for TfType %s. No maya plugin.\n", typeName.GetText()); @@ -192,8 +190,9 @@ UsdMayaPrimReaderRegistry::Find(const TfToken& usdTypeName, const UsdMayaJobImpo } /* static */ -UsdMayaPrimReaderRegistry::ReaderFactoryFn -UsdMayaPrimReaderRegistry::FindOrFallback(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs) +UsdMayaPrimReaderRegistry::ReaderFactoryFn UsdMayaPrimReaderRegistry::FindOrFallback( + const TfToken& usdTypeName, + const UsdMayaJobImportArgs& importArgs) { if (ReaderFactoryFn fn = Find(usdTypeName, importArgs)) { return fn; diff --git a/lib/mayaUsd/fileio/primReaderRegistry.h b/lib/mayaUsd/fileio/primReaderRegistry.h index af6b872e36..18bddf2495 100644 --- a/lib/mayaUsd/fileio/primReaderRegistry.h +++ b/lib/mayaUsd/fileio/primReaderRegistry.h @@ -68,17 +68,16 @@ struct UsdMayaPrimReaderRegistry MAYAUSD_CORE_PUBLIC static void Register(const TfType& type, ReaderFactoryFn fn, bool fromPython = false); - // Debug: - // overload a function for backward compatibility? - /// \brief Register \p fn as a reader provider for \p type. + /// \brief Register \p fn as a reader provider for \p type and provide the supportability. MAYAUSD_CORE_PUBLIC static void Register( - const TfType& type, + const TfType& type, ContextPredicateFn pred, - ReaderFactoryFn fn, - bool fromPython = false); + ReaderFactoryFn fn, + bool fromPython = false); /// \brief Register \p fn as a reader provider for \p T. + /// Context support will be set to default "Fallback" /// /// Example for registering a reader factory in your custom plugin, assuming /// that MyType is registered with the TfType system: @@ -100,8 +99,8 @@ struct UsdMayaPrimReaderRegistry } } - // TODO: Write the sample code - /// \brief Register \p fn as a reader provider for \p T. + /// \brief Register \p fn as a reader provider for \p T and provide the supportability. + /// Use "Supported" to override default reader /// /// Example for registering a reader factory in your custom plugin, assuming /// that MyType is registered with the TfType system: @@ -139,14 +138,14 @@ struct UsdMayaPrimReaderRegistry /// prim.GetTypeName() /// \endcode MAYAUSD_CORE_PUBLIC - static ReaderFactoryFn - Find(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs); + static ReaderFactoryFn Find(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs); /// Similar to Find(), but returns a "fallback" prim reader factory if none /// can be found for \p usdTypeName. Thus, this always returns a valid /// reader factory. MAYAUSD_CORE_PUBLIC - static ReaderFactoryFn FindOrFallback(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs); + static ReaderFactoryFn + FindOrFallback(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs); }; // Lookup TfType by name instead of static C++ type when From 5cb14d7d0b44cf19f3afa5a062ac1a1388e2795f Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Fri, 16 Jun 2023 14:44:19 -0400 Subject: [PATCH 03/12] Update PrimReader Find function in PXR plugin --- plugin/pxr/maya/lib/usdMaya/readJob_ImportWithProxies.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/pxr/maya/lib/usdMaya/readJob_ImportWithProxies.cpp b/plugin/pxr/maya/lib/usdMaya/readJob_ImportWithProxies.cpp index b52535fb19..fa0dd245ee 100644 --- a/plugin/pxr/maya/lib/usdMaya/readJob_ImportWithProxies.cpp +++ b/plugin/pxr/maya/lib/usdMaya/readJob_ImportWithProxies.cpp @@ -260,7 +260,7 @@ bool UsdMaya_ReadJobWithSceneAssembly::_ProcessCameraPrims(const std::vectorRead(ctx); From 07cbd6ec33cfa1ccd90666d11724a4779e9d622b Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Tue, 20 Jun 2023 14:10:21 -0400 Subject: [PATCH 04/12] Remove Context supported related functions in Shader Reader --- lib/mayaUsd/fileio/shaderReader.cpp | 8 -------- lib/mayaUsd/fileio/shaderReader.h | 20 -------------------- 2 files changed, 28 deletions(-) diff --git a/lib/mayaUsd/fileio/shaderReader.cpp b/lib/mayaUsd/fileio/shaderReader.cpp index afb9631c79..400ec4cd51 100644 --- a/lib/mayaUsd/fileio/shaderReader.cpp +++ b/lib/mayaUsd/fileio/shaderReader.cpp @@ -35,14 +35,6 @@ UsdMayaShaderReader::UsdMayaShaderReader(const UsdMayaPrimReaderArgs& readArgs) { } -/* static */ -UsdMayaShaderReader::ContextSupport UsdMayaShaderReader::CanImport(const UsdMayaJobImportArgs&) -{ - // Default value for all readers is Fallback. More specialized writers can - // override the base CanImport to report Supported/Unsupported as necessary. - return ContextSupport::Fallback; -} - /* virtual */ MPlug UsdMayaShaderReader::GetMayaPlugForUsdAttrName( const TfToken& usdAttrName, diff --git a/lib/mayaUsd/fileio/shaderReader.h b/lib/mayaUsd/fileio/shaderReader.h index b6e2066a05..f24ee6494b 100644 --- a/lib/mayaUsd/fileio/shaderReader.h +++ b/lib/mayaUsd/fileio/shaderReader.h @@ -41,26 +41,6 @@ class UsdMayaShaderReader : public UsdMayaPrimReader MAYAUSD_CORE_PUBLIC UsdMayaShaderReader(const UsdMayaPrimReaderArgs&); - /* - /// The level of support a reader can offer for a given context - /// - /// A basic reader that gives correct results across most contexts should - /// report `Fallback`, while a specialized reader that really shines in a - /// given context should report `Supported` when the context is right and - /// `Unsupported` if the context is not as expected. - enum class ContextSupport - { - Supported, - Fallback, - Unsupported - }; - */ - - /// This static function is expected for all shader readers and allows - /// declaring how well this class can support the current context: - MAYAUSD_CORE_PUBLIC - static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); - /// Get the Maya shading plug on \p mayaObject that corresponds to the USD /// attribute named \p usdAttrName. /// From fb86b031074c292b4e52e4a3f653d8db91598cb1 Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Thu, 22 Jun 2023 23:26:04 -0400 Subject: [PATCH 05/12] Fix a typo in comment --- lib/mayaUsd/fileio/primReader.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mayaUsd/fileio/primReader.h b/lib/mayaUsd/fileio/primReader.h index 91fff3c130..72ca89716d 100644 --- a/lib/mayaUsd/fileio/primReader.h +++ b/lib/mayaUsd/fileio/primReader.h @@ -44,7 +44,7 @@ class UsdMayaPrimReader Unsupported }; - /// This static function is expected for all shader readers and allows + /// This static function is expected for all prim readers and allows /// declaring how well this class can support the current context: MAYAUSD_CORE_PUBLIC static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); From 086ba3511cb3bbe7527629ebfd21167cefac3ae2 Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Wed, 28 Jun 2023 13:11:29 -0400 Subject: [PATCH 06/12] Pass UsdPrim to PrimReader CanImport function to provide the ability to inspect the prim --- lib/mayaUsd/fileio/jobs/readJob.cpp | 2 +- lib/mayaUsd/fileio/primReader.cpp | 2 +- lib/mayaUsd/fileio/primReader.h | 2 +- lib/mayaUsd/fileio/primReaderRegistry.cpp | 25 +++++++++++-------- lib/mayaUsd/fileio/primReaderRegistry.h | 6 ++--- lib/mayaUsd/fileio/primUpdater.cpp | 2 +- lib/mayaUsd/fileio/shaderReader.cpp | 8 ++++++ lib/mayaUsd/fileio/shaderReader.h | 5 ++++ .../lib/usdMaya/readJob_ImportWithProxies.cpp | 2 +- 9 files changed, 36 insertions(+), 18 deletions(-) diff --git a/lib/mayaUsd/fileio/jobs/readJob.cpp b/lib/mayaUsd/fileio/jobs/readJob.cpp index 09c46fc3bd..fd31cdc80f 100644 --- a/lib/mayaUsd/fileio/jobs/readJob.cpp +++ b/lib/mayaUsd/fileio/jobs/readJob.cpp @@ -513,7 +513,7 @@ void UsdMaya_ReadJob::_DoImportPrimIt( TfToken typeName = prim.GetTypeName(); if (UsdMayaPrimReaderRegistry::ReaderFactoryFn factoryFn - = UsdMayaPrimReaderRegistry::FindOrFallback(typeName, mArgs)) { + = UsdMayaPrimReaderRegistry::FindOrFallback(typeName, mArgs, prim)) { UsdMayaPrimReaderSharedPtr primReader = factoryFn(args); if (primReader) { TempNodeTrackerScope scope(readCtx); diff --git a/lib/mayaUsd/fileio/primReader.cpp b/lib/mayaUsd/fileio/primReader.cpp index 4bc580efb6..675ead0868 100644 --- a/lib/mayaUsd/fileio/primReader.cpp +++ b/lib/mayaUsd/fileio/primReader.cpp @@ -23,7 +23,7 @@ UsdMayaPrimReader::UsdMayaPrimReader(const UsdMayaPrimReaderArgs& args) } /* static */ -UsdMayaPrimReader::ContextSupport UsdMayaPrimReader::CanImport(const UsdMayaJobImportArgs&) +UsdMayaPrimReader::ContextSupport UsdMayaPrimReader::CanImport(const UsdMayaJobImportArgs&, const UsdPrim& importPrim) { // Default value for all readers is Fallback. More specialized writers can // override the base CanImport to report Supported/Unsupported as necessary. diff --git a/lib/mayaUsd/fileio/primReader.h b/lib/mayaUsd/fileio/primReader.h index 72ca89716d..66ef3e4f5b 100644 --- a/lib/mayaUsd/fileio/primReader.h +++ b/lib/mayaUsd/fileio/primReader.h @@ -47,7 +47,7 @@ class UsdMayaPrimReader /// This static function is expected for all prim readers and allows /// declaring how well this class can support the current context: MAYAUSD_CORE_PUBLIC - static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); + static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs, const UsdPrim& importPrim); /// Reads the USD prim given by the prim reader args into a Maya shape, /// modifying the prim reader context as a result. diff --git a/lib/mayaUsd/fileio/primReaderRegistry.cpp b/lib/mayaUsd/fileio/primReaderRegistry.cpp index 655b0c729f..0ef32722bd 100644 --- a/lib/mayaUsd/fileio/primReaderRegistry.cpp +++ b/lib/mayaUsd/fileio/primReaderRegistry.cpp @@ -55,7 +55,8 @@ typedef std::unordered_multimap _ static _Registry _reg; static int _indexCounter = 0; -_Registry::const_iterator _Find(const TfToken& typeName, const UsdMayaJobImportArgs& importArgs) +_Registry::const_iterator +_Find(const TfToken& typeName, const UsdMayaJobImportArgs& importArgs, const UsdPrim& importPrim) { using ContextSupport = UsdMayaPrimReader::ContextSupport; @@ -64,7 +65,7 @@ _Registry::const_iterator _Find(const TfToken& typeName, const UsdMayaJobImportA std::tie(first, last) = _reg.equal_range(typeName); while (first != last) { - ContextSupport support = first->second._pred(importArgs); + ContextSupport support = first->second._pred(importArgs, importPrim); // Look for a "Supported" reader. If no "Supported" reader is found, use a "Fallback" reader if (support == ContextSupport::Supported) { ret = first; @@ -93,8 +94,9 @@ void UsdMayaPrimReaderRegistry::Register( // Use default ContextSupport if not specified _reg.insert(std::make_pair( tfTypeName, - _RegistryEntry { - [](const UsdMayaJobImportArgs&) { return UsdMayaPrimReader::ContextSupport::Fallback; }, + _RegistryEntry { [](const UsdMayaJobImportArgs&, const UsdPrim) { + return UsdMayaPrimReader::ContextSupport::Fallback; + }, fn, index })); @@ -152,8 +154,10 @@ void UsdMayaPrimReaderRegistry::RegisterRaw(const TfType& t, UsdMayaPrimReaderRe } /* static */ -UsdMayaPrimReaderRegistry::ReaderFactoryFn -UsdMayaPrimReaderRegistry::Find(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs) +UsdMayaPrimReaderRegistry::ReaderFactoryFn UsdMayaPrimReaderRegistry::Find( + const TfToken& usdTypeName, + const UsdMayaJobImportArgs& importArgs, + const UsdPrim& importPrim) { TfRegistryManager::GetInstance().SubscribeTo(); @@ -165,7 +169,7 @@ UsdMayaPrimReaderRegistry::Find(const TfToken& usdTypeName, const UsdMayaJobImpo ReaderFactoryFn ret = nullptr; // For that we are using unordered_multimap now, we can't use TfMapLookup anymore - _Registry::const_iterator it = _Find(typeName, importArgs); + _Registry::const_iterator it = _Find(typeName, importArgs, importPrim); if (it != _reg.end()) { return it->second._fn; @@ -182,7 +186,7 @@ UsdMayaPrimReaderRegistry::Find(const TfToken& usdTypeName, const UsdMayaJobImpo //_reg[typeName] = nullptr; Register( tfType, - [](const UsdMayaJobImportArgs&) { return UsdMayaPrimReader::ContextSupport::Fallback; }, + [](const UsdMayaJobImportArgs&, const UsdPrim&) { return UsdMayaPrimReader::ContextSupport::Fallback; }, nullptr); } @@ -192,9 +196,10 @@ UsdMayaPrimReaderRegistry::Find(const TfToken& usdTypeName, const UsdMayaJobImpo /* static */ UsdMayaPrimReaderRegistry::ReaderFactoryFn UsdMayaPrimReaderRegistry::FindOrFallback( const TfToken& usdTypeName, - const UsdMayaJobImportArgs& importArgs) + const UsdMayaJobImportArgs& importArgs, + const UsdPrim& importPrim) { - if (ReaderFactoryFn fn = Find(usdTypeName, importArgs)) { + if (ReaderFactoryFn fn = Find(usdTypeName, importArgs, importPrim)) { return fn; } diff --git a/lib/mayaUsd/fileio/primReaderRegistry.h b/lib/mayaUsd/fileio/primReaderRegistry.h index 18bddf2495..79e477264f 100644 --- a/lib/mayaUsd/fileio/primReaderRegistry.h +++ b/lib/mayaUsd/fileio/primReaderRegistry.h @@ -57,7 +57,7 @@ struct UsdMayaPrimReaderRegistry /// Predicate function, i.e. a function that can tell the level of support /// the reader function will provide for a given context. using ContextPredicateFn - = std::function; + = std::function; /// Reader function, i.e. a function that reads a prim. This is the /// signature of the function declared in the PXRUSDMAYA_DEFINE_READER @@ -138,14 +138,14 @@ struct UsdMayaPrimReaderRegistry /// prim.GetTypeName() /// \endcode MAYAUSD_CORE_PUBLIC - static ReaderFactoryFn Find(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs); + static ReaderFactoryFn Find(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs, const UsdPrim& importPrim); /// Similar to Find(), but returns a "fallback" prim reader factory if none /// can be found for \p usdTypeName. Thus, this always returns a valid /// reader factory. MAYAUSD_CORE_PUBLIC static ReaderFactoryFn - FindOrFallback(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs); + FindOrFallback(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs, const UsdPrim& importPrim); }; // Lookup TfType by name instead of static C++ type when diff --git a/lib/mayaUsd/fileio/primUpdater.cpp b/lib/mayaUsd/fileio/primUpdater.cpp index 0803c63a14..1b629f2e31 100644 --- a/lib/mayaUsd/fileio/primUpdater.cpp +++ b/lib/mayaUsd/fileio/primUpdater.cpp @@ -76,7 +76,7 @@ bool UsdMayaPrimUpdater::canEditAsMaya() const _context->GetUserArgs(), /* importWithProxyShapes = */ false, GfInterval::GetFullInterval()); - return (UsdMayaPrimReaderRegistry::Find(prim.GetTypeName(), jobArgs) != nullptr); + return (UsdMayaPrimReaderRegistry::Find(prim.GetTypeName(), jobArgs, prim) != nullptr); } bool UsdMayaPrimUpdater::editAsMaya() { return true; } diff --git a/lib/mayaUsd/fileio/shaderReader.cpp b/lib/mayaUsd/fileio/shaderReader.cpp index 400ec4cd51..afb9631c79 100644 --- a/lib/mayaUsd/fileio/shaderReader.cpp +++ b/lib/mayaUsd/fileio/shaderReader.cpp @@ -35,6 +35,14 @@ UsdMayaShaderReader::UsdMayaShaderReader(const UsdMayaPrimReaderArgs& readArgs) { } +/* static */ +UsdMayaShaderReader::ContextSupport UsdMayaShaderReader::CanImport(const UsdMayaJobImportArgs&) +{ + // Default value for all readers is Fallback. More specialized writers can + // override the base CanImport to report Supported/Unsupported as necessary. + return ContextSupport::Fallback; +} + /* virtual */ MPlug UsdMayaShaderReader::GetMayaPlugForUsdAttrName( const TfToken& usdAttrName, diff --git a/lib/mayaUsd/fileio/shaderReader.h b/lib/mayaUsd/fileio/shaderReader.h index f24ee6494b..1411c63fad 100644 --- a/lib/mayaUsd/fileio/shaderReader.h +++ b/lib/mayaUsd/fileio/shaderReader.h @@ -41,6 +41,11 @@ class UsdMayaShaderReader : public UsdMayaPrimReader MAYAUSD_CORE_PUBLIC UsdMayaShaderReader(const UsdMayaPrimReaderArgs&); + /// This static function is expected for all shader readers and allows + /// declaring how well this class can support the current context: + MAYAUSD_CORE_PUBLIC + static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); + /// Get the Maya shading plug on \p mayaObject that corresponds to the USD /// attribute named \p usdAttrName. /// diff --git a/plugin/pxr/maya/lib/usdMaya/readJob_ImportWithProxies.cpp b/plugin/pxr/maya/lib/usdMaya/readJob_ImportWithProxies.cpp index fa0dd245ee..5df33ff309 100644 --- a/plugin/pxr/maya/lib/usdMaya/readJob_ImportWithProxies.cpp +++ b/plugin/pxr/maya/lib/usdMaya/readJob_ImportWithProxies.cpp @@ -260,7 +260,7 @@ bool UsdMaya_ReadJobWithSceneAssembly::_ProcessCameraPrims(const std::vectorRead(ctx); From 1c02b6e66b3a3fe94d81ccea86c00095bdaa37d9 Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Thu, 29 Jun 2023 11:43:58 -0400 Subject: [PATCH 07/12] Clang format fix --- lib/mayaUsd/fileio/primReader.cpp | 3 ++- lib/mayaUsd/fileio/primReader.h | 3 ++- lib/mayaUsd/fileio/primReaderRegistry.cpp | 8 +++++--- lib/mayaUsd/fileio/primReaderRegistry.h | 15 ++++++++++----- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/lib/mayaUsd/fileio/primReader.cpp b/lib/mayaUsd/fileio/primReader.cpp index 675ead0868..785997a3f9 100644 --- a/lib/mayaUsd/fileio/primReader.cpp +++ b/lib/mayaUsd/fileio/primReader.cpp @@ -23,7 +23,8 @@ UsdMayaPrimReader::UsdMayaPrimReader(const UsdMayaPrimReaderArgs& args) } /* static */ -UsdMayaPrimReader::ContextSupport UsdMayaPrimReader::CanImport(const UsdMayaJobImportArgs&, const UsdPrim& importPrim) +UsdMayaPrimReader::ContextSupport +UsdMayaPrimReader::CanImport(const UsdMayaJobImportArgs&, const UsdPrim& importPrim) { // Default value for all readers is Fallback. More specialized writers can // override the base CanImport to report Supported/Unsupported as necessary. diff --git a/lib/mayaUsd/fileio/primReader.h b/lib/mayaUsd/fileio/primReader.h index 66ef3e4f5b..6826d773b2 100644 --- a/lib/mayaUsd/fileio/primReader.h +++ b/lib/mayaUsd/fileio/primReader.h @@ -47,7 +47,8 @@ class UsdMayaPrimReader /// This static function is expected for all prim readers and allows /// declaring how well this class can support the current context: MAYAUSD_CORE_PUBLIC - static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs, const UsdPrim& importPrim); + static ContextSupport + CanImport(const UsdMayaJobImportArgs& importArgs, const UsdPrim& importPrim); /// Reads the USD prim given by the prim reader args into a Maya shape, /// modifying the prim reader context as a result. diff --git a/lib/mayaUsd/fileio/primReaderRegistry.cpp b/lib/mayaUsd/fileio/primReaderRegistry.cpp index 0ef32722bd..df65024079 100644 --- a/lib/mayaUsd/fileio/primReaderRegistry.cpp +++ b/lib/mayaUsd/fileio/primReaderRegistry.cpp @@ -97,8 +97,8 @@ void UsdMayaPrimReaderRegistry::Register( _RegistryEntry { [](const UsdMayaJobImportArgs&, const UsdPrim) { return UsdMayaPrimReader::ContextSupport::Fallback; }, - fn, - index })); + fn, + index })); if (fn) { UsdMaya_RegistryHelper::AddUnloader( @@ -186,7 +186,9 @@ UsdMayaPrimReaderRegistry::ReaderFactoryFn UsdMayaPrimReaderRegistry::Find( //_reg[typeName] = nullptr; Register( tfType, - [](const UsdMayaJobImportArgs&, const UsdPrim&) { return UsdMayaPrimReader::ContextSupport::Fallback; }, + [](const UsdMayaJobImportArgs&, const UsdPrim&) { + return UsdMayaPrimReader::ContextSupport::Fallback; + }, nullptr); } diff --git a/lib/mayaUsd/fileio/primReaderRegistry.h b/lib/mayaUsd/fileio/primReaderRegistry.h index 79e477264f..d42135752e 100644 --- a/lib/mayaUsd/fileio/primReaderRegistry.h +++ b/lib/mayaUsd/fileio/primReaderRegistry.h @@ -56,8 +56,8 @@ struct UsdMayaPrimReaderRegistry /// Predicate function, i.e. a function that can tell the level of support /// the reader function will provide for a given context. - using ContextPredicateFn - = std::function; + using ContextPredicateFn = std::function< + UsdMayaPrimReader::ContextSupport(const UsdMayaJobImportArgs&, const UsdPrim&)>; /// Reader function, i.e. a function that reads a prim. This is the /// signature of the function declared in the PXRUSDMAYA_DEFINE_READER @@ -138,14 +138,19 @@ struct UsdMayaPrimReaderRegistry /// prim.GetTypeName() /// \endcode MAYAUSD_CORE_PUBLIC - static ReaderFactoryFn Find(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs, const UsdPrim& importPrim); + static ReaderFactoryFn Find( + const TfToken& usdTypeName, + const UsdMayaJobImportArgs& importArgs, + const UsdPrim& importPrim); /// Similar to Find(), but returns a "fallback" prim reader factory if none /// can be found for \p usdTypeName. Thus, this always returns a valid /// reader factory. MAYAUSD_CORE_PUBLIC - static ReaderFactoryFn - FindOrFallback(const TfToken& usdTypeName, const UsdMayaJobImportArgs& importArgs, const UsdPrim& importPrim); + static ReaderFactoryFn FindOrFallback( + const TfToken& usdTypeName, + const UsdMayaJobImportArgs& importArgs, + const UsdPrim& importPrim); }; // Lookup TfType by name instead of static C++ type when From 7aeec0feb67aad147f92d3057be250f375615dbc Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Wed, 5 Jul 2023 13:32:28 -0400 Subject: [PATCH 08/12] Code clean up --- lib/mayaUsd/fileio/primReaderRegistry.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/mayaUsd/fileio/primReaderRegistry.cpp b/lib/mayaUsd/fileio/primReaderRegistry.cpp index df65024079..276d89d05e 100644 --- a/lib/mayaUsd/fileio/primReaderRegistry.cpp +++ b/lib/mayaUsd/fileio/primReaderRegistry.cpp @@ -183,7 +183,6 @@ UsdMayaPrimReaderRegistry::ReaderFactoryFn UsdMayaPrimReaderRegistry::Find( if (_reg.count(typeName) == 0) { TF_DEBUG(PXRUSDMAYA_REGISTRY) .Msg("No usdMaya reader plugin for TfType %s. No maya plugin.\n", typeName.GetText()); - //_reg[typeName] = nullptr; Register( tfType, [](const UsdMayaJobImportArgs&, const UsdPrim&) { From 96e3e55cfea5d020847ce77d9cb69b667fe966bf Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Thu, 6 Jul 2023 15:26:08 -0400 Subject: [PATCH 09/12] Add context support and new register function to prim reader python wrapper --- lib/mayaUsd/python/wrapPrimReader.cpp | 40 +++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/lib/mayaUsd/python/wrapPrimReader.cpp b/lib/mayaUsd/python/wrapPrimReader.cpp index 0475221777..a084865899 100644 --- a/lib/mayaUsd/python/wrapPrimReader.cpp +++ b/lib/mayaUsd/python/wrapPrimReader.cpp @@ -112,6 +112,25 @@ class PrimReaderWrapper return sptr; } + UsdMayaPrimReader::ContextSupport + operator()(const UsdMayaJobImportArgs& args, const UsdPrim& importPrim) + { + boost::python::object pyClass = GetPythonObject(_classIndex); + if (!pyClass) { + // Prototype was unregistered + return UsdMayaPrimReader::ContextSupport::Unsupported; + } + TfPyLock pyLock; + if (PyObject_HasAttrString(pyClass.ptr(), "CanImport")) { + boost::python::object CanImport = pyClass.attr("CanImport"); + PyObject* callable = CanImport.ptr(); + auto res = boost::python::call(callable, args); + return UsdMayaPrimReader::ContextSupport(res); + } else { + return UsdMayaPrimReader::CanImport(args, importPrim); + } + } + // Create a new wrapper for a Python class that is seen for the first time for a given // purpose. If we already have a registration for this purpose: update the class to // allow the previously issued factory function to use it. @@ -150,12 +169,20 @@ class PrimReaderWrapper } }; - static void Register(boost::python::object cl, const std::string& typeName) + static void Register( + boost::python::object cl, + const std::string& typeName, + const UsdMayaPrimReaderRegistry::ContextPredicateFn pred = nullptr) { UsdMayaPrimReaderRegistry::ReaderFactoryFn fn = FactoryFnWrapper::Register(cl, typeName); if (fn) { auto type = TfType::FindByName(typeName); - UsdMayaPrimReaderRegistry::Register(type, fn, true); + // If no context support is provided, use the default register function + if (pred) { + UsdMayaPrimReaderRegistry::Register(type, pred, fn, true); + } else { + UsdMayaPrimReaderRegistry::Register(type, fn, true); + } } } @@ -499,11 +526,20 @@ void wrapPrimReaderArgs() .def("GetUseAsAnimationCache", &UsdMayaPrimReaderArgs::GetUseAsAnimationCache); } +TF_REGISTRY_FUNCTION(TfEnum) +{ + TF_ADD_ENUM_NAME(UsdMayaPrimReader::ContextSupport::Supported, "Supported"); + TF_ADD_ENUM_NAME(UsdMayaPrimReader::ContextSupport::Fallback, "Fallback"); + TF_ADD_ENUM_NAME(UsdMayaPrimReader::ContextSupport::Unsupported, "Unsupported"); +} + void wrapPrimReader() { using namespace boost::python; typedef UsdMayaPrimReader This; + TfPyWrapEnum(); + class_, boost::noncopyable>("PrimReader", no_init) .def("__init__", make_constructor(&PrimReaderWrapper<>::New)) .def("Read", pure_virtual(&UsdMayaPrimReader::Read)) From aa315a10d324ec88af734ad785b2cdca4893bd3d Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Thu, 6 Jul 2023 16:25:36 -0400 Subject: [PATCH 10/12] Remove shader reader context support enum in python wrapper --- lib/mayaUsd/python/wrapPrimReader.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/lib/mayaUsd/python/wrapPrimReader.cpp b/lib/mayaUsd/python/wrapPrimReader.cpp index a084865899..05ab16a6af 100644 --- a/lib/mayaUsd/python/wrapPrimReader.cpp +++ b/lib/mayaUsd/python/wrapPrimReader.cpp @@ -558,13 +558,6 @@ void wrapPrimReader() .staticmethod("Unregister"); } -TF_REGISTRY_FUNCTION(TfEnum) -{ - TF_ADD_ENUM_NAME(UsdMayaShaderReader::ContextSupport::Supported, "Supported"); - TF_ADD_ENUM_NAME(UsdMayaShaderReader::ContextSupport::Fallback, "Fallback"); - TF_ADD_ENUM_NAME(UsdMayaShaderReader::ContextSupport::Unsupported, "Unsupported"); -} - //---------------------------------------------------------------------------------------------------------------------- void wrapShaderReader() { From 18370b3750b17eb0a2d25668827d9b67b018de30 Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Fri, 7 Jul 2023 18:31:39 -0400 Subject: [PATCH 11/12] Fix issues in PrimReader python wrapper and update ShaderReader unit test --- lib/mayaUsd/fileio/shaderReader.cpp | 2 +- lib/mayaUsd/fileio/shaderReaderRegistry.cpp | 4 +- lib/mayaUsd/fileio/shaderReaderRegistry.h | 2 +- .../fileio/shading/symmetricShaderReader.cpp | 2 +- lib/mayaUsd/python/wrapPrimReader.cpp | 51 ++++++++----------- .../shading/mtlxSymmetricShaderReader.cpp | 2 +- .../translators/shading/usdBlinnReader.cpp | 2 +- test/lib/mayaUsd/fileio/testShaderReader.py | 2 +- 8 files changed, 29 insertions(+), 38 deletions(-) diff --git a/lib/mayaUsd/fileio/shaderReader.cpp b/lib/mayaUsd/fileio/shaderReader.cpp index afb9631c79..497537889e 100644 --- a/lib/mayaUsd/fileio/shaderReader.cpp +++ b/lib/mayaUsd/fileio/shaderReader.cpp @@ -36,7 +36,7 @@ UsdMayaShaderReader::UsdMayaShaderReader(const UsdMayaPrimReaderArgs& readArgs) } /* static */ -UsdMayaShaderReader::ContextSupport UsdMayaShaderReader::CanImport(const UsdMayaJobImportArgs&) +UsdMayaPrimReader::ContextSupport UsdMayaShaderReader::CanImport(const UsdMayaJobImportArgs&) { // Default value for all readers is Fallback. More specialized writers can // override the base CanImport to report Supported/Unsupported as necessary. diff --git a/lib/mayaUsd/fileio/shaderReaderRegistry.cpp b/lib/mayaUsd/fileio/shaderReaderRegistry.cpp index 410baf48c9..1d932d6517 100644 --- a/lib/mayaUsd/fileio/shaderReaderRegistry.cpp +++ b/lib/mayaUsd/fileio/shaderReaderRegistry.cpp @@ -57,7 +57,7 @@ static int _ _Registry::const_iterator _Find(const TfToken& usdInfoId, const UsdMayaJobImportArgs& importArgs) { - using ContextSupport = UsdMayaShaderReader::ContextSupport; + using ContextSupport = UsdMayaPrimReader::ContextSupport; _Registry::const_iterator ret = _reg.cend(); _Registry::const_iterator first, last; @@ -120,7 +120,7 @@ void UsdMayaShaderReaderRegistry::Register( UsdMayaShaderReaderRegistry::ReaderFactoryFn UsdMayaShaderReaderRegistry::Find(const TfToken& usdInfoId, const UsdMayaJobImportArgs& importArgs) { - using ContextSupport = UsdMayaShaderReader::ContextSupport; + using ContextSupport = UsdMayaPrimReader::ContextSupport; TfRegistryManager::GetInstance().SubscribeTo(); _Registry::const_iterator it = _Find(usdInfoId, importArgs); diff --git a/lib/mayaUsd/fileio/shaderReaderRegistry.h b/lib/mayaUsd/fileio/shaderReaderRegistry.h index 76027377c1..0b1ab22887 100644 --- a/lib/mayaUsd/fileio/shaderReaderRegistry.h +++ b/lib/mayaUsd/fileio/shaderReaderRegistry.h @@ -75,7 +75,7 @@ struct UsdMayaShaderReaderRegistry /// Predicate function, i.e. a function that can tell the level of support /// the reader function will provide for a given context. using ContextPredicateFn - = std::function; + = std::function; /// Reader factory function, i.e. a function that creates a prim reader /// for the given prim reader args. diff --git a/lib/mayaUsd/fileio/shading/symmetricShaderReader.cpp b/lib/mayaUsd/fileio/shading/symmetricShaderReader.cpp index a86ceb8cd4..ce841edca9 100644 --- a/lib/mayaUsd/fileio/shading/symmetricShaderReader.cpp +++ b/lib/mayaUsd/fileio/shading/symmetricShaderReader.cpp @@ -74,7 +74,7 @@ void UsdMayaSymmetricShaderReader::RegisterReader( } /* static */ -UsdMayaShaderReader::ContextSupport UsdMayaSymmetricShaderReader::CanImport( +UsdMayaPrimReader::ContextSupport UsdMayaSymmetricShaderReader::CanImport( const UsdMayaJobImportArgs& importArgs, const TfToken& materialConversion) { diff --git a/lib/mayaUsd/python/wrapPrimReader.cpp b/lib/mayaUsd/python/wrapPrimReader.cpp index 05ab16a6af..b372449d21 100644 --- a/lib/mayaUsd/python/wrapPrimReader.cpp +++ b/lib/mayaUsd/python/wrapPrimReader.cpp @@ -124,7 +124,7 @@ class PrimReaderWrapper if (PyObject_HasAttrString(pyClass.ptr(), "CanImport")) { boost::python::object CanImport = pyClass.attr("CanImport"); PyObject* callable = CanImport.ptr(); - auto res = boost::python::call(callable, args); + auto res = boost::python::call(callable, args, importPrim); return UsdMayaPrimReader::ContextSupport(res); } else { return UsdMayaPrimReader::CanImport(args, importPrim); @@ -134,17 +134,13 @@ class PrimReaderWrapper // Create a new wrapper for a Python class that is seen for the first time for a given // purpose. If we already have a registration for this purpose: update the class to // allow the previously issued factory function to use it. - static UsdMayaPrimReaderRegistry::ReaderFactoryFn - Register(boost::python::object cl, const std::string& typeName) + static FactoryFnWrapper + Register(boost::python::object cl, const std::string& typeName, bool& updated) { size_t classIndex = RegisterPythonObject(cl, GetKey(cl, typeName)); - if (classIndex != UsdMayaPythonObjectRegistry::UPDATED) { - // Return a new factory function: - return FactoryFnWrapper { classIndex }; - } else { - // We already registered a factory function for this purpose: - return nullptr; - } + updated = classIndex == UsdMayaPythonObjectRegistry::UPDATED; + // Return a new factory function: + return FactoryFnWrapper { classIndex }; } // Unregister a class for a given purpose. This will cause the associated factory @@ -169,20 +165,14 @@ class PrimReaderWrapper } }; - static void Register( - boost::python::object cl, - const std::string& typeName, - const UsdMayaPrimReaderRegistry::ContextPredicateFn pred = nullptr) + static void Register(boost::python::object cl, const std::string& typeName) { - UsdMayaPrimReaderRegistry::ReaderFactoryFn fn = FactoryFnWrapper::Register(cl, typeName); - if (fn) { + bool updated = false; + FactoryFnWrapper fn + = FactoryFnWrapper::Register(cl, typeName, updated); + if (!updated) { auto type = TfType::FindByName(typeName); - // If no context support is provided, use the default register function - if (pred) { - UsdMayaPrimReaderRegistry::Register(type, pred, fn, true); - } else { - UsdMayaPrimReaderRegistry::Register(type, fn, true); - } + UsdMayaPrimReaderRegistry::Register(type, fn, fn, true); } } @@ -324,20 +314,20 @@ class ShaderReaderWrapper : public PrimReaderWrapper return sptr; } - // We can have multiple function objects, this one apapts the CanImport function: - UsdMayaShaderReader::ContextSupport operator()(const UsdMayaJobImportArgs& args) + // We can have multiple function objects, this one adapts the CanImport function: + UsdMayaPrimReader::ContextSupport operator()(const UsdMayaJobImportArgs& args) { boost::python::object pyClass = GetPythonObject(_classIndex); if (!pyClass) { // Prototype was unregistered - return UsdMayaShaderReader::ContextSupport::Unsupported; + return UsdMayaPrimReader::ContextSupport::Unsupported; } TfPyLock pyLock; if (PyObject_HasAttrString(pyClass.ptr(), "CanImport")) { boost::python::object CanImport = pyClass.attr("CanImport"); PyObject* callable = CanImport.ptr(); auto res = boost::python::call(callable, args); - return UsdMayaShaderReader::ContextSupport(res); + return UsdMayaPrimReader::ContextSupport(res); } else { return UsdMayaShaderReader::CanImport(args); } @@ -538,10 +528,13 @@ void wrapPrimReader() using namespace boost::python; typedef UsdMayaPrimReader This; + class_, boost::noncopyable> c("PrimReader", no_init); + + scope s(c); + TfPyWrapEnum(); - class_, boost::noncopyable>("PrimReader", no_init) - .def("__init__", make_constructor(&PrimReaderWrapper<>::New)) + c.def("__init__", make_constructor(&PrimReaderWrapper<>::New)) .def("Read", pure_virtual(&UsdMayaPrimReader::Read)) .def( "HasPostReadSubtree", @@ -569,8 +562,6 @@ void wrapShaderReader() scope s(c); - TfPyWrapEnum(); - c.def("__init__", make_constructor(&ShaderReaderWrapper::New)) .def("Read", pure_virtual(&UsdMayaPrimReader::Read)) .def( diff --git a/lib/usd/translators/shading/mtlxSymmetricShaderReader.cpp b/lib/usd/translators/shading/mtlxSymmetricShaderReader.cpp index 4ed3d21650..bc1892b48a 100644 --- a/lib/usd/translators/shading/mtlxSymmetricShaderReader.cpp +++ b/lib/usd/translators/shading/mtlxSymmetricShaderReader.cpp @@ -138,7 +138,7 @@ TF_REGISTRY_FUNCTION(UsdMayaShaderReaderRegistry) }; /* static */ -UsdMayaShaderReader::ContextSupport +UsdMayaPrimReader::ContextSupport MtlxUsd_SymmetricShaderReader::CanImport(const UsdMayaJobImportArgs& importArgs) { if (importArgs.GetMaterialConversion() == TrMtlxTokens->conversionName) { diff --git a/lib/usd/translators/shading/usdBlinnReader.cpp b/lib/usd/translators/shading/usdBlinnReader.cpp index 74881ef5bb..f557dffdf2 100644 --- a/lib/usd/translators/shading/usdBlinnReader.cpp +++ b/lib/usd/translators/shading/usdBlinnReader.cpp @@ -78,7 +78,7 @@ PxrUsdTranslators_BlinnReader::PxrUsdTranslators_BlinnReader(const UsdMayaPrimRe } /* static */ -UsdMayaShaderReader::ContextSupport +UsdMayaPrimReader::ContextSupport PxrUsdTranslators_BlinnReader::CanImport(const UsdMayaJobImportArgs& importArgs) { return importArgs.preferredMaterial == UsdMayaPreferredMaterialTokens->blinn diff --git a/test/lib/mayaUsd/fileio/testShaderReader.py b/test/lib/mayaUsd/fileio/testShaderReader.py index 82819b4974..ad19ad0970 100644 --- a/test/lib/mayaUsd/fileio/testShaderReader.py +++ b/test/lib/mayaUsd/fileio/testShaderReader.py @@ -40,7 +40,7 @@ class mtlxShaderReaderTest(mayaUsdLib.ShaderReader): @classmethod def CanImport(cls, args): - return cls.ContextSupport.Supported + return mayaUsdLib.PrimReader.ContextSupport.Supported def IsConverter(self): mtlxShaderReaderTest.IsConverterCalled = True From 8e594397cf060b211cad34b5c47c206366d25ef4 Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Fri, 7 Jul 2023 19:04:57 -0400 Subject: [PATCH 12/12] Clang format fix --- lib/mayaUsd/python/wrapPrimReader.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/mayaUsd/python/wrapPrimReader.cpp b/lib/mayaUsd/python/wrapPrimReader.cpp index b372449d21..b00ff54bbb 100644 --- a/lib/mayaUsd/python/wrapPrimReader.cpp +++ b/lib/mayaUsd/python/wrapPrimReader.cpp @@ -168,8 +168,7 @@ class PrimReaderWrapper static void Register(boost::python::object cl, const std::string& typeName) { bool updated = false; - FactoryFnWrapper fn - = FactoryFnWrapper::Register(cl, typeName, updated); + FactoryFnWrapper fn = FactoryFnWrapper::Register(cl, typeName, updated); if (!updated) { auto type = TfType::FindByName(typeName); UsdMayaPrimReaderRegistry::Register(type, fn, fn, true);