Merge branch 'blender-v4.5-release'
This commit is contained in:
@@ -918,6 +918,33 @@ static void configure_displacement(const pxr::UsdShadeShader &usd_shader, bNode
|
||||
((bNodeSocketValueFloat *)sock_scale->default_value)->value = scale_avg;
|
||||
}
|
||||
|
||||
static pxr::UsdShadeShader node_graph_output_source(const pxr::UsdShadeNodeGraph &node_graph,
|
||||
const pxr::TfToken &output_name)
|
||||
{
|
||||
// Check that we have a legit output
|
||||
pxr::UsdShadeOutput output = node_graph.GetOutput(output_name);
|
||||
if (!output) {
|
||||
return pxr::UsdShadeShader();
|
||||
}
|
||||
|
||||
pxr::UsdShadeAttributeVector attrs = pxr::UsdShadeUtils::GetValueProducingAttributes(output);
|
||||
if (attrs.empty()) {
|
||||
return pxr::UsdShadeShader();
|
||||
}
|
||||
|
||||
pxr::UsdAttribute attr = attrs[0];
|
||||
|
||||
std::pair<pxr::TfToken, pxr::UsdShadeAttributeType> name_and_type =
|
||||
pxr::UsdShadeUtils::GetBaseNameAndType(attr.GetName());
|
||||
|
||||
pxr::UsdShadeShader shader(attr.GetPrim());
|
||||
if (name_and_type.second != pxr::UsdShadeAttributeType::Output || !shader) {
|
||||
return pxr::UsdShadeShader();
|
||||
}
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
bool USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
bNode *dest_node,
|
||||
const StringRefNull dest_socket_name,
|
||||
@@ -936,11 +963,19 @@ bool USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
|
||||
usd_input.GetConnectedSource(&source, &source_name, &source_type);
|
||||
|
||||
if (!(source && source.GetPrim().IsA<pxr::UsdShadeShader>())) {
|
||||
if (!source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pxr::UsdShadeShader source_shader(source.GetPrim());
|
||||
const pxr::UsdPrim source_prim = source.GetPrim();
|
||||
pxr::UsdShadeShader source_shader;
|
||||
if (source_prim.IsA<pxr::UsdShadeShader>()) {
|
||||
source_shader = pxr::UsdShadeShader(source_prim);
|
||||
}
|
||||
else if (source_prim.IsA<pxr::UsdShadeNodeGraph>()) {
|
||||
pxr::UsdShadeNodeGraph node_graph(source_prim);
|
||||
source_shader = node_graph_output_source(node_graph, source_name);
|
||||
}
|
||||
|
||||
if (!source_shader) {
|
||||
return false;
|
||||
@@ -948,9 +983,9 @@ bool USDMaterialReader::follow_connection(const pxr::UsdShadeInput &usd_input,
|
||||
|
||||
pxr::TfToken shader_id;
|
||||
if (!source_shader.GetShaderId(&shader_id)) {
|
||||
CLOG_ERROR(&LOG,
|
||||
"Couldn't get shader id for source shader %s",
|
||||
source_shader.GetPath().GetAsString().c_str());
|
||||
CLOG_WARN(&LOG,
|
||||
"Couldn't get shader id for source shader %s",
|
||||
source_shader.GetPath().GetAsString().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
91
tests/files/usd/usd_materials_node_graph.usda
Normal file
91
tests/files/usd/usd_materials_node_graph.usda
Normal file
@@ -0,0 +1,91 @@
|
||||
#usda 1.0
|
||||
(
|
||||
defaultPrim = "root"
|
||||
doc = "Blender v4.5.0 Beta"
|
||||
metersPerUnit = 1
|
||||
upAxis = "Z"
|
||||
)
|
||||
|
||||
def Xform "root" (
|
||||
customData = {
|
||||
dictionary Blender = {
|
||||
bool generated = 1
|
||||
}
|
||||
}
|
||||
)
|
||||
{
|
||||
def Xform "Cube"
|
||||
{
|
||||
def Mesh "Cube" (
|
||||
active = true
|
||||
prepend apiSchemas = ["MaterialBindingAPI"]
|
||||
)
|
||||
{
|
||||
uniform bool doubleSided = 1
|
||||
float3[] extent = [(-1, -1, -1), (1, 1, 1)]
|
||||
int[] faceVertexCounts = [4, 4, 4, 4, 4, 4]
|
||||
int[] faceVertexIndices = [0, 4, 6, 2, 3, 2, 6, 7, 7, 6, 4, 5, 5, 1, 3, 7, 1, 0, 2, 3, 5, 4, 0, 1]
|
||||
rel material:binding = </root/_materials/Material>
|
||||
normal3f[] normals = [(0, 0, 1), (0, 0, 1), (0, 0, 1), (0, 0, 1), (0, -1, 0), (0, -1, 0), (0, -1, 0), (0, -1, 0), (-1, 0, 0), (-1, 0, 0), (-1, 0, 0), (-1, 0, 0), (0, 0, -1), (0, 0, -1), (0, 0, -1), (0, 0, -1), (1, 0, 0), (1, 0, 0), (1, 0, 0), (1, 0, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0), (0, 1, 0)] (
|
||||
interpolation = "faceVarying"
|
||||
)
|
||||
point3f[] points = [(1, 1, 1), (1, 1, -1), (1, -1, 1), (1, -1, -1), (-1, 1, 1), (-1, 1, -1), (-1, -1, 1), (-1, -1, -1)]
|
||||
texCoord2f[] primvars:st = [(0.625, 0.5), (0.875, 0.5), (0.875, 0.75), (0.625, 0.75), (0.375, 0.75), (0.625, 0.75), (0.625, 1), (0.375, 1), (0.375, 0), (0.625, 0), (0.625, 0.25), (0.375, 0.25), (0.125, 0.5), (0.375, 0.5), (0.375, 0.75), (0.125, 0.75), (0.375, 0.5), (0.625, 0.5), (0.625, 0.75), (0.375, 0.75), (0.375, 0.25), (0.625, 0.25), (0.625, 0.5), (0.375, 0.5)] (
|
||||
interpolation = "faceVarying"
|
||||
)
|
||||
uniform token subdivisionScheme = "none"
|
||||
}
|
||||
}
|
||||
|
||||
def Scope "_materials"
|
||||
{
|
||||
def Material "Material"
|
||||
{
|
||||
token outputs:surface.connect = </root/_materials/Material/Principled_BSDF.outputs:surface>
|
||||
|
||||
def Shader "Principled_BSDF"
|
||||
{
|
||||
uniform token info:id = "UsdPreviewSurface"
|
||||
float inputs:clearcoat = 0
|
||||
float inputs:clearcoatRoughness = 0.03
|
||||
color3f inputs:diffuseColor.connect = </root/_materials/Material/node_graph_BaseColor.outputs:rgb>
|
||||
float inputs:ior = 1.45
|
||||
float inputs:metallic = 0
|
||||
float inputs:opacity = 1
|
||||
float inputs:roughness = 0.5
|
||||
float inputs:specular = 0.5
|
||||
token outputs:surface
|
||||
}
|
||||
|
||||
def NodeGraph "node_graph_BaseColor" (
|
||||
prepend references = </root/_materials/node_graph_BaseColor>
|
||||
)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
def NodeGraph "node_graph_BaseColor"
|
||||
{
|
||||
string inputs:frame:st = "st"
|
||||
float3 outputs:rgb.connect = </root/_materials/node_graph_BaseColor/node_graph_BaseColor.outputs:rgb>
|
||||
|
||||
def Shader "node_graph_BaseColor"
|
||||
{
|
||||
uniform token info:id = "UsdUVTexture"
|
||||
asset inputs:file = @./textures/test_single.png@
|
||||
float2 inputs:st.connect = </root/_materials/node_graph_BaseColor/PrimvarReader_st.outputs:result>
|
||||
token inputs:wrapS = "repeat"
|
||||
token inputs:wrapT = "repeat"
|
||||
float3 outputs:rgb
|
||||
}
|
||||
|
||||
def Shader "PrimvarReader_st"
|
||||
{
|
||||
uniform token info:id = "UsdPrimvarReader_float2"
|
||||
string inputs:varname.connect = </root/_materials/node_graph_BaseColor.inputs:frame:st>
|
||||
float2 outputs:result
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,6 +533,17 @@ class USDImportTest(AbstractUSDTest):
|
||||
assert_attribute(mat, "f_vec", "Vector", "Normal")
|
||||
assert_attribute(mat, "f_float", "Fac", "Roughness")
|
||||
|
||||
def test_import_material_node_graph(self):
|
||||
"""Verify we can follow connections through NodeGraph defs."""
|
||||
|
||||
testfile = str(self.testdir / "usd_materials_node_graph.usda")
|
||||
res = bpy.ops.wm.usd_import(filepath=testfile)
|
||||
self.assertEqual({'FINISHED'}, res)
|
||||
|
||||
# If NodeGraph traversal is missing or broken, the Image Texture and UV Map nodes will be missing
|
||||
mat = bpy.data.materials["Material"]
|
||||
self.assert_all_nodes_present(mat, ["Principled BSDF", "Image Texture", "UV Map", "Material Output"])
|
||||
|
||||
def test_import_shader_varname_with_connection(self):
|
||||
"""Test importing USD shader where uv primvar is a connection"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user