From 55b97a9dd9e2d7d922ca98e01305dfb3fb880f0e Mon Sep 17 00:00:00 2001 From: Samuel Liu Date: Wed, 31 Jan 2024 15:38:25 -0500 Subject: [PATCH] Make calling CanExport() per object if multiple writers --- lib/mayaUsd/fileio/primWriterRegistry.cpp | 6 ++++ lib/mayaUsd/fileio/primWriterRegistry.h | 37 +++++++++++++++++++++++ lib/mayaUsd/fileio/writeJobContext.cpp | 5 ++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/lib/mayaUsd/fileio/primWriterRegistry.cpp b/lib/mayaUsd/fileio/primWriterRegistry.cpp index 5ee4ffa6d0..8cf006b65f 100644 --- a/lib/mayaUsd/fileio/primWriterRegistry.cpp +++ b/lib/mayaUsd/fileio/primWriterRegistry.cpp @@ -83,6 +83,12 @@ _Registry::const_iterator _Find( } // namespace +/* static */ +bool UsdMayaPrimWriterRegistry::HasMultipleWriters(const std::string& mayaTypeName) +{ + return _reg.count(mayaTypeName) > 1; +} + /* static */ void UsdMayaPrimWriterRegistry::Register( const std::string& mayaTypeName, diff --git a/lib/mayaUsd/fileio/primWriterRegistry.h b/lib/mayaUsd/fileio/primWriterRegistry.h index 73a823573a..4623fca1ec 100644 --- a/lib/mayaUsd/fileio/primWriterRegistry.h +++ b/lib/mayaUsd/fileio/primWriterRegistry.h @@ -82,6 +82,11 @@ struct UsdMayaPrimWriterRegistry using ContextPredicateFn = std::function< UsdMayaPrimWriter::ContextSupport(const UsdMayaJobExportArgs&, const MObject&)>; + // Return true if this mayaTypeName has multiple writers registered. + // In that case, call the Find function each time to find the correct writer for that object. + MAYAUSD_CORE_PUBLIC + static bool HasMultipleWriters(const std::string& mayaTypeName); + /// \brief Register \p fn as a factory function providing a /// UsdMayaPrimWriter subclass that can be used to write \p mayaType. /// Provide a supportability of the primWriter. Use "supported" to @@ -235,6 +240,38 @@ struct UsdMayaPrimWriterRegistry }); \ } +/// \brief Registers a custom pre-existing writer class for the given Maya type; +/// the writer class should be a subclass of UsdMayaPrimWriter with a three-place +/// constructor that takes (const MFnDependencyNode& depNodeFn, +/// const SdfPath& usdPath, UsdMayaWriteJobContext& jobCtx) as arguments. +/// Use CanExport(const UsdMayaJobExportArgs& exportArgs, const MObject& exportObj) function to +/// return the level of support the writer can offer for a given context. +/// +/// Example: +/// \code{.cpp} +/// class MyWriter : public UsdMayaPrimWriter { +/// MyWriter( +/// const MFnDependencyNode& depNodeFn, +/// const SdfPath& usdPath, +/// UsdMayaWriteJobContext& jobCtx) { +/// // ... +/// } +/// }; +/// PXRUSDMAYA_REGISTER_CUSTOM_WRITER(myCustomMayaNode, MyWriter); +/// \endcode +#define PXRUSDMAYA_REGISTER_CUSTOM_WRITER(mayaTypeName, writerClass) \ + TF_REGISTRY_FUNCTION_WITH_TAG(UsdMayaPrimWriterRegistry, mayaTypeName##_##writerClass) \ + { \ + UsdMayaPrimWriterRegistry::Register( \ + #mayaTypeName, \ + writerClass::CanExport, \ + [](const MFnDependencyNode& depNodeFn, \ + const SdfPath& usdPath, \ + UsdMayaWriteJobContext& jobCtx) { \ + return std::make_shared(depNodeFn, usdPath, jobCtx); \ + }); \ + } + PXR_NAMESPACE_CLOSE_SCOPE #endif diff --git a/lib/mayaUsd/fileio/writeJobContext.cpp b/lib/mayaUsd/fileio/writeJobContext.cpp index b2da0f5c0c..2142121a28 100644 --- a/lib/mayaUsd/fileio/writeJobContext.cpp +++ b/lib/mayaUsd/fileio/writeJobContext.cpp @@ -590,8 +590,11 @@ UsdMayaWriteJobContext::_FindWriter(const MFnDependencyNode& mayaNode) const std::string mayaNodeType(mayaNode.typeName().asChar()); // Check if type is already cached locally. + // If this type has multiple writers, we need to call CanExport again to determine which writer + // to use auto iter = mWriterFactoryCache.find(mayaNodeType); - if (iter != mWriterFactoryCache.end()) { + if (iter != mWriterFactoryCache.end() + && !UsdMayaPrimWriterRegistry::HasMultipleWriters(mayaNodeType)) { return iter->second; }