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 b367c59aac..1e648a5e16 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..e04e2c33ae 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 reader that gives correct results across most contexts should + /// report `Fallback`, while a specialized reader that really shines in a + /// given context should report `Supported` when the context is right and + /// `Unsupported` if the context is not as expected. + enum class ContextSupport { Supported, Fallback, Unsupported }; + + /// This static function is expected for all shader readers and allows + /// declaring how well this class can support the current context: + MAYAUSD_CORE_PUBLIC + static ContextSupport CanImport(const UsdMayaJobImportArgs& importArgs); + /// Get the 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..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 @@ -40,51 +40,102 @@ 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; + break; + } 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) { + 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); - 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()); - } + _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..a462bb44ab 100644 --- a/lib/mayaUsd/fileio/shaderReaderRegistry.h +++ b/lib/mayaUsd/fileio/shaderReaderRegistry.h @@ -58,14 +58,14 @@ 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. + 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; - - /// 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; + using ReaderFactoryFn = std::function; /// \brief Register \p fn as a factory function providing a /// UsdMayaShaderReader subclass that can be used to read \p usdInfoId. @@ -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..ac1c9c0ad4 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,83 @@ 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) { + 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.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.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 d821c018a2..a2a50f56a7 100644 --- a/lib/mayaUsd/fileio/shading/shadingModeRegistry.h +++ b/lib/mayaUsd/fileio/shading/shadingModeRegistry.h @@ -43,6 +43,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..c697f3ed7a --- /dev/null +++ b/lib/usd/translators/shading/usdBlinnReader.cpp @@ -0,0 +1,137 @@ +// +// 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 reader for importing UsdPreviewSurface to Maya's blinn material nodes +class PxrUsdTranslators_BlinnReader : public PxrUsdTranslators_LambertReader { + using _BaseClass = PxrUsdTranslators_LambertReader; + +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. + 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; + + /// 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); + +// 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::_OnBeforeReadAttribute( + 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 { + _BaseClass::_OnBeforeReadAttribute(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..1082ca2ddd --- /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::_OnBeforeReadAttribute( + 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 { + _BaseClass::_OnBeforeReadAttribute(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..cedfea91e6 --- /dev/null +++ b/lib/usd/translators/shading/usdLambertReader.h @@ -0,0 +1,54 @@ +// +// 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 reader for importing UsdPreviewSurface to Maya's lambert material nodes +class PxrUsdTranslators_LambertReader : public PxrUsdTranslators_MaterialReader { + using _BaseClass = PxrUsdTranslators_MaterialReader; + +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. + 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; + + /// 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 + +#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..3302870f01 --- /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))) { + 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; + } + _OnBeforeReadAttribute(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::_OnBeforeReadAttribute(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..652d06c429 --- /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 reader 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. + TfToken GetMayaNameForUsdAttrName(const TfToken& usdAttrName) const override; + + /// 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; + + /// 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 + 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..428f0aa9c8 --- /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 reader for importing UsdPreviewSurface to Maya's phongE material nodes +class PxrUsdTranslators_PhongEReader : public PxrUsdTranslators_LambertReader { + using _BaseClass = PxrUsdTranslators_LambertReader; + +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. + 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; +}; + +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..119a13e0d8 --- /dev/null +++ b/lib/usd/translators/shading/usdPhongReader.cpp @@ -0,0 +1,130 @@ +// +// 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 reader for importing UsdPreviewSurface to Maya's phong material nodes +class PxrUsdTranslators_PhongReader : public PxrUsdTranslators_LambertReader { + using _BaseClass = PxrUsdTranslators_LambertReader; + +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. + 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; + + /// 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; +}; + +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..08750477b3 --- /dev/null +++ b/lib/usd/translators/shading/usdStandardSurfaceReader.cpp @@ -0,0 +1,185 @@ +// +// 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 reader for importing UsdPreviewSurface to Maya's standardSurface material nodes +class PxrUsdTranslators_StandardSurfaceReader : public PxrUsdTranslators_MaterialReader { + using _BaseClass = PxrUsdTranslators_MaterialReader; + +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. + 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; + + /// 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); + +// 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::_OnBeforeReadAttribute( + 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 { + _BaseClass::_OnBeforeReadAttribute(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 329ed13c31..16f73bae5c 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)