From ea16b7913397c120944d3fa2c87968bc957c215f Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Fri, 1 Sep 2023 21:57:55 +0300 Subject: [PATCH 1/6] Improvements in NodeParser, separated OutputMaterialNodeParser declaration to output_material.h --- source/blender/nodes/shader/CMakeLists.txt | 1 + .../nodes/shader/materialx/material.cc | 10 ++- .../shader/materialx/nodes/bsdf_principled.cc | 6 +- .../shader/materialx/nodes/node_parser.cc | 79 +++++++++---------- .../shader/materialx/nodes/node_parser.h | 11 ++- .../shader/materialx/nodes/output_material.cc | 16 +++- .../shader/materialx/nodes/output_material.h | 22 ++++++ .../shader/materialx/nodes/tex_checker.cc | 2 +- .../shader/materialx/nodes/tex_environment.cc | 2 +- .../nodes/shader/materialx/nodes/tex_image.cc | 2 +- .../nodes/shader/materialx/nodes/tex_noise.cc | 2 +- 11 files changed, 96 insertions(+), 57 deletions(-) create mode 100644 source/blender/nodes/shader/materialx/nodes/output_material.h diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt index 1dec91b8b3ad..114ab576101d 100644 --- a/source/blender/nodes/shader/CMakeLists.txt +++ b/source/blender/nodes/shader/CMakeLists.txt @@ -162,6 +162,7 @@ if(WITH_MATERIALX) materialx/material.h materialx/nodes/node_item.h materialx/nodes/node_parser.h + materialx/nodes/output_material.h ) list(APPEND LIB MaterialXCore diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 502ea74f5fd8..0899d0b34e60 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -3,7 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ #include "material.h" -#include "nodes/node_parser.h" +#include "nodes/output_material.h" #include @@ -45,6 +45,7 @@ static void create_standard_surface(MaterialX::GraphElement *graph, Material *ma MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material) { + CLOG_INFO(LOG_MATERIALX_SHADER, 0, "Material: %s", material->id.name); MaterialX::DocumentPtr doc = MaterialX::createDocument(); if (material->use_nodes) { export_nodegraph(doc.get(), depsgraph, material); @@ -52,8 +53,11 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater else { create_standard_surface(doc.get(), material); } - std::string str = MaterialX::writeToXmlString(doc); - CLOG_INFO(LOG_MATERIALX_SHADER, 1, "Material: %s\n%s", material->id.name, str.c_str()); + CLOG_INFO(LOG_MATERIALX_SHADER, + 2, + "Material: %s\n%s", + material->id.name, + MaterialX::writeToXmlString(doc).c_str()); return doc; } diff --git a/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc index 5a5e9f7c053d..43a046cc9292 100644 --- a/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc +++ b/source/blender/nodes/shader/materialx/nodes/bsdf_principled.cc @@ -68,7 +68,7 @@ NodeItem BSDFPrincipledNodeParser::compute() NodeItem tangent = get_input_link("Tangent"); /* Creating standard_surface */ - NodeItem res = create_node("standard_surface", "surfaceshader", false); + NodeItem res = create_node("standard_surface", "surfaceshader"); res.set_input("base", 1.0, "float"); res.set_input("base_color", base_color.to_color3()); res.set_input("diffuse_roughness", roughness); @@ -90,7 +90,9 @@ NodeItem BSDFPrincipledNodeParser::compute() res.set_input("specular_IOR", ior); if (anisotropic) { res.set_input("specular_anisotropy", anisotropic); - res.set_input("specular_rotation", anisotropic_rotation); + if (anisotropic_rotation) { + res.set_input("specular_rotation", anisotropic_rotation); + } } } diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc index 2c8974406d9b..ad74e5e5b631 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -12,20 +12,16 @@ namespace blender::nodes::materialx { NodeParser::NodeParser(MaterialX::GraphElement *graph, const Depsgraph *depsgraph, const Material *material, - const bNode *node) - : graph(graph), depsgraph(depsgraph), material(material), node(node) + const bNode *node, + const bNodeSocket *socket_out) + : graph(graph), depsgraph(depsgraph), material(material), node(node), socket_out(socket_out) { } -NodeItem NodeParser::create_node(const std::string &mx_category, - const std::string &mx_type, - bool noname) +NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type) { NodeItem res = empty(); - res.node = graph->addNode(mx_category, - noname ? MaterialX::EMPTY_STRING : - MaterialX::createValidName(node->name), - mx_type); + res.node = graph->addNode(mx_category, MaterialX::EMPTY_STRING, mx_type); return res; } @@ -98,50 +94,43 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket) return res; } - const bNode *in_node = link->fromnode; + const bNode *from_node = link->fromnode; /* Passing NODE_REROUTE nodes */ - while (in_node->type == NODE_REROUTE) { - link = in_node->input_socket(0).link; + while (from_node->type == NODE_REROUTE) { + link = from_node->input_socket(0).link; if (!(link && link->is_used())) { return res; } - in_node = link->fromnode; + from_node = link->fromnode; } /* Getting required NodeParser object */ +#define CASE_NODE_TYPE(type, T) \ + case type: \ + parser = std::make_unique(graph, depsgraph, material, from_node, link->fromsock); \ + break; + std::unique_ptr parser; - switch (in_node->typeinfo->type) { - case SH_NODE_BSDF_PRINCIPLED: - parser = std::make_unique(graph, depsgraph, material, in_node); - break; - case SH_NODE_INVERT: - parser = std::make_unique(graph, depsgraph, material, in_node); - break; - case SH_NODE_MATH: - parser = std::make_unique(graph, depsgraph, material, in_node); - break; - case SH_NODE_MIX_RGB_LEGACY: - parser = std::make_unique(graph, depsgraph, material, in_node); - break; - case SH_NODE_TEX_IMAGE: - parser = std::make_unique(graph, depsgraph, material, in_node); - break; - case SH_NODE_TEX_ENVIRONMENT: - parser = std::make_unique(graph, depsgraph, material, in_node); - break; - case SH_NODE_TEX_NOISE: - parser = std::make_unique(graph, depsgraph, material, in_node); - break; - case SH_NODE_TEX_CHECKER: - parser = std::make_unique(graph, depsgraph, material, in_node); - break; + switch (from_node->typeinfo->type) { + CASE_NODE_TYPE(SH_NODE_BSDF_PRINCIPLED, BSDFPrincipledNodeParser) + CASE_NODE_TYPE(SH_NODE_INVERT, InvertNodeParser) + CASE_NODE_TYPE(SH_NODE_MATH, MathNodeParser) + CASE_NODE_TYPE(SH_NODE_MIX_RGB_LEGACY, MixRGBNodeParser) + CASE_NODE_TYPE(SH_NODE_TEX_CHECKER, TexCheckerNodeParser) + CASE_NODE_TYPE(SH_NODE_TEX_ENVIRONMENT, TexEnvironmentNodeParser) + CASE_NODE_TYPE(SH_NODE_TEX_IMAGE, TexImageNodeParser) + CASE_NODE_TYPE(SH_NODE_TEX_NOISE, TexNoiseNodeParser) + default: - CLOG_WARN(LOG_MATERIALX_SHADER, "Unsupported node: %s (%d)", in_node->name, in_node->type); + CLOG_WARN(LOG_MATERIALX_SHADER, + "Unsupported node: %s [%d]", + from_node->name, + from_node->typeinfo->type); return res; } - res = parser->compute(); + res = parser->compute_full(); return res; } @@ -154,4 +143,14 @@ NodeItem NodeParser::get_input_value(const bNodeSocket &socket) return res; } +NodeItem NodeParser::compute_full() +{ + CLOG_INFO(LOG_MATERIALX_SHADER, 1, "Node: %s [%d]", node->name, node->typeinfo->type); + NodeItem res = compute(); + if (res.node) { + res.node->setName(MaterialX::createValidName(std::string(node->name) + "." + socket_out->name)); + } + return res; +} + } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.h b/source/blender/nodes/shader/materialx/nodes/node_parser.h index 86d1935e41fd..f3412c693dfa 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.h +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.h @@ -18,20 +18,19 @@ class NodeParser { const Depsgraph *depsgraph; const Material *material; const bNode *node; + const bNodeSocket *socket_out; public: NodeParser(MaterialX::GraphElement *graph, const Depsgraph *depsgraph, const Material *material, - const bNode *node); + const bNode *node, + const bNodeSocket *socket_out); virtual ~NodeParser() = default; - virtual NodeItem compute() = 0; protected: - NodeItem create_node(const std::string &mx_category, - const std::string &mx_type, - bool noname = true); + NodeItem create_node(const std::string &mx_category, const std::string &mx_type); NodeItem get_input_default(const std::string &name); NodeItem get_input_default(int index); NodeItem get_input_link(const std::string &name); @@ -45,6 +44,7 @@ class NodeParser { NodeItem get_input_default(const bNodeSocket &socket); NodeItem get_input_link(const bNodeSocket &socket); NodeItem get_input_value(const bNodeSocket &socket); + NodeItem compute_full(); }; template NodeItem NodeParser::value(const T &data) const @@ -63,7 +63,6 @@ DECLARE_PARSER(BSDFPrincipledNodeParser) DECLARE_PARSER(InvertNodeParser) DECLARE_PARSER(MathNodeParser) DECLARE_PARSER(MixRGBNodeParser) -DECLARE_PARSER(OutputMaterialNodeParser) DECLARE_PARSER(TexCheckerNodeParser) DECLARE_PARSER(TexEnvironmentNodeParser) DECLARE_PARSER(TexImageNodeParser) diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.cc b/source/blender/nodes/shader/materialx/nodes/output_material.cc index 81d00737027d..fdb779de41ac 100644 --- a/source/blender/nodes/shader/materialx/nodes/output_material.cc +++ b/source/blender/nodes/shader/materialx/nodes/output_material.cc @@ -2,19 +2,31 @@ * * SPDX-License-Identifier: GPL-2.0-or-later */ -#include "node_parser.h" +#include "output_material.h" namespace blender::nodes::materialx { +OutputMaterialNodeParser::OutputMaterialNodeParser(MaterialX::GraphElement *graph, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node) + : NodeParser(graph, depsgraph, material, node, nullptr) +{ +} NodeItem OutputMaterialNodeParser::compute() { NodeItem node = empty(); NodeItem surface = get_input_link("Surface"); if (surface) { - node = create_node("surfacematerial", "material", false); + node = create_node("surfacematerial", "material"); node.set_input("surfaceshader", surface); } return node; } +NodeItem OutputMaterialNodeParser::compute_default() +{ + return empty(); +} + } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.h b/source/blender/nodes/shader/materialx/nodes/output_material.h new file mode 100644 index 000000000000..35a1703b189c --- /dev/null +++ b/source/blender/nodes/shader/materialx/nodes/output_material.h @@ -0,0 +1,22 @@ +/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation + * + * SPDX-License-Identifier: GPL-2.0-or-later */ + +#pragma once + +#include "node_parser.h" + +namespace blender::nodes::materialx { + +class OutputMaterialNodeParser : public NodeParser { + public: + OutputMaterialNodeParser(MaterialX::GraphElement *graph, + const Depsgraph *depsgraph, + const Material *material, + const bNode *node); + + NodeItem compute() override; + NodeItem compute_default(); +}; + +} // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/tex_checker.cc b/source/blender/nodes/shader/materialx/nodes/tex_checker.cc index f04f8ed2c457..078c1032bdf2 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_checker.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_checker.cc @@ -42,7 +42,7 @@ NodeItem TexCheckerNodeParser::compute() NodeItem ifequal = (modulo_x.floor() + modulo_y.floor()).if_else("==", value(1.0f), value(0.0f), value(1.0f)); - NodeItem res = create_node("mix", "color3", false); + NodeItem res = create_node("mix", "color3"); res.set_input("fg", color1.to_color3()); res.set_input("bg", color2.to_color3()); res.set_input("mix", ifequal); diff --git a/source/blender/nodes/shader/materialx/nodes/tex_environment.cc b/source/blender/nodes/shader/materialx/nodes/tex_environment.cc index a6048db0412c..826d8b15a22a 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_environment.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_environment.cc @@ -24,7 +24,7 @@ NodeItem TexEnvironmentNodeParser::compute() #endif NodeItem texcoord = create_node("texcoord", "vector2"); - NodeItem res = create_node("image", "color3", false); + NodeItem res = create_node("image", "color3"); res.set_input("file", image_path, "filename"); res.set_input("texcoord", texcoord); return res; diff --git a/source/blender/nodes/shader/materialx/nodes/tex_image.cc b/source/blender/nodes/shader/materialx/nodes/tex_image.cc index 9d0d3d033195..855c28ca0ad3 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_image.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_image.cc @@ -24,7 +24,7 @@ NodeItem TexImageNodeParser::compute() #endif NodeItem texcoord = create_node("texcoord", "vector2"); - NodeItem res = create_node("image", "color3", false); + NodeItem res = create_node("image", "color3"); res.set_input("file", image_path, "filename"); res.set_input("texcoord", texcoord); return res; diff --git a/source/blender/nodes/shader/materialx/nodes/tex_noise.cc b/source/blender/nodes/shader/materialx/nodes/tex_noise.cc index 63268d1fd8c6..d3a016c63208 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_noise.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_noise.cc @@ -18,7 +18,7 @@ NodeItem TexNoiseNodeParser::compute() NodeItem texcoord = create_node("position", "vector3"); - NodeItem res = create_node("fractal3d", "color3", false); + NodeItem res = create_node("fractal3d", "color3"); res.set_input("position", texcoord * scale); res.set_input("octaves", detail); res.set_input("lacunarity", lacunarity); -- 2.30.2 From 87a61b8edfbce0f90071558d70f17af133fe521e Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 2 Sep 2023 00:42:50 +0300 Subject: [PATCH 2/6] Improvements and code cleanup --- .../nodes/shader/materialx/material.cc | 38 +++++-------------- .../blender/nodes/shader/materialx/material.h | 4 +- .../nodes/shader/materialx/nodes/node_item.cc | 5 +++ .../nodes/shader/materialx/nodes/node_item.h | 1 + .../shader/materialx/nodes/node_parser.cc | 10 ++--- .../shader/materialx/nodes/output_material.cc | 30 +++++++++++---- .../shader/materialx/nodes/output_material.h | 2 +- 7 files changed, 47 insertions(+), 43 deletions(-) diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 0899d0b34e60..1e88124b3570 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -17,42 +17,22 @@ namespace blender::nodes::materialx { CLG_LOGREF_DECLARE_GLOBAL(LOG_MATERIALX_SHADER, "materialx.shader"); -static void export_nodegraph(MaterialX::GraphElement *graph, - Depsgraph *depsgraph, - Material *material) -{ - material->nodetree->ensure_topology_cache(); - - bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL); - OutputMaterialNodeParser parser(graph, depsgraph, material, output_node); - parser.compute(); -} - -static void create_standard_surface(MaterialX::GraphElement *graph, Material *material) -{ - MaterialX::NodePtr standard_surface = graph->addNode( - "standard_surface", MaterialX::EMPTY_STRING, "surfaceshader"); - - standard_surface->addInput("base", "float")->setValue(1.0); - standard_surface->addInput("base_color", "color3") - ->setValue(MaterialX::Color3(material->r, material->g, material->b)); - - MaterialX::NodePtr surfacematerial = graph->addNode( - "surfacematerial", MaterialX::EMPTY_STRING, "material"); - surfacematerial->addInput(standard_surface->getType(), standard_surface->getType()) - ->setNodeName(standard_surface->getName()); -} - -MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material) +MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, + Material *material, + const std::string &socket_name) { CLOG_INFO(LOG_MATERIALX_SHADER, 0, "Material: %s", material->id.name); + MaterialX::DocumentPtr doc = MaterialX::createDocument(); if (material->use_nodes) { - export_nodegraph(doc.get(), depsgraph, material); + material->nodetree->ensure_topology_cache(); + bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL); + OutputMaterialNodeParser(doc.get(), depsgraph, material, output_node).compute(socket_name); } else { - create_standard_surface(doc.get(), material); + OutputMaterialNodeParser(doc.get(), depsgraph, material, nullptr).compute_default(); } + CLOG_INFO(LOG_MATERIALX_SHADER, 2, "Material: %s\n%s", diff --git a/source/blender/nodes/shader/materialx/material.h b/source/blender/nodes/shader/materialx/material.h index b32f3ff2962a..4c90febce6c9 100644 --- a/source/blender/nodes/shader/materialx/material.h +++ b/source/blender/nodes/shader/materialx/material.h @@ -15,6 +15,8 @@ namespace blender::nodes::materialx { extern struct CLG_LogRef *LOG_MATERIALX_SHADER; -MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material); +MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, + Material *material, + const std::string &socket_name = "Surface"); } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/node_item.cc b/source/blender/nodes/shader/materialx/nodes/node_item.cc index f3cf3779058c..2300b63ded5f 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_item.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_item.cc @@ -79,6 +79,11 @@ void NodeItem::add_output(const std::string &name, const std::string &mx_type) node->addOutput(name, mx_type); } +void NodeItem::set_name(const std::string &name) +{ + node->setName(MaterialX::createValidName(name)); +} + NodeItem::operator bool() const { return value || node; diff --git a/source/blender/nodes/shader/materialx/nodes/node_item.h b/source/blender/nodes/shader/materialx/nodes/node_item.h index 2f746cda36b7..f0d5c8fc9704 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_item.h +++ b/source/blender/nodes/shader/materialx/nodes/node_item.h @@ -33,6 +33,7 @@ class NodeItem { const MaterialX::NodePtr node, const std::string &output_name = ""); void add_output(const std::string &name, const std::string &mx_type); + void set_name(const std::string &name); operator bool() const; NodeItem operator+(const NodeItem &other) const; diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc index ad74e5e5b631..6547aabffd69 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -105,13 +105,12 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket) from_node = link->fromnode; } - /* Getting required NodeParser object */ + /* Computing from_node with required NodeParser object */ #define CASE_NODE_TYPE(type, T) \ case type: \ - parser = std::make_unique(graph, depsgraph, material, from_node, link->fromsock); \ + res = T(graph, depsgraph, material, from_node, link->fromsock).compute_full(); \ break; - std::unique_ptr parser; switch (from_node->typeinfo->type) { CASE_NODE_TYPE(SH_NODE_BSDF_PRINCIPLED, BSDFPrincipledNodeParser) CASE_NODE_TYPE(SH_NODE_INVERT, InvertNodeParser) @@ -130,7 +129,6 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket) return res; } - res = parser->compute_full(); return res; } @@ -148,7 +146,9 @@ NodeItem NodeParser::compute_full() CLOG_INFO(LOG_MATERIALX_SHADER, 1, "Node: %s [%d]", node->name, node->typeinfo->type); NodeItem res = compute(); if (res.node) { - res.node->setName(MaterialX::createValidName(std::string(node->name) + "." + socket_out->name)); + res.set_name(node->output_sockets().size() == 1 ? + std::string(node->name) : + std::string(node->name) + "_" + socket_out->name); } return res; } diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.cc b/source/blender/nodes/shader/materialx/nodes/output_material.cc index fdb779de41ac..39df44ccb5c5 100644 --- a/source/blender/nodes/shader/materialx/nodes/output_material.cc +++ b/source/blender/nodes/shader/materialx/nodes/output_material.cc @@ -15,18 +15,34 @@ OutputMaterialNodeParser::OutputMaterialNodeParser(MaterialX::GraphElement *grap NodeItem OutputMaterialNodeParser::compute() { - NodeItem node = empty(); - NodeItem surface = get_input_link("Surface"); - if (surface) { - node = create_node("surfacematerial", "material"); - node.set_input("surfaceshader", surface); + return empty(); +} + +NodeItem OutputMaterialNodeParser::compute(const std::string &socket_name) +{ + NodeItem surface = empty(); + if (node) { + surface = get_input_link(socket_name); } - return node; + else { + surface = create_node("standard_surface", "surfaceshader"); + surface.set_input("base_color", value(MaterialX::Color3(1.0f, 0.0f, 1.0f))); + } + NodeItem res = create_node("surfacematerial", "material"); + res.set_name("Material"); + res.set_input("surfaceshader", surface); + return res; } NodeItem OutputMaterialNodeParser::compute_default() { - return empty(); + NodeItem surface = create_node("standard_surface", "surfaceshader"); + surface.set_input("base_color", value(MaterialX::Color3(material->r, material->g, material->b))); + + NodeItem res = create_node("surfacematerial", "material"); + res.set_name("Material"); + res.set_input("surfaceshader", surface); + return res; } } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.h b/source/blender/nodes/shader/materialx/nodes/output_material.h index 35a1703b189c..986c926f33d4 100644 --- a/source/blender/nodes/shader/materialx/nodes/output_material.h +++ b/source/blender/nodes/shader/materialx/nodes/output_material.h @@ -14,8 +14,8 @@ class OutputMaterialNodeParser : public NodeParser { const Depsgraph *depsgraph, const Material *material, const bNode *node); - NodeItem compute() override; + NodeItem compute(const std::string &socket_name); NodeItem compute_default(); }; -- 2.30.2 From a52af50029cf3b7e4d07e75873eac0ff19093bb0 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 2 Sep 2023 01:07:23 +0300 Subject: [PATCH 3/6] More correct compute_default(); --- .../blender/nodes/shader/materialx/nodes/node_parser.cc | 2 +- .../nodes/shader/materialx/nodes/output_material.cc | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc index 6547aabffd69..bcf277c8e6d6 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -143,7 +143,7 @@ NodeItem NodeParser::get_input_value(const bNodeSocket &socket) NodeItem NodeParser::compute_full() { - CLOG_INFO(LOG_MATERIALX_SHADER, 1, "Node: %s [%d]", node->name, node->typeinfo->type); + CLOG_INFO(LOG_MATERIALX_SHADER, 1, "%s [%d]", node->name, node->typeinfo->type); NodeItem res = compute(); if (res.node) { res.set_name(node->output_sockets().size() == 1 ? diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.cc b/source/blender/nodes/shader/materialx/nodes/output_material.cc index 39df44ccb5c5..b1e316be3361 100644 --- a/source/blender/nodes/shader/materialx/nodes/output_material.cc +++ b/source/blender/nodes/shader/materialx/nodes/output_material.cc @@ -38,6 +38,15 @@ NodeItem OutputMaterialNodeParser::compute_default() { NodeItem surface = create_node("standard_surface", "surfaceshader"); surface.set_input("base_color", value(MaterialX::Color3(material->r, material->g, material->b))); + surface.set_input("diffuse_roughness", value(material->roughness)); + if (material->metallic > 0.0f) { + surface.set_input("metalness", value(material->metallic)); + } + if (material->spec) { + surface.set_input("specular", value(material->spec)); + surface.set_input("specular_color", value(material->spec)); + surface.set_input("specular_roughness", value(material->roughness)); + } NodeItem res = create_node("surfacematerial", "material"); res.set_name("Material"); -- 2.30.2 From 46a1440702a7d17ac282151d82b3ce215efa5291 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 2 Sep 2023 01:17:22 +0300 Subject: [PATCH 4/6] Renamings --- .../nodes/shader/materialx/nodes/math.cc | 4 +-- .../shader/materialx/nodes/node_parser.cc | 28 +++++++++---------- .../shader/materialx/nodes/node_parser.h | 12 ++++---- .../shader/materialx/nodes/output_material.cc | 18 ++++++------ .../shader/materialx/nodes/tex_environment.cc | 8 +++--- .../nodes/shader/materialx/nodes/tex_image.cc | 8 +++--- 6 files changed, 39 insertions(+), 39 deletions(-) diff --git a/source/blender/nodes/shader/materialx/nodes/math.cc b/source/blender/nodes/shader/materialx/nodes/math.cc index 8787bf2ca390..cbd5d6fd023e 100644 --- a/source/blender/nodes/shader/materialx/nodes/math.cc +++ b/source/blender/nodes/shader/materialx/nodes/math.cc @@ -10,7 +10,7 @@ namespace blender::nodes::materialx { NodeItem MathNodeParser::compute() { /* TODO: finish some math operations */ - auto op = node->custom1; + auto op = node_->custom1; NodeItem res = empty(); /* Single operand operations */ @@ -158,7 +158,7 @@ NodeItem MathNodeParser::compute() } } - bool clamp_output = node->custom2 != 0; + bool clamp_output = node_->custom2 != 0; if (clamp_output && res) { res = res.clamp(); } diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc index bcf277c8e6d6..78e3f55a4581 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -14,50 +14,50 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph, const Material *material, const bNode *node, const bNodeSocket *socket_out) - : graph(graph), depsgraph(depsgraph), material(material), node(node), socket_out(socket_out) + : graph_(graph), depsgraph_(depsgraph), material_(material), node_(node), socket_out_(socket_out) { } NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type) { NodeItem res = empty(); - res.node = graph->addNode(mx_category, MaterialX::EMPTY_STRING, mx_type); + res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, mx_type); return res; } NodeItem NodeParser::get_input_default(const std::string &name) { - return get_input_default(node->input_by_identifier(name)); + return get_input_default(node_->input_by_identifier(name)); } NodeItem NodeParser::get_input_default(int index) { - return get_input_default(node->input_socket(index)); + return get_input_default(node_->input_socket(index)); } NodeItem NodeParser::get_input_link(const std::string &name) { - return get_input_link(node->input_by_identifier(name)); + return get_input_link(node_->input_by_identifier(name)); } NodeItem NodeParser::get_input_link(int index) { - return get_input_link(node->input_socket(index)); + return get_input_link(node_->input_socket(index)); } NodeItem NodeParser::get_input_value(const std::string &name) { - return get_input_value(node->input_by_identifier(name)); + return get_input_value(node_->input_by_identifier(name)); } NodeItem NodeParser::get_input_value(int index) { - return get_input_value(node->input_socket(index)); + return get_input_value(node_->input_socket(index)); } NodeItem NodeParser::empty() const { - return NodeItem(graph); + return NodeItem(graph_); } NodeItem NodeParser::get_input_default(const bNodeSocket &socket) @@ -108,7 +108,7 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket) /* Computing from_node with required NodeParser object */ #define CASE_NODE_TYPE(type, T) \ case type: \ - res = T(graph, depsgraph, material, from_node, link->fromsock).compute_full(); \ + res = T(graph_, depsgraph_, material_, from_node, link->fromsock).compute_full(); \ break; switch (from_node->typeinfo->type) { @@ -143,12 +143,12 @@ NodeItem NodeParser::get_input_value(const bNodeSocket &socket) NodeItem NodeParser::compute_full() { - CLOG_INFO(LOG_MATERIALX_SHADER, 1, "%s [%d]", node->name, node->typeinfo->type); + CLOG_INFO(LOG_MATERIALX_SHADER, 1, "%s [%d]", node_->name, node_->typeinfo->type); NodeItem res = compute(); if (res.node) { - res.set_name(node->output_sockets().size() == 1 ? - std::string(node->name) : - std::string(node->name) + "_" + socket_out->name); + res.set_name(node_->output_sockets().size() == 1 ? + std::string(node_->name) : + std::string(node_->name) + "_" + socket_out_->name); } return res; } diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.h b/source/blender/nodes/shader/materialx/nodes/node_parser.h index f3412c693dfa..12f77c36e257 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.h +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.h @@ -13,12 +13,12 @@ namespace blender::nodes::materialx { class NodeParser { - public: - MaterialX::GraphElement *graph; - const Depsgraph *depsgraph; - const Material *material; - const bNode *node; - const bNodeSocket *socket_out; + protected: + MaterialX::GraphElement *graph_; + const Depsgraph *depsgraph_; + const Material *material_; + const bNode *node_; + const bNodeSocket *socket_out_; public: NodeParser(MaterialX::GraphElement *graph, diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.cc b/source/blender/nodes/shader/materialx/nodes/output_material.cc index b1e316be3361..e35721e522ca 100644 --- a/source/blender/nodes/shader/materialx/nodes/output_material.cc +++ b/source/blender/nodes/shader/materialx/nodes/output_material.cc @@ -21,7 +21,7 @@ NodeItem OutputMaterialNodeParser::compute() NodeItem OutputMaterialNodeParser::compute(const std::string &socket_name) { NodeItem surface = empty(); - if (node) { + if (node_) { surface = get_input_link(socket_name); } else { @@ -37,15 +37,15 @@ NodeItem OutputMaterialNodeParser::compute(const std::string &socket_name) NodeItem OutputMaterialNodeParser::compute_default() { NodeItem surface = create_node("standard_surface", "surfaceshader"); - surface.set_input("base_color", value(MaterialX::Color3(material->r, material->g, material->b))); - surface.set_input("diffuse_roughness", value(material->roughness)); - if (material->metallic > 0.0f) { - surface.set_input("metalness", value(material->metallic)); + surface.set_input("base_color", value(MaterialX::Color3(material_->r, material_->g, material_->b))); + surface.set_input("diffuse_roughness", value(material_->roughness)); + if (material_->metallic > 0.0f) { + surface.set_input("metalness", value(material_->metallic)); } - if (material->spec) { - surface.set_input("specular", value(material->spec)); - surface.set_input("specular_color", value(material->spec)); - surface.set_input("specular_roughness", value(material->roughness)); + if (material_->spec) { + surface.set_input("specular", value(material_->spec)); + surface.set_input("specular_color", value(material_->spec)); + surface.set_input("specular_roughness", value(material_->roughness)); } NodeItem res = create_node("surfacematerial", "material"); diff --git a/source/blender/nodes/shader/materialx/nodes/tex_environment.cc b/source/blender/nodes/shader/materialx/nodes/tex_environment.cc index 826d8b15a22a..f2aede4cb4b6 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_environment.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_environment.cc @@ -12,10 +12,10 @@ namespace blender::nodes::materialx { NodeItem TexEnvironmentNodeParser::compute() { - Image *image = (Image *)node->id; - NodeTexEnvironment *tex = static_cast(node->storage); - Scene *scene = DEG_get_input_scene(depsgraph); - Main *bmain = DEG_get_bmain(depsgraph); + Image *image = (Image *)node_->id; + NodeTexEnvironment *tex = static_cast(node_->storage); + Scene *scene = DEG_get_input_scene(depsgraph_); + Main *bmain = DEG_get_bmain(depsgraph_); std::string image_path; /* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contains * pretty general code, so could be moved from bf_usd project. */ diff --git a/source/blender/nodes/shader/materialx/nodes/tex_image.cc b/source/blender/nodes/shader/materialx/nodes/tex_image.cc index 855c28ca0ad3..2a2625259ef7 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_image.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_image.cc @@ -12,10 +12,10 @@ namespace blender::nodes::materialx { NodeItem TexImageNodeParser::compute() { - Image *image = (Image *)node->id; - NodeTexImage *tex = static_cast(node->storage); - Scene *scene = DEG_get_input_scene(depsgraph); - Main *bmain = DEG_get_bmain(depsgraph); + Image *image = (Image *)node_->id; + NodeTexImage *tex = static_cast(node_->storage); + Scene *scene = DEG_get_input_scene(depsgraph_); + Main *bmain = DEG_get_bmain(depsgraph_); std::string image_path; /* TODO: What if Blender built without Hydra? Also io::hydra::cache_or_get_image_file contains * pretty general code, so could be moved from bf_usd project. */ -- 2.30.2 From d3d9a29b60e86685a3a168d9a4004584b1765e53 Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 2 Sep 2023 01:54:42 +0300 Subject: [PATCH 5/6] Fix: added check if node was already computed. Code cleanup --- .../nodes/shader/materialx/nodes/node_item.cc | 5 ----- .../nodes/shader/materialx/nodes/node_item.h | 1 - .../shader/materialx/nodes/node_parser.cc | 18 ++++++++++++++---- .../nodes/shader/materialx/nodes/node_parser.h | 1 + 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/source/blender/nodes/shader/materialx/nodes/node_item.cc b/source/blender/nodes/shader/materialx/nodes/node_item.cc index 2300b63ded5f..f3cf3779058c 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_item.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_item.cc @@ -79,11 +79,6 @@ void NodeItem::add_output(const std::string &name, const std::string &mx_type) node->addOutput(name, mx_type); } -void NodeItem::set_name(const std::string &name) -{ - node->setName(MaterialX::createValidName(name)); -} - NodeItem::operator bool() const { return value || node; diff --git a/source/blender/nodes/shader/materialx/nodes/node_item.h b/source/blender/nodes/shader/materialx/nodes/node_item.h index f0d5c8fc9704..2f746cda36b7 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_item.h +++ b/source/blender/nodes/shader/materialx/nodes/node_item.h @@ -33,7 +33,6 @@ class NodeItem { const MaterialX::NodePtr node, const std::string &output_name = ""); void add_output(const std::string &name, const std::string &mx_type); - void set_name(const std::string &name); operator bool() const; NodeItem operator+(const NodeItem &other) const; diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc index 78e3f55a4581..fdab68b1d9a0 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -60,6 +60,13 @@ NodeItem NodeParser::empty() const return NodeItem(graph_); } +std::string NodeParser::node_name(const bNode *node, const bNodeSocket *socket_out) +{ + return MaterialX::createValidName(node->output_sockets().size() == 1 ? + std::string(node->name) : + std::string(node->name) + "_" + socket_out->name); +} + NodeItem NodeParser::get_input_default(const bNodeSocket &socket) { NodeItem res = empty(); @@ -105,6 +112,12 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket) from_node = link->fromnode; } + /* Checking if node was already computed */ + res.node = graph_->getNode(node_name(from_node, link->fromsock)); + if (res.node) { + return res; + } + /* Computing from_node with required NodeParser object */ #define CASE_NODE_TYPE(type, T) \ case type: \ @@ -126,7 +139,6 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket) "Unsupported node: %s [%d]", from_node->name, from_node->typeinfo->type); - return res; } return res; @@ -146,9 +158,7 @@ NodeItem NodeParser::compute_full() CLOG_INFO(LOG_MATERIALX_SHADER, 1, "%s [%d]", node_->name, node_->typeinfo->type); NodeItem res = compute(); if (res.node) { - res.set_name(node_->output_sockets().size() == 1 ? - std::string(node_->name) : - std::string(node_->name) + "_" + socket_out_->name); + res.node->setName(node_name(node_, socket_out_)); } return res; } diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.h b/source/blender/nodes/shader/materialx/nodes/node_parser.h index 12f77c36e257..23aaffb5b9df 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.h +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.h @@ -41,6 +41,7 @@ class NodeParser { template NodeItem value(const T &data) const; private: + static std::string node_name(const bNode *node, const bNodeSocket *socket_out); NodeItem get_input_default(const bNodeSocket &socket); NodeItem get_input_link(const bNodeSocket &socket); NodeItem get_input_value(const bNodeSocket &socket); -- 2.30.2 From 979fb905756b87f840db730531901a9c9633bd1c Mon Sep 17 00:00:00 2001 From: Bogdan Nagirniak Date: Sat, 2 Sep 2023 02:22:27 +0300 Subject: [PATCH 6/6] Fixed TexChecker. Unified node name --- .../nodes/shader/materialx/nodes/node_parser.cc | 14 +++++++------- .../nodes/shader/materialx/nodes/node_parser.h | 2 +- .../shader/materialx/nodes/output_material.cc | 4 ++-- .../nodes/shader/materialx/nodes/tex_checker.cc | 9 ++------- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.cc b/source/blender/nodes/shader/materialx/nodes/node_parser.cc index fdab68b1d9a0..0b7c6e82ad60 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.cc +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.cc @@ -18,6 +18,13 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph, { } +std::string NodeParser::node_name(const bNode *node, const bNodeSocket *socket_out) +{ + return MaterialX::createValidName(node->output_sockets().size() <= 1 ? + std::string(node->name) : + std::string(node->name) + "_" + socket_out->name); +} + NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type) { NodeItem res = empty(); @@ -60,13 +67,6 @@ NodeItem NodeParser::empty() const return NodeItem(graph_); } -std::string NodeParser::node_name(const bNode *node, const bNodeSocket *socket_out) -{ - return MaterialX::createValidName(node->output_sockets().size() == 1 ? - std::string(node->name) : - std::string(node->name) + "_" + socket_out->name); -} - NodeItem NodeParser::get_input_default(const bNodeSocket &socket) { NodeItem res = empty(); diff --git a/source/blender/nodes/shader/materialx/nodes/node_parser.h b/source/blender/nodes/shader/materialx/nodes/node_parser.h index 23aaffb5b9df..bb9986896d99 100644 --- a/source/blender/nodes/shader/materialx/nodes/node_parser.h +++ b/source/blender/nodes/shader/materialx/nodes/node_parser.h @@ -30,6 +30,7 @@ class NodeParser { virtual NodeItem compute() = 0; protected: + static std::string node_name(const bNode *node, const bNodeSocket *socket_out); NodeItem create_node(const std::string &mx_category, const std::string &mx_type); NodeItem get_input_default(const std::string &name); NodeItem get_input_default(int index); @@ -41,7 +42,6 @@ class NodeParser { template NodeItem value(const T &data) const; private: - static std::string node_name(const bNode *node, const bNodeSocket *socket_out); NodeItem get_input_default(const bNodeSocket &socket); NodeItem get_input_link(const bNodeSocket &socket); NodeItem get_input_value(const bNodeSocket &socket); diff --git a/source/blender/nodes/shader/materialx/nodes/output_material.cc b/source/blender/nodes/shader/materialx/nodes/output_material.cc index e35721e522ca..5b5d9d0b7c66 100644 --- a/source/blender/nodes/shader/materialx/nodes/output_material.cc +++ b/source/blender/nodes/shader/materialx/nodes/output_material.cc @@ -29,7 +29,7 @@ NodeItem OutputMaterialNodeParser::compute(const std::string &socket_name) surface.set_input("base_color", value(MaterialX::Color3(1.0f, 0.0f, 1.0f))); } NodeItem res = create_node("surfacematerial", "material"); - res.set_name("Material"); + res.node->setName(node_name(node_, nullptr)); res.set_input("surfaceshader", surface); return res; } @@ -49,7 +49,7 @@ NodeItem OutputMaterialNodeParser::compute_default() } NodeItem res = create_node("surfacematerial", "material"); - res.set_name("Material"); + res.node->setName("Material_Default"); res.set_input("surfaceshader", surface); return res; } diff --git a/source/blender/nodes/shader/materialx/nodes/tex_checker.cc b/source/blender/nodes/shader/materialx/nodes/tex_checker.cc index 078c1032bdf2..63266bd5081a 100644 --- a/source/blender/nodes/shader/materialx/nodes/tex_checker.cc +++ b/source/blender/nodes/shader/materialx/nodes/tex_checker.cc @@ -16,16 +16,11 @@ NodeItem TexCheckerNodeParser::compute() float v = scale.value->asA(); scale = value(MaterialX::Vector2(v, v)); } - /* Modifier to follow Cycles result */ - scale = scale * value(4.0f); NodeItem texcoord = create_node("texcoord", "vector2"); NodeItem place2d = create_node("place2d", "vector2"); place2d.set_input("texcoord", texcoord * scale); - /* TODO: fix offset: - * place2d.set_input("offset", offset); */ - NodeItem separate = create_node("separate2", "multioutput"); separate.set_input("in", place2d); separate.add_output("outx", "float"); @@ -43,8 +38,8 @@ NodeItem TexCheckerNodeParser::compute() (modulo_x.floor() + modulo_y.floor()).if_else("==", value(1.0f), value(0.0f), value(1.0f)); NodeItem res = create_node("mix", "color3"); - res.set_input("fg", color1.to_color3()); - res.set_input("bg", color2.to_color3()); + res.set_input("bg", color1.to_color3()); + res.set_input("fg", color2.to_color3()); res.set_input("mix", ifequal); return res; } -- 2.30.2