diff --git a/test/sdf/basic_shapes.sdf b/test/sdf/basic_shapes.sdf index e8f7f7b5b..32e0b416f 100644 --- a/test/sdf/basic_shapes.sdf +++ b/test/sdf/basic_shapes.sdf @@ -144,12 +144,12 @@ 0.2 0.5 0.1 1.0 0.7 0.3 0.5 0.9 - + albedo_map.png normal_map.png roughness_map.png metalness_map.png - + diff --git a/usd/include/sdf/usd/sdf_parser/Material.hh b/usd/include/sdf/usd/sdf_parser/Material.hh index 3012bde6c..429dd7b8e 100644 --- a/usd/include/sdf/usd/sdf_parser/Material.hh +++ b/usd/include/sdf/usd/sdf_parser/Material.hh @@ -24,6 +24,7 @@ // included. #pragma push_macro ("__DEPRECATED") #undef __DEPRECATED +#include #include #include #pragma pop_macro ("__DEPRECATED") @@ -44,14 +45,14 @@ namespace sdf /// \param[in] _materialSdf The SDF material to parse. /// \param[in] _stage The stage that should contain the USD representation /// of _material. - /// \param[out] _materialPath Material usd path + /// \param[out] _materialPath USD Material path /// \return UsdErrors, which is a list of UsdError objects. This list is - /// empty if no errors occurred when parsing _materialSdf to _materialUsd - UsdErrors IGNITION_SDFORMAT_USD_VISIBLE - ParseSdfMaterial( + /// empty if no errors occurred when parsing _materialSdf its USD + /// representation + UsdErrors IGNITION_SDFORMAT_USD_VISIBLE ParseSdfMaterial( const sdf::Material *_materialSdf, pxr::UsdStageRefPtr &_stage, - std::string &_materialPath); + pxr::SdfPath &_materialPath); } } } diff --git a/usd/src/cmd/sdf2usd.cc b/usd/src/cmd/sdf2usd.cc index afed2df61..5ca0d7131 100644 --- a/usd/src/cmd/sdf2usd.cc +++ b/usd/src/cmd/sdf2usd.cc @@ -95,13 +95,15 @@ std::string findFileByName(const std::string &_path, const std::string &_name) /// \brief Get the full path of a file based on the extension /// \param[in] _path Where to begin searching for the file /// \param[in] _extension The extension of the file +/// \param[in] _insertDirectories Whether subdirectories should be inserted as +/// needed when looking for the file (true) or not (false) /// \return The full path to the file with an extension _extension. Empty /// string is returned if the file could not be found. std::string findFileByExtension( const std::string &_path, const std::string &_extension, - bool insertDirectories = false) + bool _insertDirectories = false) { - if (insertDirectories) + if (_insertDirectories) { for (ignition::common::DirIter file(_path); file != ignition::common::DirIter(); ++file) diff --git a/usd/src/sdf_parser/Geometry.cc b/usd/src/sdf_parser/Geometry.cc index 3aabae14c..a0827ddcf 100644 --- a/usd/src/sdf_parser/Geometry.cc +++ b/usd/src/sdf_parser/Geometry.cc @@ -383,25 +383,39 @@ namespace usd pxr::GfVec3f(meshMax.X(), meshMax.Y(), meshMax.Z())); usdMesh.CreateExtentAttr().Set(extentBounds); + // TODO(adlarkin) update this call in sdf13 to avoid casting the index to + // an int: + // https://github.com/ignitionrobotics/ign-common/pull/319 int materialIndex = subMesh->MaterialIndex(); if (materialIndex != -1) { auto material = ignMesh->MaterialByIndex(materialIndex); const sdf::Material materialSdf = sdf::usd::convert(material); - std::string materialPath; + pxr::SdfPath materialPath; UsdErrors materialErrors = ParseSdfMaterial( &materialSdf, _stage, materialPath); if (!materialErrors.empty()) { errors.push_back(UsdError( sdf::usd::UsdErrorCode::SDF_TO_USD_PARSING_ERROR, - "Unable to parse material")); + "Unable to convert material [" + std::to_string(materialIndex) + + "] of submesh named [" + subMesh->Name() + + "] to a USD material.")); return errors; } - auto materialUSD = pxr::UsdShadeMaterial(_stage->GetPrimAtPath( - pxr::SdfPath(materialPath))); + auto materialPrim = _stage->GetPrimAtPath(materialPath); + if (!materialPrim) + { + errors.push_back(UsdError( + sdf::usd::UsdErrorCode::INVALID_PRIM_PATH, + "Unable to get material prim at path [" + + materialPath.GetString() + + "], but a prim should exist at this path.")); + return errors; + } + auto materialUSD = pxr::UsdShadeMaterial(materialPrim); if (materialUSD && (materialSdf.Emissive() != ignition::math::Color(0, 0, 0, 1) || materialSdf.Specular() != ignition::math::Color(0, 0, 0, 1) @@ -413,9 +427,8 @@ namespace usd { errors.push_back(UsdError( sdf::usd::UsdErrorCode::SDF_TO_USD_PARSING_ERROR, - "Unable to convert material [" + std::to_string(materialIndex) - + "] of submesh named [" + subMesh->Name() - + "] to a USD material.")); + "The prim at path [" + materialPath.GetString() + + "] is not a pxr::UsdShadeMaterial object.")); return errors; } } diff --git a/usd/src/sdf_parser/Material.cc b/usd/src/sdf_parser/Material.cc index 4014259e7..0a1c789a8 100644 --- a/usd/src/sdf_parser/Material.cc +++ b/usd/src/sdf_parser/Material.cc @@ -111,7 +111,7 @@ namespace usd { errors.emplace_back(UsdError( sdf::usd::UsdErrorCode::INVALID_PRIM_PATH, - "Not able to convert the prim to a UsdShadeShader")); + "Unable to convert the prim to a UsdShadeShader")); return errors; } @@ -153,73 +153,66 @@ namespace usd return errors; } - UsdErrors - ParseSdfMaterial( - const sdf::Material *_materialSdf, - pxr::UsdStageRefPtr &_stage, - std::string &_materialPath) + UsdErrors ParseSdfMaterial(const sdf::Material *_materialSdf, + pxr::UsdStageRefPtr &_stage, pxr::SdfPath &_materialPath) { UsdErrors errors; - auto looksPrim = _stage->GetPrimAtPath(pxr::SdfPath("/Looks")); + + const auto looksPath = pxr::SdfPath("/Looks"); + auto looksPrim = _stage->GetPrimAtPath(looksPath); if (!looksPrim) { - looksPrim = _stage->DefinePrim( - pxr::SdfPath("/Looks"), pxr::TfToken("Scope")); + looksPrim = _stage->DefinePrim(looksPath, pxr::TfToken("Scope")); } // This variable will increase with every new material to avoid collision // with the names of the materials static int i = 0; - _materialPath = "/Looks/Material_" + std::to_string(i); + _materialPath = pxr::SdfPath("/Looks/Material_" + std::to_string(i)); + i++; pxr::UsdShadeMaterial materialUsd; - auto usdMaterialPrim = _stage->GetPrimAtPath(pxr::SdfPath(_materialPath)); + auto usdMaterialPrim = _stage->GetPrimAtPath(_materialPath); if (!usdMaterialPrim) { - materialUsd = pxr::UsdShadeMaterial::Define( - _stage, pxr::SdfPath(_materialPath)); + materialUsd = pxr::UsdShadeMaterial::Define(_stage, _materialPath); } else { materialUsd = pxr::UsdShadeMaterial(usdMaterialPrim); } - auto usdShader = pxr::UsdShadeShader::Define( - _stage, - pxr::SdfPath(_materialPath + "/Shader")); - auto shaderPrim = _stage->GetPrimAtPath( - pxr::SdfPath(_materialPath + "/Shader")); + const auto shaderPath = pxr::SdfPath(_materialPath.GetString() + "/Shader"); + auto usdShader = pxr::UsdShadeShader::Define(_stage, shaderPath); + auto shaderPrim = _stage->GetPrimAtPath(shaderPath); if (!shaderPrim) { errors.emplace_back(UsdError( sdf::usd::UsdErrorCode::INVALID_PRIM_PATH, - "Not able to cast the UsdShadeShader to a Prim")); + "Not able to cast the UsdShadeShader at path [" + shaderPath.GetString() + + "] to a Prim")); } - auto shader_out = pxr::UsdShadeConnectableAPI(shaderPrim).CreateOutput( + auto shaderOut = pxr::UsdShadeConnectableAPI(shaderPrim).CreateOutput( pxr::TfToken("out"), pxr::SdfValueTypeNames->Token); - materialUsd.CreateSurfaceOutput( - pxr::TfToken("mdl")).ConnectToSource(shader_out); - materialUsd.CreateVolumeOutput( - pxr::TfToken("mdl")).ConnectToSource(shader_out); - materialUsd.CreateDisplacementOutput( - pxr::TfToken("mdl")).ConnectToSource(shader_out); + const auto mdlToken = pxr::TfToken("mdl"); + materialUsd.CreateSurfaceOutput(mdlToken).ConnectToSource(shaderOut); + materialUsd.CreateVolumeOutput(mdlToken).ConnectToSource(shaderOut); + materialUsd.CreateDisplacementOutput(mdlToken).ConnectToSource(shaderOut); usdShader.GetImplementationSourceAttr().Set( pxr::UsdShadeTokens->sourceAsset); - usdShader.SetSourceAsset( - pxr::SdfAssetPath("OmniPBR.mdl"), pxr::TfToken("mdl")); - usdShader.SetSourceAssetSubIdentifier( - pxr::TfToken("OmniPBR"), pxr::TfToken("mdl")); + usdShader.SetSourceAsset(pxr::SdfAssetPath("OmniPBR.mdl"), mdlToken); + usdShader.SetSourceAssetSubIdentifier(pxr::TfToken("OmniPBR"), mdlToken); - std::map customDataDiffuse = + const std::map customDataDiffuse = { {pxr::TfToken("default"), pxr::VtValue(pxr::GfVec3f(0.2, 0.2, 0.2))}, {pxr::TfToken("range:max"), pxr::VtValue(pxr::GfVec3f(100000, 100000, 100000))}, {pxr::TfToken("range:min"), pxr::VtValue(pxr::GfVec3f(0, 0, 0))} }; - ignition::math::Color diffuse = _materialSdf->Diffuse(); + const ignition::math::Color diffuse = _materialSdf->Diffuse(); auto errorsMaterialDiffuseColorConstant = CreateMaterialInput( shaderPrim, "diffuse_color_constant", @@ -237,10 +230,12 @@ namespace usd errorsMaterialDiffuseColorConstant.begin(), errorsMaterialDiffuseColorConstant.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the base color of the material at path [" + + _materialPath.GetString() + "]")); + return errors; } - std::map customDataEmissive = + const std::map customDataEmissive = { {pxr::TfToken("default"), pxr::VtValue(pxr::GfVec3f(1, 0.1, 0.1))}, {pxr::TfToken("range:max"), @@ -265,11 +260,12 @@ namespace usd errorsMaterialEmissiveColor.begin(), errorsMaterialEmissiveColor.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the emission color of the material at path [" + + _materialPath.GetString() + "]")); return errors; } - std::map customDataEnableEmission = + const std::map customDataEnableEmission = { {pxr::TfToken("default"), pxr::VtValue(0)} }; @@ -291,11 +287,12 @@ namespace usd errorsMaterialEnableEmission.begin(), errorsMaterialEnableEmission.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the emissive enabled propery of the material at path" + " [" + _materialPath.GetString() + "]")); return errors; } - std::map customDataIntensity = + const std::map customDataIntensity = { {pxr::TfToken("default"), pxr::VtValue(40)}, {pxr::TfToken("range:max"), pxr::VtValue(100000)}, @@ -318,7 +315,8 @@ namespace usd errorsMaterialEmissiveIntensity.begin(), errorsMaterialEmissiveIntensity.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the emissive intensity of the material at path [" + + _materialPath.GetString() + "]")); return errors; } @@ -334,7 +332,7 @@ namespace usd if (pbrWorkflow) { - std::map customDataMetallicConstant = + const std::map customDataMetallicConstant = { {pxr::TfToken("default"), pxr::VtValue(0.5)}, {pxr::TfToken("range:max"), pxr::VtValue(1)}, @@ -356,10 +354,11 @@ namespace usd errorsMaterialMetallicConstant.begin(), errorsMaterialMetallicConstant.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the metallic constant of the material at path [" + + _materialPath.GetString() + "]")); return errors; } - std::map customDataRoughnessConstant = + const std::map customDataRoughnessConstant = { {pxr::TfToken("default"), pxr::VtValue(0.5)}, {pxr::TfToken("range:max"), pxr::VtValue(1)}, @@ -382,17 +381,18 @@ namespace usd errorsMaterialReflectionRoughnessConstant.begin(), errorsMaterialReflectionRoughnessConstant.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the roughness constant of the material at path [" + + _materialPath.GetString() + "]")); return errors; } - if (!pbrWorkflow->AlbedoMap().empty()) + const std::map customDefaultSdfAssetPath = { - std::map customDataDiffuseTexture = - { - {pxr::TfToken("default"), pxr::VtValue(pxr::SdfAssetPath())}, - }; + {pxr::TfToken("default"), pxr::VtValue(pxr::SdfAssetPath())}, + }; + if (!pbrWorkflow->AlbedoMap().empty()) + { std::string copyPath = getMaterialCopyPath(pbrWorkflow->AlbedoMap()); std::string fullnameAlbedoMap = @@ -406,16 +406,17 @@ namespace usd copyMaterial(copyPath, fullnameAlbedoMap); - auto errorsMaterialDiffuseTexture = CreateMaterialInput( - shaderPrim, - "diffuse_texture", - pxr::SdfValueTypeNames->Asset, - pxr::SdfAssetPath(copyPath), - customDataDiffuseTexture, - pxr::TfToken("Base Map"), - pxr::TfToken("Albedo"), - "", - pxr::TfToken("auto")); + auto errorsMaterialDiffuseTexture = + CreateMaterialInput( + shaderPrim, + "diffuse_texture", + pxr::SdfValueTypeNames->Asset, + pxr::SdfAssetPath(copyPath), + customDefaultSdfAssetPath, + pxr::TfToken("Base Map"), + pxr::TfToken("Albedo"), + "", + pxr::TfToken("auto")); if (!errorsMaterialDiffuseTexture.empty()) { errors.insert( @@ -423,18 +424,15 @@ namespace usd errorsMaterialDiffuseTexture.begin(), errorsMaterialDiffuseTexture.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the albedo of the material at path [" + + _materialPath.GetString() + "]")); return errors; } } if (!pbrWorkflow->MetalnessMap().empty()) { - std::map customDataMetallnessTexture = - { - {pxr::TfToken("default"), pxr::VtValue(pxr::SdfAssetPath())}, - }; - - std::string copyPath = getMaterialCopyPath(pbrWorkflow->MetalnessMap()); + std::string copyPath = + getMaterialCopyPath(pbrWorkflow->MetalnessMap()); std::string fullnameMetallnessMap = ignition::common::findFile( @@ -447,16 +445,17 @@ namespace usd copyMaterial(copyPath, fullnameMetallnessMap); - auto errorsMaterialMetallicTexture = CreateMaterialInput( - shaderPrim, - "metallic_texture", - pxr::SdfValueTypeNames->Asset, - pxr::SdfAssetPath(copyPath), - customDataMetallnessTexture, - pxr::TfToken("Metallic Map"), - pxr::TfToken("Reflectivity"), - "", - pxr::TfToken("raw")); + auto errorsMaterialMetallicTexture = + CreateMaterialInput( + shaderPrim, + "metallic_texture", + pxr::SdfValueTypeNames->Asset, + pxr::SdfAssetPath(copyPath), + customDefaultSdfAssetPath, + pxr::TfToken("Metallic Map"), + pxr::TfToken("Reflectivity"), + "", + pxr::TfToken("raw")); if (!errorsMaterialMetallicTexture.empty()) { errors.insert( @@ -464,17 +463,13 @@ namespace usd errorsMaterialMetallicTexture.begin(), errorsMaterialMetallicTexture.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the reflectivity of the material at path [" + + _materialPath.GetString() + "]")); return errors; } } if (!pbrWorkflow->NormalMap().empty()) { - std::map customDataNormalTexture = - { - {pxr::TfToken("default"), pxr::VtValue(pxr::SdfAssetPath())}, - }; - std::string copyPath = getMaterialCopyPath(pbrWorkflow->NormalMap()); std::string fullnameNormalMap = @@ -488,16 +483,17 @@ namespace usd copyMaterial(copyPath, fullnameNormalMap); - auto errorsMaterialNormalMapTexture = CreateMaterialInput( - shaderPrim, - "normalmap_texture", - pxr::SdfValueTypeNames->Asset, - pxr::SdfAssetPath(copyPath), - customDataNormalTexture, - pxr::TfToken("Normal Map"), - pxr::TfToken("Normal"), - "", - pxr::TfToken("raw")); + auto errorsMaterialNormalMapTexture = + CreateMaterialInput( + shaderPrim, + "normalmap_texture", + pxr::SdfValueTypeNames->Asset, + pxr::SdfAssetPath(copyPath), + customDefaultSdfAssetPath, + pxr::TfToken("Normal Map"), + pxr::TfToken("Normal"), + "", + pxr::TfToken("raw")); if (!errorsMaterialNormalMapTexture.empty()) { errors.insert( @@ -505,18 +501,15 @@ namespace usd errorsMaterialNormalMapTexture.begin(), errorsMaterialNormalMapTexture.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the normal map of the material at path [" + + _materialPath.GetString() + "]")); return errors; } } if (!pbrWorkflow->RoughnessMap().empty()) { - std::map customDataRoughnessTexture = - { - {pxr::TfToken("default"), pxr::VtValue(pxr::SdfAssetPath())}, - }; - - std::string copyPath = getMaterialCopyPath(pbrWorkflow->RoughnessMap()); + std::string copyPath = + getMaterialCopyPath(pbrWorkflow->RoughnessMap()); std::string fullnameRoughnessMap = ignition::common::findFile( @@ -535,7 +528,7 @@ namespace usd "reflectionroughness_texture", pxr::SdfValueTypeNames->Asset, pxr::SdfAssetPath(copyPath), - customDataRoughnessTexture, + customDefaultSdfAssetPath, pxr::TfToken("RoughnessMap Map"), pxr::TfToken("RoughnessMap"), "", @@ -547,11 +540,12 @@ namespace usd errorsMaterialReflectionRoughnessTexture.begin(), errorsMaterialReflectionRoughnessTexture.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the roughness map of the material at path [" + + _materialPath.GetString() + "]")); return errors; } - std::map + const std::map customDataRoughnessTextureInfluence = { {pxr::TfToken("default"), pxr::VtValue(0)}, @@ -577,14 +571,14 @@ namespace usd errorsMaterialReflectionRoughnessTextureInfluence.begin(), errorsMaterialReflectionRoughnessTextureInfluence.end()); errors.push_back(UsdError(UsdErrorCode::INVALID_MATERIAL, - "Unable to get the material")); + "Unable to set the reflectivity of the material at path [" + + _materialPath.GetString() + "]")); return errors; } } } } - i++; return errors; } } diff --git a/usd/src/sdf_parser/Material_Sdf2Usd_TEST.cc b/usd/src/sdf_parser/Material_Sdf2Usd_TEST.cc index 3cd743d98..657c5360e 100644 --- a/usd/src/sdf_parser/Material_Sdf2Usd_TEST.cc +++ b/usd/src/sdf_parser/Material_Sdf2Usd_TEST.cc @@ -19,7 +19,7 @@ #include -// TODO(ahcorde):this is to remove deprecated "warnings" in usd, these warnings +// TODO(ahcorde) this is to remove deprecated "warnings" in usd, these warnings // are reported using #pragma message so normal diagnostic flags cannot remove // them. This workaround requires this block to be used whenever usd is // included. @@ -36,42 +36,54 @@ #include "../UsdTestUtils.hh" void CheckMaterial( - const pxr::UsdPrim _prim, - const pxr::GfVec3f _diffuseColor, - const pxr::GfVec3f _emissiveColor, - const std::string &_albedoName, - const std::string &_normalName, - const std::string &_roughnessName, - const std::string &_metallicName, - float _metallicConstant = 0.5, - bool _enableEmission = true) + const pxr::UsdPrim &_prim, + const pxr::GfVec3f &_diffuseColor, + const pxr::GfVec3f &_emissiveColor, + bool _hasPbr, + const std::string &_albedoName = "", + const std::string &_normalName = "", + const std::string &_roughnessName = "", + const std::string &_metallicName = "") { auto variantshader = pxr::UsdShadeShader(_prim); - EXPECT_TRUE(variantshader); + ASSERT_TRUE(variantshader); std::vector inputs = variantshader.GetInputs(); pxr::GfVec3f diffuseColor {0, 0, 0}; pxr::GfVec3f emissiveColor {0, 0, 0}; + // PBR-specific values + const float _metallicConstant = 0.5; + const bool _enableEmission = true; + + bool checkedDiffuse = false; + bool checkedEmissive = false; + bool checkedAlbedo = false; + bool checkedNormal = false; + bool checkedRoughness = false; + bool checkedMetallicName = false; + bool checkedMetallicConstant = false; + bool checkedEnableEmission = false; for (auto &input : inputs) { - if (input.GetBaseName() == "diffuse_texture") + if (_hasPbr && input.GetBaseName() == "diffuse_texture") { pxr::SdfAssetPath materialPathUSD; pxr::UsdShadeInput diffuseTextureShaderInput = variantshader.GetInput(pxr::TfToken("diffuse_texture")); - auto source = diffuseTextureShaderInput.GetConnectedSources(); diffuseTextureShaderInput.Get(&materialPathUSD); EXPECT_EQ(_albedoName, materialPathUSD.GetAssetPath()); + checkedAlbedo = true; } - else if (input.GetBaseName() == "metallic_constant") + else if (_hasPbr && input.GetBaseName() == "metallic_constant") { pxr::UsdShadeInput metallicConstantShaderInput = variantshader.GetInput(pxr::TfToken("metallic_constant")); float metallicConstant; metallicConstantShaderInput.Get(&metallicConstant); EXPECT_FLOAT_EQ(_metallicConstant, metallicConstant); + checkedMetallicConstant = true; } else if (input.GetBaseName() == "enable_emission") { @@ -80,33 +92,34 @@ void CheckMaterial( variantshader.GetInput(pxr::TfToken("enable_emission")); enableEmissiveShaderInput.Get(&enableEmission); EXPECT_EQ(_enableEmission, enableEmission); + checkedEnableEmission = true; } - else if (input.GetBaseName() == "normalmap_texture") + else if (_hasPbr && input.GetBaseName() == "normalmap_texture") { pxr::SdfAssetPath materialPath; pxr::UsdShadeInput normalTextureShaderInput = variantshader.GetInput(pxr::TfToken("normalmap_texture")); - auto source = normalTextureShaderInput.GetConnectedSources(); normalTextureShaderInput.Get(&materialPath); EXPECT_EQ(_normalName, materialPath.GetAssetPath()); + checkedNormal = true; } - else if (input.GetBaseName() == "reflectionroughness_texture") + else if (_hasPbr && input.GetBaseName() == "reflectionroughness_texture") { pxr::SdfAssetPath materialPath; pxr::UsdShadeInput roughnessTextureShaderInput = variantshader.GetInput(pxr::TfToken("reflectionroughness_texture")); - auto source = roughnessTextureShaderInput.GetConnectedSources(); roughnessTextureShaderInput.Get(&materialPath); EXPECT_EQ(_roughnessName, materialPath.GetAssetPath()); + checkedRoughness = true; } - else if (input.GetBaseName() == "metallic_texture") + else if (_hasPbr && input.GetBaseName() == "metallic_texture") { pxr::SdfAssetPath materialPath; pxr::UsdShadeInput metallicTextureShaderInput = variantshader.GetInput(pxr::TfToken("metallic_texture")); - auto source = metallicTextureShaderInput.GetConnectedSources(); metallicTextureShaderInput.Get(&materialPath); EXPECT_EQ(_metallicName, materialPath.GetAssetPath()); + checkedMetallicName = true; } else if (input.GetBaseName() == "emissive_color") { @@ -116,6 +129,7 @@ void CheckMaterial( { EXPECT_EQ(_emissiveColor, emissiveColor); } + checkedEmissive = true; } else if (input.GetBaseName() == "diffuse_color_constant") { @@ -128,18 +142,30 @@ void CheckMaterial( const pxr::SdfPath& thisAttrPath = connectedInput.GetAttr().GetPath(); auto connectedPrim = _prim.GetStage()->GetPrimAtPath( thisAttrPath.GetPrimPath()); - if(connectedPrim) + if (connectedPrim) + { connectedPrim.GetAttribute( pxr::TfToken("inputs:diffuse_color_constant")).Get(&diffuseColor); + } } + else { pxr::UsdShadeInput diffuseShaderInput = variantshader.GetInput(pxr::TfToken("diffuse_color_constant")); diffuseShaderInput.Get(&diffuseColor); } EXPECT_EQ(_diffuseColor, diffuseColor); + checkedDiffuse = true; } } + EXPECT_TRUE(checkedDiffuse); + EXPECT_TRUE(checkedEmissive); + EXPECT_TRUE(checkedEnableEmission); + EXPECT_EQ(_hasPbr, checkedAlbedo); + EXPECT_EQ(_hasPbr, checkedNormal); + EXPECT_EQ(_hasPbr, checkedRoughness); + EXPECT_EQ(_hasPbr, checkedMetallicName); + EXPECT_EQ(_hasPbr, checkedMetallicConstant); } ///////////////////////////////////////////////// @@ -178,54 +204,40 @@ TEST_F(UsdStageFixture, Material) auto worldPrim = this->stage->GetPrimAtPath(pxr::SdfPath(worldPath)); ASSERT_TRUE(worldPrim); - std::string meshPath = worldPath + "/" + "mesh"; - std::string meshLinkPath = meshPath + "/" + "link"; - std::string meshVisualPath = meshLinkPath + "/" + "visual"; - std::string meshGeometryPath = - meshVisualPath + "/" + "geometry"; - auto meshGeometry = this->stage->GetPrimAtPath( - pxr::SdfPath(meshGeometryPath)); - ASSERT_TRUE(meshGeometry); + const std::string meshGeometryPath = worldPath + "/mesh/link/visual/geometry"; + ASSERT_TRUE(this->stage->GetPrimAtPath(pxr::SdfPath(meshGeometryPath))); { - std::string materialPath = "/Looks/Material_2"; - auto materialPrim = this->stage->GetPrimAtPath( - pxr::SdfPath(materialPath)); - EXPECT_TRUE(materialPrim); + const std::string materialPath = "/Looks/Material_2"; + ASSERT_TRUE(this->stage->GetPrimAtPath(pxr::SdfPath(materialPath))); - std::string materialshaderPath = materialPath + "/Shader"; - auto materialShaderPrim = this->stage->GetPrimAtPath( + const std::string materialshaderPath = materialPath + "/Shader"; + const auto materialShaderPrim = this->stage->GetPrimAtPath( pxr::SdfPath(materialshaderPath)); - EXPECT_TRUE(materialShaderPrim); + ASSERT_TRUE(materialShaderPrim); CheckMaterial(materialShaderPrim, pxr::GfVec3f(0.2, 0.5, 0.1), pxr::GfVec3f(0, 0, 0), + true, "materials/textures/albedo_map.png", "materials/textures/normal_map.png", "materials/textures/roughness_map.png", - "materials/textures/metallic_map.png" - ); + "materials/textures/metalness_map.png"); } { - std::string materialPath = "/Looks/Material_0"; - auto materialPrim = this->stage->GetPrimAtPath( - pxr::SdfPath(materialPath)); - EXPECT_TRUE(materialPrim); + const std::string materialPath = "/Looks/Material_0"; + ASSERT_TRUE(this->stage->GetPrimAtPath(pxr::SdfPath(materialPath))); - std::string materialshaderPath = materialPath + "/Shader"; - auto materialShaderPrim = this->stage->GetPrimAtPath( + const std::string materialshaderPath = materialPath + "/Shader"; + const auto materialShaderPrim = this->stage->GetPrimAtPath( pxr::SdfPath(materialshaderPath)); - EXPECT_TRUE(materialShaderPrim); + ASSERT_TRUE(materialShaderPrim); CheckMaterial(materialShaderPrim, pxr::GfVec3f(0, 0.1, 0.2), pxr::GfVec3f(0.12, 0.23, 0.34), - "", - "", - "", - "" - ); + false); } } diff --git a/usd/src/sdf_parser/Visual.cc b/usd/src/sdf_parser/Visual.cc index 8e1f7bff2..3dbbb889c 100644 --- a/usd/src/sdf_parser/Visual.cc +++ b/usd/src/sdf_parser/Visual.cc @@ -95,25 +95,28 @@ namespace usd { if (_visual.Material()) { - std::string materialPath; + pxr::SdfPath materialPath; UsdErrors materialErrors = ParseSdfMaterial( _visual.Material(), _stage, materialPath); if (!materialErrors.empty()) { + errors.insert(errors.end(), materialErrors.begin(), + materialErrors.end()); errors.push_back(UsdError( sdf::usd::UsdErrorCode::SDF_TO_USD_PARSING_ERROR, - "Unable to parse material")); + "Error parsing material attached to visual [" + + _visual.Name() + "]")); return errors; } - auto materialUSD = pxr::UsdShadeMaterial(_stage->GetPrimAtPath( - pxr::SdfPath(materialPath))); + auto materialUSD = + pxr::UsdShadeMaterial(_stage->GetPrimAtPath(materialPath)); if (!materialUSD) { errors.push_back(UsdError( sdf::usd::UsdErrorCode::SDF_TO_USD_PARSING_ERROR, - "Error parsing material attached to visual [" - + _visual.Name() + "]")); + "Unable to convert prim at path [" + materialPath.GetString() + + "] to a pxr::UsdShadeMaterial.")); return errors; } pxr::UsdShadeMaterialBindingAPI(geomPrim).Bind(materialUSD);