From 705425f6b99c244d1a0ea661d279a5232f239922 Mon Sep 17 00:00:00 2001 From: JGamache-autodesk Date: Wed, 12 Aug 2020 16:48:04 -0400 Subject: [PATCH 1/3] MAYA-104987 Allows converting preview surface to Maya native shaders Also allows converting displayColor to other Maya shader nodes. --- lib/mayaUsd/commands/baseImportCommand.cpp | 3 + lib/mayaUsd/commands/baseImportCommand.h | 1 + lib/mayaUsd/fileio/jobs/jobArgs.cpp | 8 + lib/mayaUsd/fileio/jobs/jobArgs.h | 2 + lib/mayaUsd/fileio/shaderReader.cpp | 8 + lib/mayaUsd/fileio/shaderReader.h | 13 ++ lib/mayaUsd/fileio/shaderReaderRegistry.cpp | 97 +++++++--- lib/mayaUsd/fileio/shaderReaderRegistry.h | 35 ++-- .../shading/shadingModeDisplayColor.cpp | 181 ++++++++++++------ .../fileio/shading/shadingModeRegistry.cpp | 3 + .../fileio/shading/shadingModeRegistry.h | 11 ++ .../fileio/shading/shadingModeUseRegistry.cpp | 2 +- lib/mayaUsd/utils/util.cpp | 39 +++- .../usdPreviewSurfaceReader.cpp | 5 - lib/usd/translators/shading/CMakeLists.txt | 14 +- .../translators/shading/usdBlinnReader.cpp | 134 +++++++++++++ .../translators/shading/usdLambertReader.cpp | 118 ++++++++++++ .../translators/shading/usdLambertReader.h | 50 +++++ .../translators/shading/usdLambertWriter.cpp | 7 +- .../translators/shading/usdMaterialReader.cpp | 136 +++++++++++++ .../translators/shading/usdMaterialReader.h | 62 ++++++ .../translators/shading/usdPhongEReader.cpp | 115 +++++++++++ .../translators/shading/usdPhongReader.cpp | 128 +++++++++++++ .../shading/usdStandardSurfaceReader.cpp | 177 +++++++++++++++++ .../shading/usdStandardSurfaceWriter.cpp | 5 +- .../shading/usdUVTextureReader.cpp | 2 +- .../adsk/scripts/mayaUsdTranslatorImport.mel | 16 ++ plugin/pxr/doc/README.md | 3 +- ...tUsdExportImportRoundtripPreviewSurface.py | 5 +- .../testUsdImportPreviewSurface.py | 18 +- 30 files changed, 1289 insertions(+), 109 deletions(-) create mode 100644 lib/usd/translators/shading/usdBlinnReader.cpp create mode 100644 lib/usd/translators/shading/usdLambertReader.cpp create mode 100644 lib/usd/translators/shading/usdLambertReader.h create mode 100644 lib/usd/translators/shading/usdMaterialReader.cpp create mode 100644 lib/usd/translators/shading/usdMaterialReader.h create mode 100644 lib/usd/translators/shading/usdPhongEReader.cpp create mode 100644 lib/usd/translators/shading/usdPhongReader.cpp create mode 100644 lib/usd/translators/shading/usdStandardSurfaceReader.cpp diff --git a/lib/mayaUsd/commands/baseImportCommand.cpp b/lib/mayaUsd/commands/baseImportCommand.cpp index af8205e114..9e7aaa4178 100644 --- a/lib/mayaUsd/commands/baseImportCommand.cpp +++ b/lib/mayaUsd/commands/baseImportCommand.cpp @@ -45,6 +45,9 @@ MayaUSDImportCommand::createSyntax() syntax.addFlag(kShadingModeFlag, UsdMayaJobImportArgsTokens->shadingMode.GetText(), MSyntax::kString); + syntax.addFlag(kShadingConversionFlag, + UsdMayaJobImportArgsTokens->shadingConversion.GetText(), + MSyntax::kString); syntax.addFlag(kAssemblyRepFlag, UsdMayaJobImportArgsTokens->assemblyRep.GetText(), MSyntax::kString); diff --git a/lib/mayaUsd/commands/baseImportCommand.h b/lib/mayaUsd/commands/baseImportCommand.h index 683a74a9fd..ea4179bdb1 100644 --- a/lib/mayaUsd/commands/baseImportCommand.h +++ b/lib/mayaUsd/commands/baseImportCommand.h @@ -42,6 +42,7 @@ class MAYAUSD_CORE_PUBLIC MayaUSDImportCommand : public MPxCommand // // The list of short forms of flags defined as Arg Tokens: static constexpr auto kShadingModeFlag = "shd"; + static constexpr auto kShadingConversionFlag = "shc"; static constexpr auto kAssemblyRepFlag = "ar"; static constexpr auto kMetadataFlag = "md"; static constexpr auto kApiSchemaFlag = "api"; diff --git a/lib/mayaUsd/fileio/jobs/jobArgs.cpp b/lib/mayaUsd/fileio/jobs/jobArgs.cpp index 5b71d4eb82..21b1f35a18 100644 --- a/lib/mayaUsd/fileio/jobs/jobArgs.cpp +++ b/lib/mayaUsd/fileio/jobs/jobArgs.cpp @@ -561,6 +561,11 @@ UsdMayaJobImportArgs::UsdMayaJobImportArgs( UsdMayaJobImportArgsTokens->shadingMode, UsdMayaShadingModeTokens->none, UsdMayaShadingModeRegistry::ListImporters())), + shadingConversion( + _Token(userArgs, + UsdMayaJobImportArgsTokens->shadingConversion, + UsdMayaShadingConversionTokens->none, + UsdMayaShadingConversionTokens->allTokens)), useAsAnimationCache( _Boolean(userArgs, UsdMayaJobImportArgsTokens->useAsAnimationCache)), @@ -601,6 +606,8 @@ const VtDictionary& UsdMayaJobImportArgs::GetDefaultDictionary() }); d[UsdMayaJobImportArgsTokens->shadingMode] = UsdMayaShadingModeTokens->displayColor.GetString(); + d[UsdMayaJobImportArgsTokens->shadingConversion] = + UsdMayaShadingConversionTokens->lambert.GetString(); d[UsdMayaJobImportArgsTokens->useAsAnimationCache] = false; // plugInfo.json site defaults. @@ -619,6 +626,7 @@ std::ostream& operator <<(std::ostream& out, const UsdMayaJobImportArgs& importArgs) { out << "shadingMode: " << importArgs.shadingMode << std::endl + << "shadingConversion: " << importArgs.shadingConversion << std::endl << "assemblyRep: " << importArgs.assemblyRep << std::endl << "timeInterval: " << importArgs.timeInterval << std::endl << "useAsAnimationCache: " << TfStringify(importArgs.useAsAnimationCache) << std::endl diff --git a/lib/mayaUsd/fileio/jobs/jobArgs.h b/lib/mayaUsd/fileio/jobs/jobArgs.h index dedd70d210..c87851360c 100644 --- a/lib/mayaUsd/fileio/jobs/jobArgs.h +++ b/lib/mayaUsd/fileio/jobs/jobArgs.h @@ -106,6 +106,7 @@ TF_DECLARE_PUBLIC_TOKENS( (excludePrimvar) \ (metadata) \ (shadingMode) \ + (shadingConversion) \ (useAsAnimationCache) \ /* assemblyRep values */ \ (Collapsed) \ @@ -248,6 +249,7 @@ struct UsdMayaJobImportArgs const TfToken::Set includeAPINames; const TfToken::Set includeMetadataKeys; TfToken shadingMode; // XXX can we make this const? + const TfToken shadingConversion; const bool useAsAnimationCache; const bool importWithProxyShapes; diff --git a/lib/mayaUsd/fileio/shaderReader.cpp b/lib/mayaUsd/fileio/shaderReader.cpp index 591aa2dd00..a7344df511 100644 --- a/lib/mayaUsd/fileio/shaderReader.cpp +++ b/lib/mayaUsd/fileio/shaderReader.cpp @@ -34,6 +34,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 */ TfToken UsdMayaShaderReader::GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const { diff --git a/lib/mayaUsd/fileio/shaderReader.h b/lib/mayaUsd/fileio/shaderReader.h index feb1c210c0..a7aaefe7a4 100644 --- a/lib/mayaUsd/fileio/shaderReader.h +++ b/lib/mayaUsd/fileio/shaderReader.h @@ -37,6 +37,19 @@ class UsdMayaShaderReader : public UsdMayaPrimReader { MAYAUSD_CORE_PUBLIC UsdMayaShaderReader(const UsdMayaPrimReaderArgs&); + /// The level of support a reader can offer for a given context + /// + /// A basic writer that gives correct results across most contexts should + /// report `Fallback`, while a specialized writer 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 writers and allows + /// declaring how well this class can support the current context: + MAYAUSD_CORE_PUBLIC + static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); + /// Get the name of the Maya shading attribute that corresponds to the /// USD attribute named \p usdAttrName. /// diff --git a/lib/mayaUsd/fileio/shaderReaderRegistry.cpp b/lib/mayaUsd/fileio/shaderReaderRegistry.cpp index db80171e35..a9ae484e89 100644 --- a/lib/mayaUsd/fileio/shaderReaderRegistry.cpp +++ b/lib/mayaUsd/fileio/shaderReaderRegistry.cpp @@ -28,7 +28,7 @@ #include #include -#include +#include #include #include @@ -40,51 +40,98 @@ TF_DEFINE_PRIVATE_TOKENS( (ShaderReader) ); -typedef TfHashMap - _Registry; +namespace { +struct _RegistryEntry { + UsdMayaShaderReaderRegistry::ContextPredicateFn _pred; + UsdMayaShaderReaderRegistry::ReaderFactoryFn _fn; + int _index; +}; + +typedef std::unordered_multimap _Registry; static _Registry _reg; +static int _indexCounter = 0; + +_Registry::const_iterator _Find( + const TfToken& usdInfoId, + const UsdMayaJobImportArgs& importArgs) { + using ContextSupport = UsdMayaShaderReader::ContextSupport; + + _Registry::const_iterator ret = _reg.cend(); + _Registry::const_iterator first, last; + std::tie(first, last) = _reg.equal_range(usdInfoId); + while (first != last) { + ContextSupport support = first->second._pred(importArgs); + if (support == ContextSupport::Supported) { + ret = first; + } else if (support == ContextSupport::Fallback && ret == _reg.end()) { + ret = first; + } + ++first; + } + + return ret; +} +} // namespace /* static */ void UsdMayaShaderReaderRegistry::Register( - TfToken usdInfoId, - UsdMayaShaderReaderRegistry::ReaderFactoryFn fn) + TfToken usdInfoId, + UsdMayaShaderReaderRegistry::ContextPredicateFn pred, + UsdMayaShaderReaderRegistry::ReaderFactoryFn fn) { TF_DEBUG(PXRUSDMAYA_REGISTRY) .Msg("Registering UsdMayaShaderReader for info:id %s.\n", usdInfoId.GetText()); - std::pair<_Registry::iterator, bool> insertStatus = _reg.insert(std::make_pair(usdInfoId, fn)); - if (insertStatus.second) { - UsdMaya_RegistryHelper::AddUnloader([usdInfoId]() { _reg.erase(usdInfoId); }); - } else { - TF_CODING_ERROR("Multiple readers for id %s", usdInfoId.GetText()); - } + int index = _indexCounter++; + _reg.insert(std::make_pair(usdInfoId, _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. + UsdMaya_RegistryHelper::AddUnloader([usdInfoId, index]() { + _Registry::const_iterator it, itEnd; + std::tie(it, itEnd) = _reg.equal_range(usdInfoId); + for (; it != itEnd; ++it) { + if (it->second._index == index) { + _reg.erase(it); + break; + } + } + }); } /* static */ -UsdMayaShaderReaderRegistry::ReaderFactoryFn -UsdMayaShaderReaderRegistry::Find(const TfToken& usdInfoId) +UsdMayaShaderReaderRegistry::ReaderFactoryFn UsdMayaShaderReaderRegistry::Find( + const TfToken& usdInfoId, + const UsdMayaJobImportArgs& importArgs) { + using ContextSupport = UsdMayaShaderReader::ContextSupport; TfRegistryManager::GetInstance().SubscribeTo(); - ReaderFactoryFn ret = nullptr; - if (TfMapLookup(_reg, usdInfoId, &ret)) { - return ret; + _Registry::const_iterator it = _Find(usdInfoId, importArgs); + + if (it != _reg.end()) { + return it->second._fn; } + // Try adding more writers via plugin load: static const TfTokenVector SCOPE = { _tokens->UsdMaya, _tokens->ShaderReader }; UsdMaya_RegistryHelper::FindAndLoadMayaPlug(SCOPE, usdInfoId); - // ideally something just registered itself. if not, we at least put it in - // the registry in case we encounter it again. - if (!TfMapLookup(_reg, usdInfoId, &ret)) { - TF_DEBUG(PXRUSDMAYA_REGISTRY) - .Msg( - "No usdMaya reader plugin for info:id %s. No maya plugin found.\n", - usdInfoId.GetText()); - _reg[usdInfoId] = nullptr; + it = _Find(usdInfoId, importArgs); + + if (it != _reg.end()) { + return it->second._fn; } - return ret; + if (_reg.count(usdInfoId) == 0) { + // Nothing registered at all, remember that: + Register( + usdInfoId, + [](const UsdMayaJobImportArgs&) { return ContextSupport::Fallback; }, + nullptr); + } + + return nullptr; } PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/mayaUsd/fileio/shaderReaderRegistry.h b/lib/mayaUsd/fileio/shaderReaderRegistry.h index 06661e027c..923b5f6d62 100644 --- a/lib/mayaUsd/fileio/shaderReaderRegistry.h +++ b/lib/mayaUsd/fileio/shaderReaderRegistry.h @@ -58,15 +58,15 @@ PXR_NAMESPACE_OPEN_SCOPE /// reader plugin for some Maya built-in type, you can register your own /// plugin for that Maya built-in type. struct UsdMayaShaderReaderRegistry { + /// Predicate function, i.e. a function that can tell the level of support + /// the reader function will provide for a given context. + typedef std::function + ContextPredicateFn; + /// Reader factory function, i.e. a function that creates a prim reader /// for the given prim reader args. typedef std::function ReaderFactoryFn; - /// Reader function, i.e. a function that reads a prim. This is the - /// signature of the function declared in the PXRUSDMAYA_DEFINE_READER - /// macro. - typedef std::function ReaderFn; - /// \brief Register \p fn as a factory function providing a /// UsdMayaShaderReader subclass that can be used to read \p usdInfoId. /// If you can't provide a valid UsdMayaShaderReader for the given arguments, @@ -77,20 +77,27 @@ struct UsdMayaShaderReaderRegistry { /// class MyReader : public UsdMayaShaderReader { /// static UsdMayaPrimReaderSharedPtr Create( /// const UsdMayaPrimReaderArgs&); + /// static CanImport(const UsdMayaJobImportArgs& importArgs) { + /// return Supported; // After consulting the arguments + /// } /// }; /// TF_REGISTRY_FUNCTION_WITH_TAG(UsdMayaShaderReaderRegistry, MyReader) { /// UsdMayaShaderReaderRegistry::Register("myCustomInfoId", + /// MyReader::CanImport, /// MyReader::Create); /// } /// \endcode MAYAUSD_CORE_PUBLIC - static void Register(TfToken usdInfoId, ReaderFactoryFn fn); + static void Register(TfToken usdInfoId, ContextPredicateFn pred, ReaderFactoryFn fn); - /// \brief Finds a reader if one exists for \p usdInfoId. + /// \brief Finds a reader if one exists for \p usdInfoId. The returned reader will have declared + /// support given the current \p importArgs. /// - /// If there is no reader plugin for \p usdInfoId, returns nullptr. + /// If there is no supported reader plugin for \p usdInfoId, returns nullptr. MAYAUSD_CORE_PUBLIC - static ReaderFactoryFn Find(const TfToken& usdInfoId); + static ReaderFactoryFn Find( + const TfToken& usdInfoId, + const UsdMayaJobImportArgs& importArgs); }; /// \brief Registers a pre-existing reader class for the given USD info:id; @@ -105,16 +112,22 @@ struct UsdMayaShaderReaderRegistry { /// const UsdMayaPrimReaderArgs& readerArgs) { /// // ... /// } +/// static CanImport(const UsdMayaJobImportArgs& importArgs) { +/// return Supported; // After consulting the arguments +/// } /// }; /// PXRUSDMAYA_REGISTER_SHADER_READER(myCustomInfoId, MyReader); /// \endcode #define PXRUSDMAYA_REGISTER_SHADER_READER(usdInfoId, readerClass) \ TF_REGISTRY_FUNCTION_WITH_TAG(UsdMayaShaderReaderRegistry, usdInfoId##_##readerClass) \ { \ - static_assert(std::is_base_of::value, \ + static_assert( \ + std::is_base_of::value, \ #readerClass " must derive from UsdMayaShaderReader"); \ UsdMayaShaderReaderRegistry::Register( \ - TfToken(#usdInfoId), [](const UsdMayaPrimReaderArgs& readerArgs) { \ + TfToken(#usdInfoId), \ + readerClass::CanImport, \ + [](const UsdMayaPrimReaderArgs& readerArgs) { \ return std::make_shared(readerArgs); \ }); \ } diff --git a/lib/mayaUsd/fileio/shading/shadingModeDisplayColor.cpp b/lib/mayaUsd/fileio/shading/shadingModeDisplayColor.cpp index 69688c5f78..663d59e175 100644 --- a/lib/mayaUsd/fileio/shading/shadingModeDisplayColor.cpp +++ b/lib/mayaUsd/fileio/shading/shadingModeDisplayColor.cpp @@ -13,18 +13,13 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#include - -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include #include #include #include @@ -34,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -48,11 +44,21 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if MAYA_API_VERSION >= 20200000 +#include +#endif + +#include PXR_NAMESPACE_OPEN_SCOPE @@ -64,7 +70,6 @@ TF_DEFINE_PRIVATE_TOKENS( (transmissionColor) (transparency) - ((MayaShaderName, "lambert")) ((DefaultShaderId, "PxrDiffuse")) ((DefaultShaderOutputName, "out")) ); @@ -85,10 +90,6 @@ class DisplayColorShadingModeExporter : public UsdMayaShadingModeExporter if (status != MS::kSuccess) { return; } - const MFnLambertShader lambertFn(ssDepNode.object(), &status); - if (status != MS::kSuccess) { - return; - } const UsdMayaShadingModeExportContext::AssignmentVector& assignments = context.GetAssignments(); @@ -97,13 +98,33 @@ class DisplayColorShadingModeExporter : public UsdMayaShadingModeExporter } const UsdStageRefPtr& stage = context.GetUsdStage(); - const MColor mayaColor = lambertFn.color(); - const MColor mayaTransparency = lambertFn.transparency(); - const float diffuseCoeff = lambertFn.diffuseCoeff(); - const GfVec3f color = UsdMayaColorSpace::ConvertMayaToLinear( - diffuseCoeff*GfVec3f(mayaColor[0], mayaColor[1], mayaColor[2])); - const GfVec3f transparency = UsdMayaColorSpace::ConvertMayaToLinear( - GfVec3f(mayaTransparency[0], mayaTransparency[1], mayaTransparency[2])); + GfVec3f color; + GfVec3f transparency; + const MFnLambertShader lambertFn(ssDepNode.object(), &status); + if (status == MS::kSuccess) { + const MColor mayaColor = lambertFn.color(); + const MColor mayaTransparency = lambertFn.transparency(); + const float diffuseCoeff = lambertFn.diffuseCoeff(); + color = UsdMayaColorSpace::ConvertMayaToLinear( + diffuseCoeff*GfVec3f(mayaColor[0], mayaColor[1], mayaColor[2])); + transparency = UsdMayaColorSpace::ConvertMayaToLinear( + GfVec3f(mayaTransparency[0], mayaTransparency[1], mayaTransparency[2])); + } else { +#if MAYA_API_VERSION >= 20200000 + const MFnStandardSurfaceShader surfaceFn(ssDepNode.object(), &status); + if (status != MS::kSuccess) { + return; + } + const MColor mayaColor = surfaceFn.baseColor(); + const float base = surfaceFn.base(); + color = UsdMayaColorSpace::ConvertMayaToLinear( + base*GfVec3f(mayaColor[0], mayaColor[1], mayaColor[2])); + const float mayaTransparency = surfaceFn.transmission(); + transparency = GfVec3f(mayaTransparency, mayaTransparency, mayaTransparency); +#else + return; +#endif + } VtVec3fArray displayColorAry; displayColorAry.push_back(color); @@ -114,9 +135,9 @@ class DisplayColorShadingModeExporter : public UsdMayaShadingModeExporter // (of the common graycale conversion) on re-import // The average is compute from the Maya color as is VtFloatArray displayOpacityAry; - const float transparencyAvg = (mayaTransparency[0] + - mayaTransparency[1] + - mayaTransparency[2]) / 3.0f; + const float transparencyAvg = (transparency[0] + + transparency[1] + + transparency[2]) / 3.0f; if (transparencyAvg > 0.0f) { displayOpacityAry.push_back(1.0f - transparencyAvg); } @@ -241,7 +262,7 @@ TF_REGISTRY_FUNCTION_WITH_TAG(UsdMayaShadingModeExportContext, displayColor) ); } -DEFINE_SHADING_MODE_IMPORTER(displayColor, context) +DEFINE_SHADING_MODE_IMPORTER_WITH_JOB_ARGUMENTS(displayColor, context, jobArguments) { const UsdShadeMaterial& shadeMaterial = context->GetShadeMaterial(); const UsdGeomGprim& primSchema = context->GetBoundPrim(); @@ -304,40 +325,86 @@ DEFINE_SHADING_MODE_IMPORTER(displayColor, context) const GfVec3f transparencyColor = UsdMayaColorSpace::ConvertLinearToMaya(linearTransparency); - std::string shaderName(_tokens->MayaShaderName.GetText()); + // We default to lambert if no conversion was requested: + const TfToken& shadingConversion + = jobArguments.shadingConversion != UsdMayaShadingConversionTokens->none + ? jobArguments.shadingConversion + : UsdMayaShadingConversionTokens->lambert; + std::string shaderName(shadingConversion.GetText()); SdfPath shaderParentPath = SdfPath::AbsoluteRootPath(); if (shadeMaterial) { const UsdPrim& shadeMaterialPrim = shadeMaterial.GetPrim(); shaderName = TfStringPrintf("%s_%s", shadeMaterialPrim.GetName().GetText(), - _tokens->MayaShaderName.GetText()); + shadingConversion.GetText()); shaderParentPath = shadeMaterialPrim.GetPath(); } - // Construct the lambert shader. - MFnLambertShader lambertFn; - MObject shadingObj = lambertFn.create(); - lambertFn.setName(shaderName.c_str()); - lambertFn.setColor( - MColor(displayColor[0], displayColor[1], displayColor[2])); - lambertFn.setTransparency( - MColor(transparencyColor[0], transparencyColor[1], transparencyColor[2])); - - // We explicitly set diffuse coefficient to 1.0 here since new lamberts - // default to 0.8. This is to make sure the color value matches visually - // when roundtripping since we bake the diffuseCoeff into the diffuse color - // at export. - lambertFn.setDiffuseCoeff(1.0); - - const SdfPath lambertPath = - shaderParentPath.AppendChild(TfToken(lambertFn.name().asChar())); - context->AddCreatedObject(lambertPath, shadingObj); - - // Find the outColor plug so we can connect it as the surface shader of the - // shading engine. - MPlug outputPlug = lambertFn.findPlug("outColor", &status); - CHECK_MSTATUS_AND_RETURN(status, MObject()); + // Construct the selected shader. + MObject shadingObj; + UsdMayaTranslatorUtil::CreateShaderNode( + MString(shaderName.c_str()), + shadingConversion.GetText(), + UsdMayaShadingNodeType::Shader, + &status, + &shadingObj); + if (status != MS::kSuccess) { + // we need to make sure assumes those types are loaded.. + TF_RUNTIME_ERROR( + "Could not create node of type '%s' for prim '%s'.\n", + shadingConversion.GetText(), + primSchema.GetPath().GetText()); + return MObject(); + } + + MPlug outputPlug; +#if MAYA_API_VERSION >= 20200000 + if (shadingConversion != UsdMayaShadingConversionTokens->standardSurface) { +#endif + MFnLambertShader lambertFn; + lambertFn.setObject(shadingObj); + lambertFn.setName(shaderName.c_str()); + lambertFn.setColor( + MColor(displayColor[0], displayColor[1], displayColor[2])); + lambertFn.setTransparency( + MColor(transparencyColor[0], transparencyColor[1], transparencyColor[2])); + + // We explicitly set diffuse coefficient to 1.0 here since new lamberts + // default to 0.8. This is to make sure the color value matches visually + // when roundtripping since we bake the diffuseCoeff into the diffuse color + // at export. + lambertFn.setDiffuseCoeff(1.0); + + const SdfPath lambertPath = + shaderParentPath.AppendChild(TfToken(lambertFn.name().asChar())); + context->AddCreatedObject(lambertPath, shadingObj); + + outputPlug = lambertFn.findPlug("outColor", &status); + CHECK_MSTATUS_AND_RETURN(status, MObject()); +#if MAYA_API_VERSION >= 20200000 + } else { + MFnStandardSurfaceShader surfaceFn; + surfaceFn.setObject(shadingObj); + surfaceFn.setName(shaderName.c_str()); + surfaceFn.setBase(1.0f); + surfaceFn.setBaseColor( + MColor(displayColor[0], displayColor[1], displayColor[2])); + + float transmission + = (transparencyColor[0] + transparencyColor[1] + transparencyColor[2]) / 3.0f; + surfaceFn.setTransmission(transmission); + + const SdfPath surfacePath = + shaderParentPath.AppendChild(TfToken(surfaceFn.name().asChar())); + context->AddCreatedObject(surfacePath, shadingObj); + + // Find the outColor plug so we can connect it as the surface shader of the + // shading engine. + outputPlug = surfaceFn.findPlug("outColor", &status); + CHECK_MSTATUS_AND_RETURN(status, MObject()); + } +#endif // Create the shading engine. MObject shadingEngine = context->CreateShadingEngine(); diff --git a/lib/mayaUsd/fileio/shading/shadingModeRegistry.cpp b/lib/mayaUsd/fileio/shading/shadingModeRegistry.cpp index 15c35731de..cbd3cc767a 100644 --- a/lib/mayaUsd/fileio/shading/shadingModeRegistry.cpp +++ b/lib/mayaUsd/fileio/shading/shadingModeRegistry.cpp @@ -34,6 +34,9 @@ PXR_NAMESPACE_OPEN_SCOPE TF_DEFINE_PUBLIC_TOKENS(UsdMayaShadingModeTokens, PXRUSDMAYA_SHADINGMODE_TOKENS); +TF_DEFINE_PUBLIC_TOKENS(UsdMayaShadingConversionTokens, + PXRUSDMAYA_SHADINGCONVERSION_TOKENS); + typedef std::map _ExportRegistry; static _ExportRegistry _exportReg; diff --git a/lib/mayaUsd/fileio/shading/shadingModeRegistry.h b/lib/mayaUsd/fileio/shading/shadingModeRegistry.h index 6c62d44c0b..58ee9e72ab 100644 --- a/lib/mayaUsd/fileio/shading/shadingModeRegistry.h +++ b/lib/mayaUsd/fileio/shading/shadingModeRegistry.h @@ -42,6 +42,17 @@ TF_DECLARE_PUBLIC_TOKENS(UsdMayaShadingModeTokens, MAYAUSD_CORE_PUBLIC, PXRUSDMAYA_SHADINGMODE_TOKENS); +#define PXRUSDMAYA_SHADINGCONVERSION_TOKENS \ + (none) \ + (lambert) \ + (standardSurface) \ + (blinn) \ + (phong) \ + (phongE) + +TF_DECLARE_PUBLIC_TOKENS(UsdMayaShadingConversionTokens, + MAYAUSD_CORE_PUBLIC, + PXRUSDMAYA_SHADINGCONVERSION_TOKENS); TF_DECLARE_WEAK_PTRS(UsdMayaShadingModeRegistry); diff --git a/lib/mayaUsd/fileio/shading/shadingModeUseRegistry.cpp b/lib/mayaUsd/fileio/shading/shadingModeUseRegistry.cpp index 67c2460c32..08b7b36532 100644 --- a/lib/mayaUsd/fileio/shading/shadingModeUseRegistry.cpp +++ b/lib/mayaUsd/fileio/shading/shadingModeUseRegistry.cpp @@ -476,7 +476,7 @@ class UseRegistryShadingModeImporter { shaderSchema.GetIdAttr().Get(&shaderId); if (UsdMayaShaderReaderRegistry::ReaderFactoryFn factoryFn - = UsdMayaShaderReaderRegistry::Find(shaderId)) { + = UsdMayaShaderReaderRegistry::Find(shaderId, _jobArguments)) { UsdPrim shaderPrim = shaderSchema.GetPrim(); UsdMayaPrimReaderArgs args(shaderPrim, _jobArguments); diff --git a/lib/mayaUsd/utils/util.cpp b/lib/mayaUsd/utils/util.cpp index 2ff36f8801..70cceb8a39 100644 --- a/lib/mayaUsd/utils/util.cpp +++ b/lib/mayaUsd/utils/util.cpp @@ -54,6 +54,10 @@ #include #include +#if MAYA_API_VERSION >= 20200000 +#include +#endif + #include #include #include @@ -819,7 +823,7 @@ _GetColorAndTransparencyFromLambert( } if (alpha) { MColor trn = lambertFn.transparency(); - // Assign Alpha as 1.0 - average of shader trasparency + // Assign Alpha as 1.0 - average of shader transparency // and check if they are all the same *alpha = 1.0 - ((trn[0] + trn[1] + trn[2]) / 3.0); } @@ -829,6 +833,34 @@ _GetColorAndTransparencyFromLambert( return false; } +bool +_GetColorAndTransparencyFromStandardSurface( + const MObject& shaderObj, + GfVec3f* rgb, + float* alpha) +{ +#if MAYA_API_VERSION >= 20200000 + MStatus status; + MFnStandardSurfaceShader surfaceFn(shaderObj, &status); + if (status == MS::kSuccess ) { + if (rgb) { + GfVec3f displayColor; + MColor color = surfaceFn.baseColor(); + for (int j=0;j<3;j++) { + displayColor[j] = color[j]; + } + displayColor *= surfaceFn.base(); + *rgb = UsdMayaColorSpace::ConvertMayaToLinear(displayColor); + } + if (alpha) { + *alpha = 1.0f - surfaceFn.transmission(); + } + return true; + } +#endif + return false; +} + bool _GetColorAndTransparencyFromDepNode( const MObject& shaderObj, @@ -913,6 +945,11 @@ _getMayaShadersColor( RGBData ? &(*RGBData)[i] : nullptr, AlphaData ? &(*AlphaData)[i] : nullptr) + || _GetColorAndTransparencyFromStandardSurface( + shaderObjs[i], + RGBData ? &(*RGBData)[i] : nullptr, + AlphaData ? &(*AlphaData)[i] : nullptr) + || _GetColorAndTransparencyFromDepNode( shaderObjs[i], RGBData ? &(*RGBData)[i] : nullptr, diff --git a/lib/usd/pxrUsdPreviewSurface/usdPreviewSurfaceReader.cpp b/lib/usd/pxrUsdPreviewSurface/usdPreviewSurfaceReader.cpp index 3cf6470b8e..6ae2d06a51 100644 --- a/lib/usd/pxrUsdPreviewSurface/usdPreviewSurfaceReader.cpp +++ b/lib/usd/pxrUsdPreviewSurface/usdPreviewSurfaceReader.cpp @@ -88,8 +88,6 @@ bool PxrMayaUsdPreviewSurface_Reader::Read(UsdMayaPrimReaderContext* context) context->RegisterNewMayaNode(prim.GetPath().GetString(), mayaObject); - MDGModifier modifier; - bool useModifier = false; for (const UsdShadeInput& input : shaderSchema.GetInputs()) { TfToken baseName = GetMayaNameForUsdAttrName(input.GetFullName()); if (baseName.IsEmpty()) { @@ -101,9 +99,6 @@ bool PxrMayaUsdPreviewSurface_Reader::Read(UsdMayaPrimReaderContext* context) } UsdMayaReadUtil::SetMayaAttr(mayaAttr, input, /*unlinearizeColors*/ false); } - if (useModifier) { - modifier.doIt(); - } return true; } diff --git a/lib/usd/translators/shading/CMakeLists.txt b/lib/usd/translators/shading/CMakeLists.txt index cd16e9a64c..c3e59a22f2 100644 --- a/lib/usd/translators/shading/CMakeLists.txt +++ b/lib/usd/translators/shading/CMakeLists.txt @@ -3,13 +3,25 @@ # ----------------------------------------------------------------------------- target_sources(${TARGET_NAME} PRIVATE + usdBlinnReader.cpp usdBlinnWriter.cpp usdFileTextureWriter.cpp + usdLambertReader.cpp usdLambertWriter.cpp + usdMaterialReader.cpp usdMaterialWriter.cpp + usdPhongReader.cpp usdPhongWriter.cpp + usdPhongEReader.cpp usdPhongEWriter.cpp usdReflectWriter.cpp - usdStandardSurfaceWriter.cpp usdUVTextureReader.cpp ) + +if (MAYA_APP_VERSION VERSION_GREATER_EQUAL 2020) + target_sources(${TARGET_NAME} + PRIVATE + usdStandardSurfaceReader.cpp + usdStandardSurfaceWriter.cpp + ) +endif() diff --git a/lib/usd/translators/shading/usdBlinnReader.cpp b/lib/usd/translators/shading/usdBlinnReader.cpp new file mode 100644 index 0000000000..595b18833d --- /dev/null +++ b/lib/usd/translators/shading/usdBlinnReader.cpp @@ -0,0 +1,134 @@ +// +// Copyright 2020 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "usdLambertReader.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +/// Shader writer for importing UsdPreviewSurface to Maya's lambert material nodes +class PxrUsdTranslators_BlinnReader : public PxrUsdTranslators_LambertReader { + typedef PxrUsdTranslators_LambertReader _BaseClass; + +public: + PxrUsdTranslators_BlinnReader(const UsdMayaPrimReaderArgs&); + + static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); + + /// Get the name of the Maya shading attribute that corresponds to the + /// USD attribute named \p usdAttrName. + virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + +protected: + /// What is the Maya node type name we want to convert to: + const TfToken& _GetMayaNodeTypeName() const override; + + void _OnReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const override; +}; + +PXRUSDMAYA_REGISTER_SHADER_READER(UsdPreviewSurface, PxrUsdTranslators_BlinnReader); + +// clang-format off +TF_DEFINE_PRIVATE_TOKENS( + _tokens, + + // Maya material nodes attribute names + (eccentricity) + (specularColor) +); +// clang-format on + +PxrUsdTranslators_BlinnReader::PxrUsdTranslators_BlinnReader(const UsdMayaPrimReaderArgs& readArgs) + : PxrUsdTranslators_LambertReader(readArgs) +{ +} + +/* static */ +UsdMayaShaderReader::ContextSupport +PxrUsdTranslators_BlinnReader::CanImport(const UsdMayaJobImportArgs& importArgs) +{ + return importArgs.shadingConversion == UsdMayaShadingConversionTokens->blinn + ? ContextSupport::Supported + : ContextSupport::Unsupported; +} + +const TfToken& PxrUsdTranslators_BlinnReader::_GetMayaNodeTypeName() const +{ + return UsdMayaShadingConversionTokens->blinn; +} + +void PxrUsdTranslators_BlinnReader::_OnReadAttribute( + const TfToken& mayaAttrName, + MFnDependencyNode& shaderFn) const +{ + if (mayaAttrName == _tokens->specularColor) { + MFnBlinnShader blinnFn; + blinnFn.setObject(shaderFn.object()); + MColor color(blinnFn.specularColor()); + float scale(blinnFn.specularRollOff()); + color /= scale; + blinnFn.setSpecularColor(color); + blinnFn.setSpecularRollOff(1.0f); + } else { + return _BaseClass::_OnReadAttribute(mayaAttrName, shaderFn); + } +} + +/* virtual */ +TfToken PxrUsdTranslators_BlinnReader::GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const +{ + TfToken usdInputName; + UsdShadeAttributeType attrType; + std::tie(usdInputName, attrType) = UsdShadeUtils::GetBaseNameAndType(usdAttrName); + + if (attrType == UsdShadeAttributeType::Input) { + if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->SpecularColorAttrName) { + return _tokens->specularColor; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->RoughnessAttrName) { + return _tokens->eccentricity; + } + } + + return _BaseClass::GetMayaNameForUsdAttrName(usdAttrName); +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/usd/translators/shading/usdLambertReader.cpp b/lib/usd/translators/shading/usdLambertReader.cpp new file mode 100644 index 0000000000..edcebe35cd --- /dev/null +++ b/lib/usd/translators/shading/usdLambertReader.cpp @@ -0,0 +1,118 @@ +// +// Copyright 2020 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "usdLambertReader.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +PXRUSDMAYA_REGISTER_SHADER_READER(UsdPreviewSurface, PxrUsdTranslators_LambertReader); + +// clang-format off +TF_DEFINE_PRIVATE_TOKENS( + _tokens, + + // Maya material nodes attribute names + (color) + (incandescence) + (normalCamera) +); +// clang-format on + +PxrUsdTranslators_LambertReader::PxrUsdTranslators_LambertReader( + const UsdMayaPrimReaderArgs& readArgs) + : PxrUsdTranslators_MaterialReader(readArgs) +{ +} + +/* static */ +UsdMayaShaderReader::ContextSupport +PxrUsdTranslators_LambertReader::CanImport(const UsdMayaJobImportArgs& importArgs) +{ + return importArgs.shadingConversion == UsdMayaShadingConversionTokens->lambert + ? ContextSupport::Supported + : ContextSupport::Unsupported; +} + +const TfToken& PxrUsdTranslators_LambertReader::_GetMayaNodeTypeName() const +{ + return UsdMayaShadingConversionTokens->lambert; +} + +void PxrUsdTranslators_LambertReader::_OnReadAttribute( + const TfToken& mayaAttrName, + MFnDependencyNode& shaderFn) const +{ + if (mayaAttrName == _tokens->color) { + MFnLambertShader lambertFn; + lambertFn.setObject(shaderFn.object()); + MColor color(lambertFn.color()); + float scale(lambertFn.diffuseCoeff()); + color /= scale; + lambertFn.setColor(color); + lambertFn.setDiffuseCoeff(1.0f); + } else { + return _BaseClass::_OnReadAttribute(mayaAttrName, shaderFn); + } +} + +/* virtual */ +TfToken PxrUsdTranslators_LambertReader::GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const +{ + TfToken usdInputName; + UsdShadeAttributeType attrType; + std::tie(usdInputName, attrType) = UsdShadeUtils::GetBaseNameAndType(usdAttrName); + + if (attrType == UsdShadeAttributeType::Input) { + if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->DiffuseColorAttrName) { + return _tokens->color; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->EmissiveColorAttrName) { + return _tokens->incandescence; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->NormalAttrName) { + return _tokens->normalCamera; + } + } + + return _BaseClass::GetMayaNameForUsdAttrName(usdAttrName); +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/usd/translators/shading/usdLambertReader.h b/lib/usd/translators/shading/usdLambertReader.h new file mode 100644 index 0000000000..74a1e536e6 --- /dev/null +++ b/lib/usd/translators/shading/usdLambertReader.h @@ -0,0 +1,50 @@ +// +// Copyright 2020 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef PXRUSDTRANSLATORS_LAMBERT_READER_H +#define PXRUSDTRANSLATORS_LAMBERT_READER_H + +/// \file + +#include "usdMaterialReader.h" + +#include + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +/// Shader writer for importing UsdPreviewSurface to Maya's lambert material nodes +class PxrUsdTranslators_LambertReader : public PxrUsdTranslators_MaterialReader { + typedef PxrUsdTranslators_MaterialReader _BaseClass; + +public: + PxrUsdTranslators_LambertReader(const UsdMayaPrimReaderArgs&); + + static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); + + /// Get the name of the Maya shading attribute that corresponds to the + /// USD attribute named \p usdAttrName. + virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + +protected: + const TfToken& _GetMayaNodeTypeName() const override; + + void _OnReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const override; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif diff --git a/lib/usd/translators/shading/usdLambertWriter.cpp b/lib/usd/translators/shading/usdLambertWriter.cpp index 6aebcc3d8f..d185a55540 100644 --- a/lib/usd/translators/shading/usdLambertWriter.cpp +++ b/lib/usd/translators/shading/usdLambertWriter.cpp @@ -111,11 +111,16 @@ void PxrUsdTranslators_LambertWriter::WriteSpecular(const UsdTimeCode& usdTime) .CreateInput(PxrMayaUsdPreviewSurfaceTokens->RoughnessAttrName, SdfValueTypeNames->Float) .Set(1.0f, usdTime); - // Using specular workflow, but with default black specular color. + // Using specular workflow, but enforced black specular color. shaderSchema .CreateInput( PxrMayaUsdPreviewSurfaceTokens->UseSpecularWorkflowAttrName, SdfValueTypeNames->Int) .Set(1, usdTime); + + shaderSchema + .CreateInput(PxrMayaUsdPreviewSurfaceTokens->SpecularColorAttrName, SdfValueTypeNames->Color3f) + .Set(GfVec3f(0.0f, 0.0f, 0.0f), usdTime); + } /* virtual */ diff --git a/lib/usd/translators/shading/usdMaterialReader.cpp b/lib/usd/translators/shading/usdMaterialReader.cpp new file mode 100644 index 0000000000..919261395f --- /dev/null +++ b/lib/usd/translators/shading/usdMaterialReader.cpp @@ -0,0 +1,136 @@ +// +// Copyright 2020 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "usdMaterialReader.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +PXR_NAMESPACE_OPEN_SCOPE + +// clang-format off +TF_DEFINE_PRIVATE_TOKENS( + _tokens, + + (outColor) +); +// clang-format on + +PxrUsdTranslators_MaterialReader::PxrUsdTranslators_MaterialReader( + const UsdMayaPrimReaderArgs& readArgs) + : UsdMayaShaderReader(readArgs) +{ +} + +/* virtual */ +bool PxrUsdTranslators_MaterialReader::Read(UsdMayaPrimReaderContext* context) +{ + const auto& prim = _GetArgs().GetUsdPrim(); + UsdShadeShader shaderSchema = UsdShadeShader(prim); + if (!shaderSchema) { + return false; + } + + const TfToken& mayaNodeTypeName = _GetMayaNodeTypeName(); + MStatus status; + MObject mayaObject; + MFnDependencyNode depFn; + if (!(UsdMayaTranslatorUtil::CreateShaderNode( + MString(prim.GetName().GetText()), + mayaNodeTypeName.GetText(), + UsdMayaShadingNodeType::Shader, + &status, + &mayaObject) + && depFn.setObject(mayaObject))) { + // we need to make sure assumes those types are loaded.. + TF_RUNTIME_ERROR( + "Could not create node of type '%s' for shader '%s'.\n", + mayaNodeTypeName.GetText(), + prim.GetPath().GetText()); + return false; + } + + context->RegisterNewMayaNode(prim.GetPath().GetString(), mayaObject); + + for (const UsdShadeInput& input : shaderSchema.GetInputs()) { + TfToken baseName = GetMayaNameForUsdAttrName(input.GetFullName()); + if (baseName.IsEmpty()) { + continue; + } + _OnReadAttribute(baseName, depFn); + MPlug mayaAttr = depFn.findPlug(baseName.GetText(), true, &status); + if (status != MS::kSuccess) { + continue; + } + VtValue val; + if (input.Get(&val)) { + _ConvertToMaya(baseName, val); + UsdMayaReadUtil::SetMayaAttr(mayaAttr, val, /*unlinearizeColors*/ false); + } + } + + return true; +} + +/* virtual */ +TfToken +PxrUsdTranslators_MaterialReader::GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const +{ + TfToken usdOutputName; + UsdShadeAttributeType attrType; + std::tie(usdOutputName, attrType) = UsdShadeUtils::GetBaseNameAndType(usdAttrName); + + if (attrType == UsdShadeAttributeType::Output) { + if (usdOutputName == UsdShadeTokens->surface) { + return _tokens->outColor; + } + } + + return TfToken(); +} + +void PxrUsdTranslators_MaterialReader::_ConvertToMaya(const TfToken&, VtValue&) const +{ + // Nothing to do + return; +} + +void PxrUsdTranslators_MaterialReader::_OnReadAttribute(const TfToken&, MFnDependencyNode&) const +{ + // Nothing to do + return; +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/usd/translators/shading/usdMaterialReader.h b/lib/usd/translators/shading/usdMaterialReader.h new file mode 100644 index 0000000000..ed945a334b --- /dev/null +++ b/lib/usd/translators/shading/usdMaterialReader.h @@ -0,0 +1,62 @@ +// +// Copyright 2020 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#ifndef PXRUSDTRANSLATORS_MATERIAL_READER_H +#define PXRUSDTRANSLATORS_MATERIAL_READER_H + +/// \file + +#include + +#include + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +class UsdMayaPrimReaderArgs; +class TfToken; +struct UsdMayaJobImportArgs; +class UsdShadeShader; + +/// Shader writer for importing UsdPreviewSurface to Maya's native material nodes +class PxrUsdTranslators_MaterialReader : public UsdMayaShaderReader { +public: + PxrUsdTranslators_MaterialReader(const UsdMayaPrimReaderArgs&); + + /// Get the name of the Maya shading attribute that corresponds to the + /// USD attribute named \p usdAttrName. + virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + + /// Generic read function that traverses a schema and reads everything. + bool Read(UsdMayaPrimReaderContext* context) override; + +protected: + /// What is the Maya node type name we want to convert to: + virtual const TfToken& _GetMayaNodeTypeName() const = 0; + + /// Allows setting values on attributes indirectly affected by attribute + /// \p mayaAttribute. This allows setting back values in \p shaderFn that + /// were lost during the export phase. + virtual void _OnReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const; + + /// Convert the value in \p usdValue from USD back to Maya following rules + /// for attribute \p mayaAttrName + virtual void _ConvertToMaya(const TfToken& mayaAttrName, VtValue& usdValue) const; +}; + +PXR_NAMESPACE_CLOSE_SCOPE + +#endif diff --git a/lib/usd/translators/shading/usdPhongEReader.cpp b/lib/usd/translators/shading/usdPhongEReader.cpp new file mode 100644 index 0000000000..96cebdd58a --- /dev/null +++ b/lib/usd/translators/shading/usdPhongEReader.cpp @@ -0,0 +1,115 @@ +// +// Copyright 2020 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "usdLambertReader.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +/// Shader writer for importing UsdPreviewSurface to Maya's lambert material nodes +class PxrUsdTranslators_PhongEReader : public PxrUsdTranslators_LambertReader { + typedef PxrUsdTranslators_LambertReader _BaseClass; + +public: + PxrUsdTranslators_PhongEReader(const UsdMayaPrimReaderArgs&); + + static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); + + /// Get the name of the Maya shading attribute that corresponds to the + /// USD attribute named \p usdAttrName. + virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + +protected: + /// What is the Maya node type name we want to convert to: + const TfToken& _GetMayaNodeTypeName() const override; +}; + +PXRUSDMAYA_REGISTER_SHADER_READER(UsdPreviewSurface, PxrUsdTranslators_PhongEReader); + +// clang-format off +TF_DEFINE_PRIVATE_TOKENS( + _tokens, + + // Maya material nodes attribute names + (roughness) + (specularColor) +); +// clang-format on + +PxrUsdTranslators_PhongEReader::PxrUsdTranslators_PhongEReader( + const UsdMayaPrimReaderArgs& readArgs) + : PxrUsdTranslators_LambertReader(readArgs) +{ +} + +/* static */ +UsdMayaShaderReader::ContextSupport +PxrUsdTranslators_PhongEReader::CanImport(const UsdMayaJobImportArgs& importArgs) +{ + return importArgs.shadingConversion == UsdMayaShadingConversionTokens->phongE + ? ContextSupport::Supported + : ContextSupport::Unsupported; +} + +const TfToken& PxrUsdTranslators_PhongEReader::_GetMayaNodeTypeName() const +{ + return UsdMayaShadingConversionTokens->phongE; +} + +/* virtual */ +TfToken PxrUsdTranslators_PhongEReader::GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const +{ + TfToken usdInputName; + UsdShadeAttributeType attrType; + std::tie(usdInputName, attrType) = UsdShadeUtils::GetBaseNameAndType(usdAttrName); + + if (attrType == UsdShadeAttributeType::Input) { + if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->SpecularColorAttrName) { + return _tokens->specularColor; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->RoughnessAttrName) { + return _tokens->roughness; + } + } + + return _BaseClass::GetMayaNameForUsdAttrName(usdAttrName); +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/usd/translators/shading/usdPhongReader.cpp b/lib/usd/translators/shading/usdPhongReader.cpp new file mode 100644 index 0000000000..2dd763d1d0 --- /dev/null +++ b/lib/usd/translators/shading/usdPhongReader.cpp @@ -0,0 +1,128 @@ +// +// Copyright 2020 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "usdLambertReader.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +/// Shader writer for importing UsdPreviewSurface to Maya's lambert material nodes +class PxrUsdTranslators_PhongReader : public PxrUsdTranslators_LambertReader { + typedef PxrUsdTranslators_LambertReader _BaseClass; + +public: + PxrUsdTranslators_PhongReader(const UsdMayaPrimReaderArgs&); + + static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); + + /// Get the name of the Maya shading attribute that corresponds to the + /// USD attribute named \p usdAttrName. + virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + +protected: + /// What is the Maya node type name we want to convert to: + const TfToken& _GetMayaNodeTypeName() const override; + + void _ConvertToMaya(const TfToken& mayaAttrName, VtValue& usdValue) const override; +}; + +PXRUSDMAYA_REGISTER_SHADER_READER(UsdPreviewSurface, PxrUsdTranslators_PhongReader); + +// clang-format off +TF_DEFINE_PRIVATE_TOKENS( + _tokens, + + // Maya material nodes attribute names + (cosinePower) + (specularColor) +); +// clang-format on + +PxrUsdTranslators_PhongReader::PxrUsdTranslators_PhongReader(const UsdMayaPrimReaderArgs& readArgs) + : PxrUsdTranslators_LambertReader(readArgs) +{ +} + +/* static */ +UsdMayaShaderReader::ContextSupport +PxrUsdTranslators_PhongReader::CanImport(const UsdMayaJobImportArgs& importArgs) +{ + return importArgs.shadingConversion == UsdMayaShadingConversionTokens->phong + ? ContextSupport::Supported + : ContextSupport::Unsupported; +} + +const TfToken& PxrUsdTranslators_PhongReader::_GetMayaNodeTypeName() const +{ + return UsdMayaShadingConversionTokens->phong; +} + +void PxrUsdTranslators_PhongReader::_ConvertToMaya(const TfToken& mayaAttrName, VtValue& usdValue) + const +{ + if (mayaAttrName == _tokens->cosinePower && usdValue.IsHolding()) { + float roughness = usdValue.UncheckedGet(); + float squared = roughness * roughness; + // In the maya UI, cosinePower goes from 2.0 to 100.0 + // this does not map directly to specular roughness + usdValue = GfClamp((1.0f - 3.357f * squared) / (0.454f * squared), 2.0f, 100.0f); + } +} + +/* virtual */ +TfToken PxrUsdTranslators_PhongReader::GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const +{ + TfToken usdInputName; + UsdShadeAttributeType attrType; + std::tie(usdInputName, attrType) = UsdShadeUtils::GetBaseNameAndType(usdAttrName); + + if (attrType == UsdShadeAttributeType::Input) { + if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->SpecularColorAttrName) { + return _tokens->specularColor; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->RoughnessAttrName) { + return _tokens->cosinePower; + } + } + + return _BaseClass::GetMayaNameForUsdAttrName(usdAttrName); +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/usd/translators/shading/usdStandardSurfaceReader.cpp b/lib/usd/translators/shading/usdStandardSurfaceReader.cpp new file mode 100644 index 0000000000..3f5af502b1 --- /dev/null +++ b/lib/usd/translators/shading/usdStandardSurfaceReader.cpp @@ -0,0 +1,177 @@ +// +// Copyright 2020 Autodesk +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +#include "usdMaterialReader.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +PXR_NAMESPACE_OPEN_SCOPE + +/// Shader writer for importing UsdPreviewSurface to Maya's lambert material nodes +class PxrUsdTranslators_StandardSurfaceReader : public PxrUsdTranslators_MaterialReader { + typedef PxrUsdTranslators_MaterialReader _BaseClass; + +public: + PxrUsdTranslators_StandardSurfaceReader(const UsdMayaPrimReaderArgs&); + + static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); + + /// Get the name of the Maya shading attribute that corresponds to the + /// USD attribute named \p usdAttrName. + virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + +protected: + const TfToken& _GetMayaNodeTypeName() const override; + void _ConvertToMaya(const TfToken& mayaAttrName, VtValue& usdValue) const override; + void _OnReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const override; +}; + +PXRUSDMAYA_REGISTER_SHADER_READER(UsdPreviewSurface, PxrUsdTranslators_StandardSurfaceReader); + +// clang-format off +TF_DEFINE_PRIVATE_TOKENS( + _tokens, + + // Maya material nodes attribute names + (base) + (baseColor) + (emission) + (emissionColor) + (metalness) + (specularColor) + (specularIOR) + (specularRoughness) + (coat) + (coatRoughness) + (transmission) + (normalCamera) +); +// clang-format on + +PxrUsdTranslators_StandardSurfaceReader::PxrUsdTranslators_StandardSurfaceReader( + const UsdMayaPrimReaderArgs& readArgs) + : PxrUsdTranslators_MaterialReader(readArgs) +{ +} + +/* static */ +UsdMayaShaderReader::ContextSupport +PxrUsdTranslators_StandardSurfaceReader::CanImport(const UsdMayaJobImportArgs& importArgs) +{ + // Check to see if import requested conversion + return importArgs.shadingConversion == UsdMayaShadingConversionTokens->standardSurface + ? ContextSupport::Supported + : ContextSupport::Unsupported; +} + +const TfToken& PxrUsdTranslators_StandardSurfaceReader::_GetMayaNodeTypeName() const +{ + return UsdMayaShadingConversionTokens->standardSurface; +} + +void PxrUsdTranslators_StandardSurfaceReader::_ConvertToMaya( + const TfToken& mayaAttrName, + VtValue& usdValue) const +{ + if (mayaAttrName == _tokens->transmission && usdValue.IsHolding()) { + usdValue = 1.0f - usdValue.UncheckedGet(); + } +} + +void PxrUsdTranslators_StandardSurfaceReader::_OnReadAttribute( + const TfToken& mayaAttrName, + MFnDependencyNode& shaderFn) const +{ + MFnStandardSurfaceShader surfaceFn; + surfaceFn.setObject(shaderFn.object()); + if (mayaAttrName == _tokens->baseColor) { + MColor color(surfaceFn.baseColor()); + float scale(surfaceFn.base()); + color /= scale; + surfaceFn.setBaseColor(color); + surfaceFn.setBase(1.0f); + } else if (mayaAttrName == _tokens->emissionColor) { + MColor color(surfaceFn.emissionColor()); + float scale(surfaceFn.emission()); + color /= scale; + surfaceFn.setEmissionColor(color); + surfaceFn.setEmission(1.0f); + } else { + return _BaseClass::_OnReadAttribute(mayaAttrName, shaderFn); + } +} + +/* virtual */ +TfToken +PxrUsdTranslators_StandardSurfaceReader::GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const +{ + TfToken usdInputName; + UsdShadeAttributeType attrType; + std::tie(usdInputName, attrType) = UsdShadeUtils::GetBaseNameAndType(usdAttrName); + + if (attrType == UsdShadeAttributeType::Input) { + if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->DiffuseColorAttrName) { + return _tokens->baseColor; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->EmissiveColorAttrName) { + return _tokens->emissionColor; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->MetallicAttrName) { + return _tokens->metalness; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->SpecularColorAttrName) { + return _tokens->specularColor; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->IorAttrName) { + return _tokens->specularIOR; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->RoughnessAttrName) { + return _tokens->specularRoughness; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->ClearcoatRoughnessAttrName) { + return _tokens->coatRoughness; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->NormalAttrName) { + return _tokens->normalCamera; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->ClearcoatAttrName) { + return _tokens->coat; + } else if (usdInputName == PxrMayaUsdPreviewSurfaceTokens->OpacityAttrName) { + return _tokens->transmission; + } + } + + return _BaseClass::GetMayaNameForUsdAttrName(usdAttrName); +} + +PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/usd/translators/shading/usdStandardSurfaceWriter.cpp b/lib/usd/translators/shading/usdStandardSurfaceWriter.cpp index 4190019708..a02aaa3223 100644 --- a/lib/usd/translators/shading/usdStandardSurfaceWriter.cpp +++ b/lib/usd/translators/shading/usdStandardSurfaceWriter.cpp @@ -140,13 +140,12 @@ void PxrUsdTranslators_StandardSurfaceWriter::Write(const UsdTimeCode& usdTime) PxrMayaUsdPreviewSurfaceTokens->UseSpecularWorkflowAttrName, SdfValueTypeNames->Int) .Set(1, usdTime); - AuthorShaderInputFromScaledShadingNodeAttr( + AuthorShaderInputFromShadingNodeAttr( depNodeFn, _tokens->specularColor, shaderSchema, PxrMayaUsdPreviewSurfaceTokens->SpecularColorAttrName, - usdTime, - _tokens->specular); + usdTime); AuthorShaderInputFromShadingNodeAttr( depNodeFn, diff --git a/lib/usd/translators/shading/usdUVTextureReader.cpp b/lib/usd/translators/shading/usdUVTextureReader.cpp index 406505510e..a79a022cc5 100644 --- a/lib/usd/translators/shading/usdUVTextureReader.cpp +++ b/lib/usd/translators/shading/usdUVTextureReader.cpp @@ -183,7 +183,7 @@ bool PxrMayaUsdUVTexture_Reader::Read(UsdMayaPrimReaderContext* context) // nesting of referenced assets. Use absolute path instead if USD was // able to resolve. A better fix will require providing an asset // resolver to Maya that can resolve the file correctly using the - // MPxAssertResolver API. + // MPxFileResolver API. val = SdfAssetPath(filePath); } mayaAttr = depFn.findPlug(_tokens->fileTextureName.GetText(), true, &status); diff --git a/plugin/adsk/scripts/mayaUsdTranslatorImport.mel b/plugin/adsk/scripts/mayaUsdTranslatorImport.mel index e052496d33..db8563cbcf 100644 --- a/plugin/adsk/scripts/mayaUsdTranslatorImport.mel +++ b/plugin/adsk/scripts/mayaUsdTranslatorImport.mel @@ -138,6 +138,19 @@ global proc int mayaUsdTranslatorImport (string $parent, } mayaUsdTranslatorImport_SetOptionMenuByAnnotation("useRegistry", "mayaUsdTranslator_MaterialsOptionMenu"); + optionMenuGrp -l "Material Conversion:" -cw 1 $cw1 mayaUsdTranslator_MaterialsConversionMenu; + menuItem -l "No Conversion" -ann "none"; + menuItem -l "To Lambert" -ann "lambert"; + string $apiString = `about -q -apiVersion`; + $apiString = `substring $apiString 1 4`; + if ((int)$apiString >= 2020) { + menuItem -l "To Standard Surface" -ann "standardSurface"; + } + menuItem -l "To Blinn" -ann "blinn"; + menuItem -l "To Phong" -ann "phong"; + menuItem -l "To Phong Explorer" -ann "phongE"; + mayaUsdTranslatorImport_SetOptionMenuByAnnotation("none", "mayaUsdTranslator_MaterialsConversionMenu"); + // checkBoxGrp -label "InstancedPrims: " -label1 "Convert to Instances" -cw 1 $cw1 mayaUsdTranslator_InstancedPrimsCheckBox; // // optionMenuGrp -label "Include Metadata: " -cw 1 $cw1 mayaUsdTranslator_IncludeMetadataOptionMenu; @@ -173,6 +186,8 @@ global proc int mayaUsdTranslatorImport (string $parent, tokenize($optionList[$index], "=", $optionBreakDown); if ($optionBreakDown[0] == "shadingMode") { mayaUsdTranslatorImport_SetOptionMenuByAnnotation($optionBreakDown[1], "mayaUsdTranslator_MaterialsOptionMenu"); + } else if ($optionBreakDown[0] == "shadingConversion") { + mayaUsdTranslatorImport_SetOptionMenuByAnnotation($optionBreakDown[1], "mayaUsdTranslator_MaterialsConversionMenu"); } else if ($optionBreakDown[0] == "readAnimData") { mayaUsdTranslatorImport_SetCheckBoxGrp($optionBreakDown[1], "mayaUsdTranslator_AnimDataCheckBox"); } else if ($optionBreakDown[0] == "startTime") { @@ -192,6 +207,7 @@ global proc int mayaUsdTranslatorImport (string $parent, } else if ($action == "query") { string $currentOptions = ""; $currentOptions = mayaUsdTranslatorImport_AppendFromPopup($currentOptions, "shadingMode", "mayaUsdTranslator_MaterialsOptionMenu"); + $currentOptions = mayaUsdTranslatorImport_AppendFromPopup($currentOptions, "shadingConversion", "mayaUsdTranslator_MaterialsConversionMenu"); $currentOptions = mayaUsdTranslatorImport_AppendFromDialog($currentOptions, "primPath", "-primPath"); $currentOptions = mayaUsdTranslatorImport_AppendFromCheckBoxGrp($currentOptions, "readAnimData", "mayaUsdTranslator_AnimDataCheckBox"); $currentOptions = mayaUsdTranslatorImport_AppendFromCheckBoxGrp($currentOptions, "useCustomFrameRange", "mayaUsdTranslator_CustomFrameRangeCheckBox"); diff --git a/plugin/pxr/doc/README.md b/plugin/pxr/doc/README.md index b30d874e13..2106c5bb28 100644 --- a/plugin/pxr/doc/README.md +++ b/plugin/pxr/doc/README.md @@ -38,7 +38,8 @@ The plugin creates two commands: `usdImport` and `usdExport`, and will also regi | `-p` | `-parent` | string | none | Name of the Maya scope that will be the parent of the imported data. | | `-pp` | `-primPath` | string | none (defaultPrim) | Name of the USD scope where traversing will being. The prim at the specified primPath (including the prim) will be imported. Specifying the pseudo-root (`/`) means you want to import everything in the file. If the passed prim path is empty, it will first try to import the defaultPrim for the rootLayer if it exists. Otherwise, it will behave as if the pseudo-root was passed in. | | `-ani` | `-readAnimData` | bool | false | Read animation data from prims while importing the specified USD file. If the USD file being imported specifies `startTimeCode` and/or `endTimeCode`, Maya's MinTime and/or MaxTime will be expanded if necessary to include that frame range. **Note**: Only some types of animation are currently supported, for example: animated visibility, animated transforms, animated cameras, mesh and NURBS surface animation via blend shape deformers. Other types are not yet supported, for example: time-varying curve points, time-varying mesh points/normals, time-varying NURBS surface points | -| `-shd` | `-shadingMode` | string | `displayColor` | Enable importing of materials according to a defined shading mode. Allowed values are: `none` (extract no shading data from the USD), `displayColor` (if there are bound materials in the USD, create corresponding Lambertian shaders and bind them to the appropriate Maya geometry nodes), `pxrRis` (attempt to reconstruct a Maya shading network from (presumed) Renderman RIS shading networks in the USD) | +| `-shd` | `-shadingMode` | string | `displayColor` | Enable importing of materials according to a defined shading mode. Allowed values are: `none` (extract no shading data from the USD), `displayColor` (if there are bound materials in the USD, create corresponding Lambertian shaders and bind them to the appropriate Maya geometry nodes), `pxrRis` (attempt to reconstruct a Maya shading network from (presumed) Renderman RIS shading networks in the USD), `useRegistry` (attempt to reconstruct a Maya shading network from (presumed) UsdPreviewSurface shading networks in the USD) | +| `-shc` | `-shadingConversion` | string | `lambert` | Enable conversion of foreign surface materials to a single type of Maya native surface material. Allowed values are `none` (prefer plugin nodes like pxrUsdPreviewSurface and aiStandardSurface) or one of `lambert`, `standardSurface`, `blinn`, `phong`, `phongE`. In displayColor shading mode, a value of `none` will default to `lambert`. | `-uac` | `-useAsAnimationCache` | bool | false | Imports geometry prims with time-sampled point data using a point-based deformer node that references the imported USD file. When this parameter is enabled, `usdImport` will create a `pxrUsdStageNode` for the USD file that is being imported. Then for each geometry prim being imported that has time-sampled points, a `pxrUsdPointBasedDeformerNode` will be created that reads the points for that prim from USD and uses them to deform the imported Maya geometry. This provides better import and playback performance when importing time-sampled geometry from USD, and it should reduce the weight of the resulting Maya scene since it will bypass creating blend shape deformers with per-object, per-time sample geometry. Only point data from the geometry prim will be computed by the deformer from the referenced USD. Transform data from the geometry prim will still be imported into native Maya form on the Maya shape's transform node. **Note**: This means that a link is created between the resulting Maya scene and the USD file that was imported. With this parameter off (as is the default), the USD file that was imported can be freely changed or deleted post-import. With the parameter on, however, the Maya scene will have a dependency on that USD file, as well as other layers that it may reference. Currently, this functionality is only implemented for Mesh prims/Maya mesh nodes. | | `-var` | `-variant` | string[2] | none | Set variant key value pairs | diff --git a/test/lib/usd/translators/testUsdExportImportRoundtripPreviewSurface.py b/test/lib/usd/translators/testUsdExportImportRoundtripPreviewSurface.py index e998ceaa76..5248f65ee5 100644 --- a/test/lib/usd/translators/testUsdExportImportRoundtripPreviewSurface.py +++ b/test/lib/usd/translators/testUsdExportImportRoundtripPreviewSurface.py @@ -102,10 +102,13 @@ def testPxrUsdPreviewSurfaceRoundtrip(self): cmds.file(defaultExtensions=default_ext_setting) # Import back: + import_options = ("shadingMode=useRegistry", + "shadingConversion=none", + "primPath=/") cmds.file(usd_path, i=True, type="USD Import", ignoreVersion=True, ra=True, mergeNamespacesOnClash=False, namespace="Test", pr=True, importTimeRange="combine", - options=";shadingMode=useRegistry;primPath=/") + options=";".join(import_options)) # Check the new sphere is in the new shading group: self.assertTrue(cmds.sets( diff --git a/test/lib/usd/translators/testUsdImportPreviewSurface.py b/test/lib/usd/translators/testUsdImportPreviewSurface.py index 142e4b2d89..6ea2251f5e 100644 --- a/test/lib/usd/translators/testUsdImportPreviewSurface.py +++ b/test/lib/usd/translators/testUsdImportPreviewSurface.py @@ -46,10 +46,13 @@ def testImportReferenceWithRelativeFilePath(self): cmds.file(f=True, new=True) usd_path = os.path.join(self.test_dir, "world.usda") + options = ["shadingMode=useRegistry", + "primPath=/", + "shadingConversion=none"] cmds.file(usd_path, i=True, type="USD Import", ignoreVersion=True, ra=True, mergeNamespacesOnClash=False, namespace="Test", pr=True, importTimeRange="combine", - options=";shadingMode=useRegistry;primPath=/") + options=";".join(options)) # Check that all paths are absolute: green_a = "props/billboards/textures/green_A.png" @@ -72,6 +75,19 @@ def testImportReferenceWithRelativeFilePath(self): self.assertEqual(filename.lower().replace("\\", "/"), rebased_name.lower().replace("\\", "/")) + # We expect pxrUsdPreviewSurface shaders: + self.assertEqual(len(cmds.ls(typ="pxrUsdPreviewSurface")), 8) + + # Re-import, but with lamberts: + lambert_before = len(cmds.ls(typ="lambert")) + options = options[:-1] + options.append("shadingConversion=lambert") + cmds.file(usd_path, i=True, type="USD Import", + ignoreVersion=True, ra=True, mergeNamespacesOnClash=False, + namespace="Test", pr=True, importTimeRange="combine", + options=";".join(options)) + + self.assertEqual(len(cmds.ls(typ="lambert")), lambert_before + 8) if __name__ == '__main__': unittest.main(verbosity=2) From 9055a0fcaa24ab339d62c2d7ada6509d5369b54a Mon Sep 17 00:00:00 2001 From: JGamache-autodesk Date: Wed, 12 Aug 2020 21:42:18 -0400 Subject: [PATCH 2/3] MAYA-104987 Fix OS/X build --- lib/usd/translators/shading/usdBlinnReader.cpp | 2 +- lib/usd/translators/shading/usdLambertReader.h | 2 +- lib/usd/translators/shading/usdMaterialReader.h | 2 +- lib/usd/translators/shading/usdPhongEReader.cpp | 2 +- lib/usd/translators/shading/usdPhongReader.cpp | 2 +- lib/usd/translators/shading/usdStandardSurfaceReader.cpp | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/usd/translators/shading/usdBlinnReader.cpp b/lib/usd/translators/shading/usdBlinnReader.cpp index 595b18833d..0883ab79e7 100644 --- a/lib/usd/translators/shading/usdBlinnReader.cpp +++ b/lib/usd/translators/shading/usdBlinnReader.cpp @@ -56,7 +56,7 @@ class PxrUsdTranslators_BlinnReader : public PxrUsdTranslators_LambertReader { /// Get the name of the Maya shading attribute that corresponds to the /// USD attribute named \p usdAttrName. - virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const override; protected: /// What is the Maya node type name we want to convert to: diff --git a/lib/usd/translators/shading/usdLambertReader.h b/lib/usd/translators/shading/usdLambertReader.h index 74a1e536e6..4a890e1d1f 100644 --- a/lib/usd/translators/shading/usdLambertReader.h +++ b/lib/usd/translators/shading/usdLambertReader.h @@ -37,7 +37,7 @@ class PxrUsdTranslators_LambertReader : public PxrUsdTranslators_MaterialReader /// Get the name of the Maya shading attribute that corresponds to the /// USD attribute named \p usdAttrName. - virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const override; protected: const TfToken& _GetMayaNodeTypeName() const override; diff --git a/lib/usd/translators/shading/usdMaterialReader.h b/lib/usd/translators/shading/usdMaterialReader.h index ed945a334b..6898093526 100644 --- a/lib/usd/translators/shading/usdMaterialReader.h +++ b/lib/usd/translators/shading/usdMaterialReader.h @@ -38,7 +38,7 @@ class PxrUsdTranslators_MaterialReader : public UsdMayaShaderReader { /// Get the name of the Maya shading attribute that corresponds to the /// USD attribute named \p usdAttrName. - virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const override; /// Generic read function that traverses a schema and reads everything. bool Read(UsdMayaPrimReaderContext* context) override; diff --git a/lib/usd/translators/shading/usdPhongEReader.cpp b/lib/usd/translators/shading/usdPhongEReader.cpp index 96cebdd58a..b4a6bdb856 100644 --- a/lib/usd/translators/shading/usdPhongEReader.cpp +++ b/lib/usd/translators/shading/usdPhongEReader.cpp @@ -55,7 +55,7 @@ class PxrUsdTranslators_PhongEReader : public PxrUsdTranslators_LambertReader { /// Get the name of the Maya shading attribute that corresponds to the /// USD attribute named \p usdAttrName. - virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const override; protected: /// What is the Maya node type name we want to convert to: diff --git a/lib/usd/translators/shading/usdPhongReader.cpp b/lib/usd/translators/shading/usdPhongReader.cpp index 2dd763d1d0..a45bce1786 100644 --- a/lib/usd/translators/shading/usdPhongReader.cpp +++ b/lib/usd/translators/shading/usdPhongReader.cpp @@ -55,7 +55,7 @@ class PxrUsdTranslators_PhongReader : public PxrUsdTranslators_LambertReader { /// Get the name of the Maya shading attribute that corresponds to the /// USD attribute named \p usdAttrName. - virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const override; protected: /// What is the Maya node type name we want to convert to: diff --git a/lib/usd/translators/shading/usdStandardSurfaceReader.cpp b/lib/usd/translators/shading/usdStandardSurfaceReader.cpp index 3f5af502b1..219ae8e0f4 100644 --- a/lib/usd/translators/shading/usdStandardSurfaceReader.cpp +++ b/lib/usd/translators/shading/usdStandardSurfaceReader.cpp @@ -56,7 +56,7 @@ class PxrUsdTranslators_StandardSurfaceReader : public PxrUsdTranslators_Materia /// Get the name of the Maya shading attribute that corresponds to the /// USD attribute named \p usdAttrName. - virtual TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const; + TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const override; protected: const TfToken& _GetMayaNodeTypeName() const override; From 8412e3d3a3431125768ea896fe343978779aec07 Mon Sep 17 00:00:00 2001 From: JGamache-autodesk Date: Tue, 25 Aug 2020 18:28:10 -0400 Subject: [PATCH 3/3] MAYA-104987 Updates from review comments --- lib/mayaUsd/fileio/shaderReader.h | 6 +++--- lib/mayaUsd/fileio/shaderReaderRegistry.cpp | 10 +++++++--- lib/mayaUsd/fileio/shaderReaderRegistry.h | 6 +++--- .../shading/shadingModeDisplayColor.cpp | 3 --- .../translators/shading/usdBlinnReader.cpp | 13 +++++++----- .../translators/shading/usdLambertReader.cpp | 4 ++-- .../translators/shading/usdLambertReader.h | 10 +++++++--- .../translators/shading/usdMaterialReader.cpp | 6 +++--- .../translators/shading/usdMaterialReader.h | 10 +++++----- .../translators/shading/usdPhongEReader.cpp | 4 ++-- .../translators/shading/usdPhongReader.cpp | 6 ++++-- .../shading/usdStandardSurfaceReader.cpp | 20 +++++++++++++------ 12 files changed, 58 insertions(+), 40 deletions(-) diff --git a/lib/mayaUsd/fileio/shaderReader.h b/lib/mayaUsd/fileio/shaderReader.h index a7aaefe7a4..e04e2c33ae 100644 --- a/lib/mayaUsd/fileio/shaderReader.h +++ b/lib/mayaUsd/fileio/shaderReader.h @@ -39,13 +39,13 @@ class UsdMayaShaderReader : public UsdMayaPrimReader { /// The level of support a reader can offer for a given context /// - /// A basic writer that gives correct results across most contexts should - /// report `Fallback`, while a specialized writer that really shines in a + /// 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 writers and allows + /// 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); diff --git a/lib/mayaUsd/fileio/shaderReaderRegistry.cpp b/lib/mayaUsd/fileio/shaderReaderRegistry.cpp index a9ae484e89..b5d3f90bef 100644 --- a/lib/mayaUsd/fileio/shaderReaderRegistry.cpp +++ b/lib/mayaUsd/fileio/shaderReaderRegistry.cpp @@ -28,8 +28,8 @@ #include #include -#include #include +#include #include PXR_NAMESPACE_OPEN_SCOPE @@ -63,6 +63,7 @@ _Registry::const_iterator _Find( ContextSupport support = first->second._pred(importArgs); if (support == ContextSupport::Supported) { ret = first; + break; } else if (support == ContextSupport::Fallback && ret == _reg.end()) { ret = first; } @@ -79,10 +80,13 @@ void UsdMayaShaderReaderRegistry::Register( UsdMayaShaderReaderRegistry::ContextPredicateFn pred, UsdMayaShaderReaderRegistry::ReaderFactoryFn fn) { + int index = _indexCounter++; TF_DEBUG(PXRUSDMAYA_REGISTRY) - .Msg("Registering UsdMayaShaderReader for info:id %s.\n", usdInfoId.GetText()); + .Msg( + "Registering UsdMayaShaderReader for info:id %s with index %d.\n", + usdInfoId.GetText(), + index); - int index = _indexCounter++; _reg.insert(std::make_pair(usdInfoId, _RegistryEntry{pred, fn, index})); // The unloader uses the index to know which entry to erase when there are diff --git a/lib/mayaUsd/fileio/shaderReaderRegistry.h b/lib/mayaUsd/fileio/shaderReaderRegistry.h index 923b5f6d62..a462bb44ab 100644 --- a/lib/mayaUsd/fileio/shaderReaderRegistry.h +++ b/lib/mayaUsd/fileio/shaderReaderRegistry.h @@ -60,12 +60,12 @@ PXR_NAMESPACE_OPEN_SCOPE struct UsdMayaShaderReaderRegistry { /// Predicate function, i.e. a function that can tell the level of support /// the reader function will provide for a given context. - typedef std::function - ContextPredicateFn; + using ContextPredicateFn + = std::function; /// Reader factory function, i.e. a function that creates a prim reader /// for the given prim reader args. - typedef std::function ReaderFactoryFn; + using ReaderFactoryFn = std::function; /// \brief Register \p fn as a factory function providing a /// UsdMayaShaderReader subclass that can be used to read \p usdInfoId. diff --git a/lib/mayaUsd/fileio/shading/shadingModeDisplayColor.cpp b/lib/mayaUsd/fileio/shading/shadingModeDisplayColor.cpp index 663d59e175..ac1c9c0ad4 100644 --- a/lib/mayaUsd/fileio/shading/shadingModeDisplayColor.cpp +++ b/lib/mayaUsd/fileio/shading/shadingModeDisplayColor.cpp @@ -350,7 +350,6 @@ DEFINE_SHADING_MODE_IMPORTER_WITH_JOB_ARGUMENTS(displayColor, context, jobArgume &status, &shadingObj); if (status != MS::kSuccess) { - // we need to make sure assumes those types are loaded.. TF_RUNTIME_ERROR( "Could not create node of type '%s' for prim '%s'.\n", shadingConversion.GetText(), @@ -364,7 +363,6 @@ DEFINE_SHADING_MODE_IMPORTER_WITH_JOB_ARGUMENTS(displayColor, context, jobArgume #endif MFnLambertShader lambertFn; lambertFn.setObject(shadingObj); - lambertFn.setName(shaderName.c_str()); lambertFn.setColor( MColor(displayColor[0], displayColor[1], displayColor[2])); lambertFn.setTransparency( @@ -386,7 +384,6 @@ DEFINE_SHADING_MODE_IMPORTER_WITH_JOB_ARGUMENTS(displayColor, context, jobArgume } else { MFnStandardSurfaceShader surfaceFn; surfaceFn.setObject(shadingObj); - surfaceFn.setName(shaderName.c_str()); surfaceFn.setBase(1.0f); surfaceFn.setBaseColor( MColor(displayColor[0], displayColor[1], displayColor[2])); diff --git a/lib/usd/translators/shading/usdBlinnReader.cpp b/lib/usd/translators/shading/usdBlinnReader.cpp index 0883ab79e7..c697f3ed7a 100644 --- a/lib/usd/translators/shading/usdBlinnReader.cpp +++ b/lib/usd/translators/shading/usdBlinnReader.cpp @@ -45,9 +45,9 @@ PXR_NAMESPACE_OPEN_SCOPE -/// Shader writer for importing UsdPreviewSurface to Maya's lambert material nodes +/// Shader reader for importing UsdPreviewSurface to Maya's blinn material nodes class PxrUsdTranslators_BlinnReader : public PxrUsdTranslators_LambertReader { - typedef PxrUsdTranslators_LambertReader _BaseClass; + using _BaseClass = PxrUsdTranslators_LambertReader; public: PxrUsdTranslators_BlinnReader(const UsdMayaPrimReaderArgs&); @@ -62,7 +62,10 @@ class PxrUsdTranslators_BlinnReader : public PxrUsdTranslators_LambertReader { /// What is the Maya node type name we want to convert to: const TfToken& _GetMayaNodeTypeName() const override; - void _OnReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const override; + /// Callback called before the attribute \p mayaAttribute is read from UsdShade. This allows + /// setting back values in \p shaderFn that were lost during the export phase. + void + _OnBeforeReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const override; }; PXRUSDMAYA_REGISTER_SHADER_READER(UsdPreviewSurface, PxrUsdTranslators_BlinnReader); @@ -96,7 +99,7 @@ const TfToken& PxrUsdTranslators_BlinnReader::_GetMayaNodeTypeName() const return UsdMayaShadingConversionTokens->blinn; } -void PxrUsdTranslators_BlinnReader::_OnReadAttribute( +void PxrUsdTranslators_BlinnReader::_OnBeforeReadAttribute( const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const { @@ -109,7 +112,7 @@ void PxrUsdTranslators_BlinnReader::_OnReadAttribute( blinnFn.setSpecularColor(color); blinnFn.setSpecularRollOff(1.0f); } else { - return _BaseClass::_OnReadAttribute(mayaAttrName, shaderFn); + _BaseClass::_OnBeforeReadAttribute(mayaAttrName, shaderFn); } } diff --git a/lib/usd/translators/shading/usdLambertReader.cpp b/lib/usd/translators/shading/usdLambertReader.cpp index edcebe35cd..1082ca2ddd 100644 --- a/lib/usd/translators/shading/usdLambertReader.cpp +++ b/lib/usd/translators/shading/usdLambertReader.cpp @@ -78,7 +78,7 @@ const TfToken& PxrUsdTranslators_LambertReader::_GetMayaNodeTypeName() const return UsdMayaShadingConversionTokens->lambert; } -void PxrUsdTranslators_LambertReader::_OnReadAttribute( +void PxrUsdTranslators_LambertReader::_OnBeforeReadAttribute( const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const { @@ -91,7 +91,7 @@ void PxrUsdTranslators_LambertReader::_OnReadAttribute( lambertFn.setColor(color); lambertFn.setDiffuseCoeff(1.0f); } else { - return _BaseClass::_OnReadAttribute(mayaAttrName, shaderFn); + _BaseClass::_OnBeforeReadAttribute(mayaAttrName, shaderFn); } } diff --git a/lib/usd/translators/shading/usdLambertReader.h b/lib/usd/translators/shading/usdLambertReader.h index 4a890e1d1f..cedfea91e6 100644 --- a/lib/usd/translators/shading/usdLambertReader.h +++ b/lib/usd/translators/shading/usdLambertReader.h @@ -26,9 +26,9 @@ PXR_NAMESPACE_OPEN_SCOPE -/// Shader writer for importing UsdPreviewSurface to Maya's lambert material nodes +/// Shader reader for importing UsdPreviewSurface to Maya's lambert material nodes class PxrUsdTranslators_LambertReader : public PxrUsdTranslators_MaterialReader { - typedef PxrUsdTranslators_MaterialReader _BaseClass; + using _BaseClass = PxrUsdTranslators_MaterialReader; public: PxrUsdTranslators_LambertReader(const UsdMayaPrimReaderArgs&); @@ -40,9 +40,13 @@ class PxrUsdTranslators_LambertReader : public PxrUsdTranslators_MaterialReader TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const override; protected: + /// What is the Maya node type name we want to convert to: const TfToken& _GetMayaNodeTypeName() const override; - void _OnReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const override; + /// Callback called before the attribute \p mayaAttribute is read from UsdShade. This allows + /// setting back values in \p shaderFn that were lost during the export phase. + void + _OnBeforeReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const override; }; PXR_NAMESPACE_CLOSE_SCOPE diff --git a/lib/usd/translators/shading/usdMaterialReader.cpp b/lib/usd/translators/shading/usdMaterialReader.cpp index 919261395f..3302870f01 100644 --- a/lib/usd/translators/shading/usdMaterialReader.cpp +++ b/lib/usd/translators/shading/usdMaterialReader.cpp @@ -74,7 +74,6 @@ bool PxrUsdTranslators_MaterialReader::Read(UsdMayaPrimReaderContext* context) &status, &mayaObject) && depFn.setObject(mayaObject))) { - // we need to make sure assumes those types are loaded.. TF_RUNTIME_ERROR( "Could not create node of type '%s' for shader '%s'.\n", mayaNodeTypeName.GetText(), @@ -89,7 +88,7 @@ bool PxrUsdTranslators_MaterialReader::Read(UsdMayaPrimReaderContext* context) if (baseName.IsEmpty()) { continue; } - _OnReadAttribute(baseName, depFn); + _OnBeforeReadAttribute(baseName, depFn); MPlug mayaAttr = depFn.findPlug(baseName.GetText(), true, &status); if (status != MS::kSuccess) { continue; @@ -127,7 +126,8 @@ void PxrUsdTranslators_MaterialReader::_ConvertToMaya(const TfToken&, VtValue&) return; } -void PxrUsdTranslators_MaterialReader::_OnReadAttribute(const TfToken&, MFnDependencyNode&) const +void PxrUsdTranslators_MaterialReader::_OnBeforeReadAttribute(const TfToken&, MFnDependencyNode&) + const { // Nothing to do return; diff --git a/lib/usd/translators/shading/usdMaterialReader.h b/lib/usd/translators/shading/usdMaterialReader.h index 6898093526..652d06c429 100644 --- a/lib/usd/translators/shading/usdMaterialReader.h +++ b/lib/usd/translators/shading/usdMaterialReader.h @@ -31,7 +31,7 @@ class TfToken; struct UsdMayaJobImportArgs; class UsdShadeShader; -/// Shader writer for importing UsdPreviewSurface to Maya's native material nodes +/// Shader reader for importing UsdPreviewSurface to Maya's native material nodes class PxrUsdTranslators_MaterialReader : public UsdMayaShaderReader { public: PxrUsdTranslators_MaterialReader(const UsdMayaPrimReaderArgs&); @@ -47,10 +47,10 @@ class PxrUsdTranslators_MaterialReader : public UsdMayaShaderReader { /// What is the Maya node type name we want to convert to: virtual const TfToken& _GetMayaNodeTypeName() const = 0; - /// Allows setting values on attributes indirectly affected by attribute - /// \p mayaAttribute. This allows setting back values in \p shaderFn that - /// were lost during the export phase. - virtual void _OnReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const; + /// Callback called before the attribute \p mayaAttribute is read from UsdShade. This allows + /// setting back values in \p shaderFn that were lost during the export phase. + virtual void + _OnBeforeReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const; /// Convert the value in \p usdValue from USD back to Maya following rules /// for attribute \p mayaAttrName diff --git a/lib/usd/translators/shading/usdPhongEReader.cpp b/lib/usd/translators/shading/usdPhongEReader.cpp index b4a6bdb856..428f0aa9c8 100644 --- a/lib/usd/translators/shading/usdPhongEReader.cpp +++ b/lib/usd/translators/shading/usdPhongEReader.cpp @@ -44,9 +44,9 @@ PXR_NAMESPACE_OPEN_SCOPE -/// Shader writer for importing UsdPreviewSurface to Maya's lambert material nodes +/// Shader reader for importing UsdPreviewSurface to Maya's phongE material nodes class PxrUsdTranslators_PhongEReader : public PxrUsdTranslators_LambertReader { - typedef PxrUsdTranslators_LambertReader _BaseClass; + using _BaseClass = PxrUsdTranslators_LambertReader; public: PxrUsdTranslators_PhongEReader(const UsdMayaPrimReaderArgs&); diff --git a/lib/usd/translators/shading/usdPhongReader.cpp b/lib/usd/translators/shading/usdPhongReader.cpp index a45bce1786..119a13e0d8 100644 --- a/lib/usd/translators/shading/usdPhongReader.cpp +++ b/lib/usd/translators/shading/usdPhongReader.cpp @@ -44,9 +44,9 @@ PXR_NAMESPACE_OPEN_SCOPE -/// Shader writer for importing UsdPreviewSurface to Maya's lambert material nodes +/// Shader reader for importing UsdPreviewSurface to Maya's phong material nodes class PxrUsdTranslators_PhongReader : public PxrUsdTranslators_LambertReader { - typedef PxrUsdTranslators_LambertReader _BaseClass; + using _BaseClass = PxrUsdTranslators_LambertReader; public: PxrUsdTranslators_PhongReader(const UsdMayaPrimReaderArgs&); @@ -61,6 +61,8 @@ class PxrUsdTranslators_PhongReader : public PxrUsdTranslators_LambertReader { /// What is the Maya node type name we want to convert to: const TfToken& _GetMayaNodeTypeName() const override; + /// Convert the value in \p usdValue from USD back to Maya following rules + /// for attribute \p mayaAttrName void _ConvertToMaya(const TfToken& mayaAttrName, VtValue& usdValue) const override; }; diff --git a/lib/usd/translators/shading/usdStandardSurfaceReader.cpp b/lib/usd/translators/shading/usdStandardSurfaceReader.cpp index 219ae8e0f4..08750477b3 100644 --- a/lib/usd/translators/shading/usdStandardSurfaceReader.cpp +++ b/lib/usd/translators/shading/usdStandardSurfaceReader.cpp @@ -45,9 +45,9 @@ PXR_NAMESPACE_OPEN_SCOPE -/// Shader writer for importing UsdPreviewSurface to Maya's lambert material nodes +/// Shader reader for importing UsdPreviewSurface to Maya's standardSurface material nodes class PxrUsdTranslators_StandardSurfaceReader : public PxrUsdTranslators_MaterialReader { - typedef PxrUsdTranslators_MaterialReader _BaseClass; + using _BaseClass = PxrUsdTranslators_MaterialReader; public: PxrUsdTranslators_StandardSurfaceReader(const UsdMayaPrimReaderArgs&); @@ -59,9 +59,17 @@ class PxrUsdTranslators_StandardSurfaceReader : public PxrUsdTranslators_Materia TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const override; protected: + /// What is the Maya node type name we want to convert to: const TfToken& _GetMayaNodeTypeName() const override; - void _ConvertToMaya(const TfToken& mayaAttrName, VtValue& usdValue) const override; - void _OnReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const override; + + /// Convert the value in \p usdValue from USD back to Maya following rules + /// for attribute \p mayaAttrName + void _ConvertToMaya(const TfToken& mayaAttrName, VtValue& usdValue) const override; + + /// Callback called before the attribute \p mayaAttribute is read from UsdShade. This allows + /// setting back values in \p shaderFn that were lost during the export phase. + void + _OnBeforeReadAttribute(const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const override; }; PXRUSDMAYA_REGISTER_SHADER_READER(UsdPreviewSurface, PxrUsdTranslators_StandardSurfaceReader); @@ -116,7 +124,7 @@ void PxrUsdTranslators_StandardSurfaceReader::_ConvertToMaya( } } -void PxrUsdTranslators_StandardSurfaceReader::_OnReadAttribute( +void PxrUsdTranslators_StandardSurfaceReader::_OnBeforeReadAttribute( const TfToken& mayaAttrName, MFnDependencyNode& shaderFn) const { @@ -135,7 +143,7 @@ void PxrUsdTranslators_StandardSurfaceReader::_OnReadAttribute( surfaceFn.setEmissionColor(color); surfaceFn.setEmission(1.0f); } else { - return _BaseClass::_OnReadAttribute(mayaAttrName, shaderFn); + _BaseClass::_OnBeforeReadAttribute(mayaAttrName, shaderFn); } }