diff --git a/pxr/imaging/hdSt/materialXFilter.cpp b/pxr/imaging/hdSt/materialXFilter.cpp index 8897c5e72..975017525 100644 --- a/pxr/imaging/hdSt/materialXFilter.cpp +++ b/pxr/imaging/hdSt/materialXFilter.cpp @@ -634,26 +634,48 @@ _GetGlTFSurfaceMaterialTag(HdMaterialNode2 const& terminal) return materialToken.GetString(); } -static const mx::TypeDesc* +static const mx::TypeDesc _GetMxTypeDescription(std::string const& typeName) { +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION==38 + // Add whatever is necessary for current codebase: + static const auto _typeLibrary = + std::map{ + {"float", mx::Type::FLOAT}, + {"color3", mx::Type::COLOR3}, + {"color4", mx::Type::COLOR4}, + {"vector2", mx::Type::VECTOR2}, + {"vector3", mx::Type::VECTOR3}, + {"vector4", mx::Type::VECTOR4}, + {"surfaceshader", mx::Type::SURFACESHADER} + }; + + const auto typeDescIt = _typeLibrary.find(typeName); + if (typeDescIt != _typeLibrary.end()) { + return *(typeDescIt->second); + } + + return *mx::Type::NONE; +#else // Add whatever is necessary for current codebase: - static const auto _typeLibrary = - std::map{ - {"float", mx::Type::FLOAT}, - {"color3", mx::Type::COLOR3}, - {"color4", mx::Type::COLOR4}, - {"vector2", mx::Type::VECTOR2}, - {"vector3", mx::Type::VECTOR3}, - {"vector4", mx::Type::VECTOR4}, - {"surfaceshader", mx::Type::SURFACESHADER} + static const auto _typeLibrary = + std::map{ + {"float", mx::Type::FLOAT}, + {"color3", mx::Type::COLOR3}, + {"color4", mx::Type::COLOR4}, + {"vector2", mx::Type::VECTOR2}, + {"vector3", mx::Type::VECTOR3}, + {"vector4", mx::Type::VECTOR4}, + {"surfaceshader", mx::Type::SURFACESHADER} }; const auto typeDescIt = _typeLibrary.find(typeName); if (typeDescIt != _typeLibrary.end()) { return typeDescIt->second; } - return nullptr; + + return mx::Type::NONE; +#endif } // This function adds a stripped down version of the surfaceshader node to the @@ -678,32 +700,30 @@ _AddStrippedSurfaceNode( if (!mxInputDef) { continue; } - auto const* mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType()); - if (!mxTypeDesc) { + auto const mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType()); + if (mxTypeIsNone(mxTypeDesc)) { continue; } // If hdNode is connected to the surfaceshader node, recursively call // this function to make sure that surfaceshader node is added to // the mxDocument - if (mxTypeDesc == mx::Type::SURFACESHADER) { + if (mxTypeIsSurfaceShader(mxTypeDesc)) { auto const& hdConnectedPath = connIt.second.front().upstreamNode; auto const& hdConnectedNode = hdNetwork.nodes.at(hdConnectedPath); mx::NodePtr mxConnectedNode = _AddStrippedSurfaceNode(mxDocument, hdConnectedPath.GetName(), hdConnectedNode, hdNetwork); - mx::InputPtr mxInput = - mxNode->addInput(mxInput->getName(), mxInput->getType()); + mx::InputPtr mxInput = mxNode->addInputFromNodeDef(mxInputDef->getName()); mxInput->setConnectedNode(mxConnectedNode); } // Add the connection as an input with each component set to 0.5 - else if (mxTypeDesc->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT && - mxTypeDesc->getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) { + else if (mxTypeDesc.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT && + mxTypeDesc.getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) { std::string valueStr = "0.5"; - for (size_t i = 1; i < mxTypeDesc->getSize(); ++i) { + for (size_t i = 1; i < mxTypeDesc.getSize(); ++i) { valueStr += ", 0.5"; } - mx::InputPtr mxInput = - mxNode->addInput(mxInputDef->getName(), mxInputDef->getType()); + mx::InputPtr mxInput = mxNode->addInputFromNodeDef(mxInputDef->getName()); mxInput->setValueString(valueStr); } } @@ -715,16 +735,15 @@ _AddStrippedSurfaceNode( if (!mxInputDef) { continue; } - auto const* mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType()); - if (!mxTypeDesc) { + auto const mxTypeDesc = _GetMxTypeDescription(mxInputDef->getType()); + if (mxTypeIsNone(mxTypeDesc)) { continue; } - if (mxTypeDesc->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT && - mxTypeDesc->getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) { + if (mxTypeDesc.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT && + mxTypeDesc.getSemantic() != mx::TypeDesc::SEMANTIC_MATRIX) { // Add the parameter as an input to the mxNode in the mx Document - mx::InputPtr mxInput = - mxNode->addInput(mxInputDef->getName(), mxInputDef->getType()); + mx::InputPtr mxInput = mxNode->addInputFromNodeDef(mxInputDef->getName()); mxInput->setValueString(HdMtlxConvertToString(paramIt.second)); } } @@ -787,9 +806,9 @@ _GetMaterialTag( // Outputting anything that is not a surfaceshader will be // considered opaque, unless outputting a color4 or vector4. // XXX This is not fully per USD specs, but is supported by MaterialX. - auto const* typeDesc = + auto const typeDesc = _GetMxTypeDescription(activeOutputs.back()->getType()); - if (typeDesc == mx::Type::COLOR4 || typeDesc == mx::Type::VECTOR4) { + if (typeDesc.isFloat4()) { return HdStMaterialTagTokens->translucent.GetString(); } return HdStMaterialTagTokens->defaultMaterialTag.GetString(); @@ -1100,7 +1119,7 @@ _AddMaterialXParams( // MaterialX parameter Information const auto* variable = paramsBlock[i]; - const auto varType = variable->getType(); + const auto varType = getMxTypeDesc(variable); // Create a corresponding HdSt_MaterialParam HdSt_MaterialParam param; @@ -1111,9 +1130,9 @@ _AddMaterialXParams( const auto paramValueIt = mxParamNameToValue.find(variable->getVariable()); if (paramValueIt != mxParamNameToValue.end()) { - if (varType->getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN || - varType->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT || - varType->getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) { + if (varType.getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN || + varType.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT || + varType.getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) { param.fallbackValue = paramValueIt->second; } } @@ -1124,52 +1143,52 @@ _AddMaterialXParams( const auto varValue = variable->getValue(); std::istringstream valueStream(varValue ? varValue->getValueString() : std::string()); - if (varType->getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN) { + if (varType.getBaseType() == mx::TypeDesc::BASETYPE_BOOLEAN) { const bool val = valueStream.str() == "true"; param.fallbackValue = VtValue(val); } - else if (varType->getBaseType() == mx::TypeDesc::BASETYPE_FLOAT) { - if (varType->getSize() == 1) { + else if (varType.getBaseType() == mx::TypeDesc::BASETYPE_FLOAT) { + if (varType.getSize() == 1) { float val; valueStream >> val; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 2) { + else if (varType.getSize() == 2) { GfVec2f val; valueStream >> val[0] >> separator >> val[1]; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 3) { + else if (varType.getSize() == 3) { GfVec3f val; valueStream >> val[0] >> separator >> val[1] >> separator >> val[2]; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 4) { + else if (varType.getSize() == 4) { GfVec4f val; valueStream >> val[0] >> separator >> val[1] >> separator >> val[2] >> separator >> val[3]; param.fallbackValue = VtValue(val); } } - else if (varType->getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) { - if (varType->getSize() == 1) { + else if (varType.getBaseType() == mx::TypeDesc::BASETYPE_INTEGER) { + if (varType.getSize() == 1) { int val; valueStream >> val; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 2) { + else if (varType.getSize() == 2) { GfVec2i val; valueStream >> val[0] >> separator >> val[1]; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 3) { + else if (varType.getSize() == 3) { GfVec3i val; valueStream >> val[0] >> separator >> val[1] >> separator >> val[2]; param.fallbackValue = VtValue(val); } - else if (varType->getSize() == 4) { + else if (varType.getSize() == 4) { GfVec4i val; valueStream >> val[0] >> separator >> val[1] >> separator >> val[2] >> separator >> val[3]; @@ -1183,7 +1202,7 @@ _AddMaterialXParams( } // For filename inputs, manage the associated texture node - if (varType->getSemantic() == mx::TypeDesc::SEMANTIC_FILENAME) { + if (varType.getSemantic() == mx::TypeDesc::SEMANTIC_FILENAME) { // Get the anonymized MaterialX node name from the param name // annonNodeName_paramName -> annonNodeName std::string mxNodeName = variable->getVariable(); diff --git a/pxr/imaging/hdSt/materialXShaderGen.cpp b/pxr/imaging/hdSt/materialXShaderGen.cpp index 30674b521..78517b39d 100644 --- a/pxr/imaging/hdSt/materialXShaderGen.cpp +++ b/pxr/imaging/hdSt/materialXShaderGen.cpp @@ -156,13 +156,17 @@ HdStMaterialXShaderGen::_EmitGlslfxHeader(mx::ShaderStage& mxStage) const Base::emitString(R"( "attributes": {)" "\n", mxStage); std::string line = ""; unsigned int i = 0; for (mx::StringMap::const_reference primvarPair : _mxHdPrimvarMap) { - const mx::TypeDesc *mxType = mx::TypeDesc::get(primvarPair.second); - if (mxType == nullptr) { + const mx::TypeDesc mxType = getMxTypeDesc(primvarPair.second); + if (mxTypeIsNone(mxType)) { TF_WARN("MaterialX geomprop '%s' has unknown type '%s'", primvarPair.first.c_str(), primvarPair.second.c_str()); } - const std::string type = mxType - ? Base::_syntax->getTypeName(mxType) : "vec2"; + +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION==38 + const std::string type = (!mxTypeIsNone(mxType)) ? Base::_syntax->getTypeName(&mxType) : "vec2"; +#else + const std::string type = (!mxTypeIsNone(mxType)) ? Base::_syntax->getTypeName(mxType) : "vec2"; +#endif line += " \"" + primvarPair.first + "\": {\n"; line += " \"type\": \"" + type + "\"\n"; @@ -285,12 +289,15 @@ HdStMaterialXShaderGen::_EmitMxSurfaceShader( if (outputConnection) { std::string finalOutput = outputConnection->getVariable(); +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION==38 + // channels feature removed in MaterialX 1.39 const std::string& channels = outputSocket->getChannels(); if (!channels.empty()) { finalOutput = Base::_syntax->getSwizzledVariable( finalOutput, outputConnection->getType(), channels, outputSocket->getType()); } +#endif if (mxGraph.hasClassification( mx::ShaderNode::Classification::SURFACE)) { @@ -311,7 +318,7 @@ HdStMaterialXShaderGen::_EmitMxSurfaceShader( } } else { - if (!outputSocket->getType()->isFloat4()) { + if (!getMxTypeDesc(outputSocket).isFloat4()) { Base::toVec4(outputSocket->getType(), finalOutput); } emitLine(finalOutputReturn + @@ -323,7 +330,7 @@ HdStMaterialXShaderGen::_EmitMxSurfaceShader( ? Base::_syntax->getValue( outputSocket->getType(), *outputSocket->getValue()) : Base::_syntax->getDefaultValue(outputSocket->getType()); - if (!outputSocket->getType()->isFloat4()) { + if (!getMxTypeDesc(outputSocket).isFloat4()) { std::string finalOutput = outputSocket->getVariable() + "_tmp"; emitLine(Base::_syntax->getTypeName(outputSocket->getType()) + " " + finalOutput + " = " + outputValue, mxStage); @@ -415,8 +422,8 @@ HdStMaterialXShaderGen::_EmitMxInitFunction( mxStage.getUniformBlock(mx::HW::PUBLIC_UNIFORMS); for (size_t i = 0; i < paramsBlock.size(); ++i) { const mx::ShaderPort* variable = paramsBlock[i]; - const mx::TypeDesc* variableType = variable->getType(); - if (!_IsHardcodedPublicUniform(*variableType)) { + const mx::TypeDesc variableType = getMxTypeDesc(variable); + if (!_IsHardcodedPublicUniform(variableType)) { emitLine(variable->getVariable() + " = HdGet_" + variable->getVariable() + "()", mxStage); } @@ -622,16 +629,16 @@ HdStMaterialXShaderGen::emitVariableDeclarations( { Base::emitLineBegin(stage); const mx::ShaderPort* variable = block[i]; - const mx::TypeDesc* varType = variable->getType(); + const mx::TypeDesc varType = getMxTypeDesc(variable); // If bindlessTextures are not enabled the Mx Smpler names are mapped // to the Hydra equivalents in HdStMaterialXShaderGen*::_EmitMxFunctions - if (!_bindlessTexturesEnabled && varType == mx::Type::FILENAME) { + if (!_bindlessTexturesEnabled && mxTypeDescIsFilename(varType)) { continue; } // Only declare the variables that we need to initialize with Hd Data - if ( (isPublicUniform && !_IsHardcodedPublicUniform(*varType)) + if ( (isPublicUniform && !_IsHardcodedPublicUniform(varType)) || MxHdVariables.count(variable->getName()) ) { Base::emitVariableDeclaration(variable, mx::EMPTY_STRING, context, stage, false /* assignValue */); @@ -1349,4 +1356,53 @@ HdStMaterialXShaderGenMsl::_EmitMxFunctions( } +bool mxTypeIsNone(mx::TypeDesc typeDesc) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION==38 + return typeDesc == *mx::Type::NONE; +#else + return typeDesc == mx::Type::NONE; +#endif +} + +bool mxTypeIsSurfaceShader(mx::TypeDesc typeDesc) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION==38 + return typeDesc == *mx::Type::SURFACESHADER; +#else + return typeDesc == mx::Type::SURFACESHADER; +#endif +} + +bool mxTypeDescIsFilename(const mx::TypeDesc typeDesc) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION==38 + return typeDesc == *mx::Type::FILENAME; +#else + return typeDesc == mx::Type::FILENAME; +#endif +} + +mx::TypeDesc getMxTypeDesc(const std::string& typeName) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION==38 + const mx::TypeDesc* mxType = mx::TypeDesc::get(typeName); + if (mxType) + return *mxType; + return *mx::Type::NONE; +#else + return mx::TypeDesc::get(typeName); +#endif +} + +const MaterialX::TypeDesc getMxTypeDesc(const mx::ShaderPort* port) +{ +#if MATERIALX_MAJOR_VERSION == 1 && MATERIALX_MINOR_VERSION==38 + return port->getType() ? *(port->getType()) : *mx::Type::NONE; +#else + return port->getType(); +#endif +} + + PXR_NAMESPACE_CLOSE_SCOPE diff --git a/pxr/imaging/hdSt/materialXShaderGen.h b/pxr/imaging/hdSt/materialXShaderGen.h index e61bd13a4..a7f93fdd0 100644 --- a/pxr/imaging/hdSt/materialXShaderGen.h +++ b/pxr/imaging/hdSt/materialXShaderGen.h @@ -192,6 +192,13 @@ private: MaterialX::ShaderStage& mxStage) const; }; +// helper functions to aid building both MaterialX 1.38.X and 1.39.X +// once MaterialX 1.38.X is no longer required these should likely be removed. +bool mxTypeIsNone(MaterialX::TypeDesc typeDesc); +bool mxTypeIsSurfaceShader(MaterialX::TypeDesc typeDesc); +bool mxTypeDescIsFilename(const MaterialX::TypeDesc typeDesc); +MaterialX::TypeDesc getMxTypeDesc(const std::string& typeName); +const MaterialX::TypeDesc getMxTypeDesc(const MaterialX::ShaderPort* port); PXR_NAMESPACE_CLOSE_SCOPE