From 2a10096ff459c1c455a220a7b4023a16d0a951f9 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Fri, 22 Sep 2023 16:07:51 +0300 Subject: [PATCH 1/4] MaterialX: added callback ExportImageFunction for image caching --- source/blender/io/usd/hydra/material.cc | 3 +- .../nodes/shader/materialx/group_nodes.cc | 10 ++++-- .../nodes/shader/materialx/material.cc | 33 +++++++++++++++---- .../blender/nodes/shader/materialx/material.h | 6 +++- .../nodes/shader/materialx/node_parser.cc | 29 ++++++++++++---- .../nodes/shader/materialx/node_parser.h | 18 ++++++++-- .../nodes/node_shader_tex_environment.cc | 7 ++-- .../shader/nodes/node_shader_tex_image.cc | 7 ++-- 8 files changed, 85 insertions(+), 28 deletions(-) diff --git a/source/blender/io/usd/hydra/material.cc b/source/blender/io/usd/hydra/material.cc index 9fdf47965a86..afc5048efb2e 100644 --- a/source/blender/io/usd/hydra/material.cc +++ b/source/blender/io/usd/hydra/material.cc @@ -36,6 +36,7 @@ #include "intern/usd_exporter_context.h" #include "intern/usd_writer_material.h" #ifdef WITH_MATERIALX +# include "shader/materialx/node_parser.h" # include "shader/materialx/material.h" #endif namespace blender::io::hydra { @@ -79,7 +80,7 @@ void MaterialData::init() #ifdef WITH_MATERIALX if (scene_delegate_->use_materialx) { MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx( - scene_delegate_->depsgraph, (Material *)id); + scene_delegate_->depsgraph, (Material *)id, cache_or_get_image_file); pxr::UsdMtlxRead(doc, stage); /* Logging stage: creating lambda stage_str() for not to call stage->ExportToString() diff --git a/source/blender/nodes/shader/materialx/group_nodes.cc b/source/blender/nodes/shader/materialx/group_nodes.cc index 7f13fb108aef..9f6778ca01c1 100644 --- a/source/blender/nodes/shader/materialx/group_nodes.cc +++ b/source/blender/nodes/shader/materialx/group_nodes.cc @@ -32,8 +32,14 @@ NodeItem GroupNodeParser::compute() #endif NodeItem out = - GroupOutputNodeParser( - graph, depsgraph_, material_, node_out, socket_out_, NodeItem::Type::Any, this) + GroupOutputNodeParser(graph, + depsgraph_, + material_, + node_out, + socket_out_, + NodeItem::Type::Any, + this, + export_image_fn_) .compute_full(); #ifdef USE_MATERIALX_NODEGRAPH diff --git a/source/blender/nodes/shader/materialx/material.cc b/source/blender/nodes/shader/materialx/material.cc index 4da740b5431e..755c937ad740 100644 --- a/source/blender/nodes/shader/materialx/material.cc +++ b/source/blender/nodes/shader/materialx/material.cc @@ -54,7 +54,9 @@ class DefaultMaterialNodeParser : public NodeParser { } }; -MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material) +MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, + Material *material, + ExportImageFunction export_image_fn) { CLOG_INFO(LOG_MATERIALX_SHADER, 0, "Material: %s", material->id.name); @@ -63,19 +65,36 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater material->nodetree->ensure_topology_cache(); bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL); if (output_node) { - NodeParserData data = { - doc.get(), depsgraph, material, NodeItem::Type::Material, nullptr, NodeItem(doc.get())}; + NodeParserData data = {doc.get(), + depsgraph, + material, + NodeItem::Type::Material, + nullptr, + NodeItem(doc.get()), + export_image_fn}; output_node->typeinfo->materialx_fn(&data, output_node, nullptr); } else { - DefaultMaterialNodeParser( - doc.get(), depsgraph, material, nullptr, nullptr, NodeItem::Type::Material, nullptr) + DefaultMaterialNodeParser(doc.get(), + depsgraph, + material, + nullptr, + nullptr, + NodeItem::Type::Material, + nullptr, + export_image_fn) .compute_error(); } } else { - DefaultMaterialNodeParser( - doc.get(), depsgraph, material, nullptr, nullptr, NodeItem::Type::Material, nullptr) + DefaultMaterialNodeParser(doc.get(), + depsgraph, + material, + nullptr, + nullptr, + NodeItem::Type::Material, + nullptr, + export_image_fn) .compute(); } diff --git a/source/blender/nodes/shader/materialx/material.h b/source/blender/nodes/shader/materialx/material.h index 760b6cdef33b..d0a4a7e6a318 100644 --- a/source/blender/nodes/shader/materialx/material.h +++ b/source/blender/nodes/shader/materialx/material.h @@ -9,8 +9,12 @@ struct Depsgraph; struct Material; +class ExportImageFunction; + namespace blender::nodes::materialx { -MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *material); +MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, + Material *material, + ExportImageFunction export_image_fn); } // namespace blender::nodes::materialx diff --git a/source/blender/nodes/shader/materialx/node_parser.cc b/source/blender/nodes/shader/materialx/node_parser.cc index 158a8be33517..e22681cbe637 100644 --- a/source/blender/nodes/shader/materialx/node_parser.cc +++ b/source/blender/nodes/shader/materialx/node_parser.cc @@ -20,14 +20,16 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph, const bNode *node, const bNodeSocket *socket_out, NodeItem::Type to_type, - GroupNodeParser *group_parser) + GroupNodeParser *group_parser, + ExportImageFunction export_image_fn) : graph_(graph), depsgraph_(depsgraph), material_(material), node_(node), socket_out_(socket_out), to_type_(to_type), - group_parser_(group_parser) + group_parser_(group_parser), + export_image_fn_(export_image_fn) { } @@ -207,13 +209,25 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to } if (from_node->is_group()) { - return GroupNodeParser( - graph_, depsgraph_, material_, from_node, link->fromsock, to_type, group_parser_) + return GroupNodeParser(graph_, + depsgraph_, + material_, + from_node, + link->fromsock, + to_type, + group_parser_, + export_image_fn_) .compute_full(); } if (from_node->is_group_input()) { - return GroupInputNodeParser( - graph_, depsgraph_, material_, from_node, link->fromsock, to_type, group_parser_) + return GroupInputNodeParser(graph_, + depsgraph_, + material_, + from_node, + link->fromsock, + to_type, + group_parser_, + export_image_fn_) .compute_full(); } @@ -225,7 +239,8 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to return empty(); } - NodeParserData data = {graph_, depsgraph_, material_, to_type, group_parser_, empty()}; + NodeParserData data = { + graph_, depsgraph_, material_, to_type, group_parser_, empty(), export_image_fn_}; from_node->typeinfo->materialx_fn(&data, const_cast(from_node), link->fromsock); return data.result; } diff --git a/source/blender/nodes/shader/materialx/node_parser.h b/source/blender/nodes/shader/materialx/node_parser.h index eaaa5c1d35b2..f1d6d29af27e 100644 --- a/source/blender/nodes/shader/materialx/node_parser.h +++ b/source/blender/nodes/shader/materialx/node_parser.h @@ -17,6 +17,10 @@ namespace blender::nodes::materialx { extern struct CLG_LogRef *LOG_MATERIALX_SHADER; class GroupNodeParser; +typedef std::string (*ExportImageFunction)(Main *bmain, + Scene *Scene, + Image *image, + ImageUser *iuser); class NodeParser { protected: @@ -27,6 +31,7 @@ class NodeParser { const bNodeSocket *socket_out_; NodeItem::Type to_type_; GroupNodeParser *group_parser_; + ExportImageFunction export_image_fn_; public: NodeParser(MaterialX::GraphElement *graph, @@ -35,7 +40,8 @@ class NodeParser { const bNode *node, const bNodeSocket *socket_out, NodeItem::Type to_type, - GroupNodeParser *group_parser); + GroupNodeParser *group_parser, + ExportImageFunction export_image_fn); virtual ~NodeParser() = default; virtual NodeItem compute() = 0; @@ -82,6 +88,7 @@ struct NodeParserData { NodeItem::Type to_type; GroupNodeParser *group_parser; NodeItem result; + ExportImageFunction export_image_fn; }; #define NODE_SHADER_MATERIALX_BEGIN \ @@ -102,7 +109,14 @@ struct NodeParserData { { \ materialx::NodeParserData *d = reinterpret_cast(data); \ d->result = MaterialXNodeParser( \ - d->graph, d->depsgraph, d->material, node, out, d->to_type, d->group_parser) \ + d->graph, \ + d->depsgraph, \ + d->material, \ + node, \ + out, \ + d->to_type, \ + d->group_parser, \ + d->export_image_fn) \ .compute_full(); \ } diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc index 30ad01b489f8..6c87de3ba2fd 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc @@ -145,10 +145,9 @@ NODE_SHADER_MATERIALX_BEGIN Scene *scene = DEG_get_input_scene(depsgraph_); Main *bmain = DEG_get_bmain(depsgraph_); - /* 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. */ - std::string image_path = io::hydra::cache_or_get_image_file( - bmain, scene, image, &tex_env->iuser); + std::string image_path = export_image_fn_ ? + export_image_fn_(bmain, scene, image, &tex_env->iuser) : + image->id.name; NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2); if (!vector) { diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc index 537114b70d70..1d685dca582b 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc @@ -194,10 +194,9 @@ NODE_SHADER_MATERIALX_BEGIN Scene *scene = DEG_get_input_scene(depsgraph_); Main *bmain = DEG_get_bmain(depsgraph_); - /* 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. */ - std::string image_path = io::hydra::cache_or_get_image_file( - bmain, scene, image, &tex_image->iuser); + std::string image_path = export_image_fn_ ? + export_image_fn_(bmain, scene, image, &tex_image->iuser) : + image->id.name; NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2); if (!vector) { -- 2.30.2 From 9b20c9456d5eb3443a9729251cc1e4a1a75db8d3 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Fri, 22 Sep 2023 17:01:37 +0300 Subject: [PATCH 2/4] MaterialX: clean up code --- source/blender/nodes/shader/CMakeLists.txt | 7 ------- .../nodes/shader/nodes/node_shader_tex_environment.cc | 2 -- source/blender/nodes/shader/nodes/node_shader_tex_image.cc | 2 -- 3 files changed, 11 deletions(-) diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt index f437420e5d46..0caf0e164c56 100644 --- a/source/blender/nodes/shader/CMakeLists.txt +++ b/source/blender/nodes/shader/CMakeLists.txt @@ -22,13 +22,6 @@ set(INC ${CMAKE_BINARY_DIR}/source/blender/makesrna ) -if(WITH_HYDRA) - list(APPEND INC - ../../io/usd - ) - add_definitions(-DWITH_HYDRA) -endif() - set(INC_SYS ) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc index 6c87de3ba2fd..8b0477573671 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc @@ -11,8 +11,6 @@ #include "IMB_colormanagement.h" -#include "hydra/image.h" - #include "DEG_depsgraph_query.h" namespace blender::nodes::node_shader_tex_environment_cc { diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc index 1d685dca582b..56da8ce6ee18 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc @@ -11,8 +11,6 @@ #include "IMB_colormanagement.h" -#include "hydra/image.h" - #include "DEG_depsgraph_query.h" namespace blender::nodes::node_shader_tex_image_cc { -- 2.30.2 From 37bb54fc61562979ffc465a7a27515ee75cffb4a Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Fri, 22 Sep 2023 19:00:36 +0300 Subject: [PATCH 3/4] MaterialX: fix review comment --- source/blender/nodes/shader/materialx/node_parser.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source/blender/nodes/shader/materialx/node_parser.h b/source/blender/nodes/shader/materialx/node_parser.h index f1d6d29af27e..4bc332442c68 100644 --- a/source/blender/nodes/shader/materialx/node_parser.h +++ b/source/blender/nodes/shader/materialx/node_parser.h @@ -17,10 +17,8 @@ namespace blender::nodes::materialx { extern struct CLG_LogRef *LOG_MATERIALX_SHADER; class GroupNodeParser; -typedef std::string (*ExportImageFunction)(Main *bmain, - Scene *Scene, - Image *image, - ImageUser *iuser); + +using ExportImageFunction = std::function; class NodeParser { protected: -- 2.30.2 From e2939967a161b7bc7b954c6a13754705165057a1 Mon Sep 17 00:00:00 2001 From: "georgiy.m.markelov@gmail.com" Date: Fri, 22 Sep 2023 19:10:06 +0300 Subject: [PATCH 4/4] MaterialX: small refactoring --- .../nodes/shader/nodes/node_shader_tex_environment.cc | 11 ++++++----- .../nodes/shader/nodes/node_shader_tex_image.cc | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc index 8b0477573671..feaa0351d0b7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.cc @@ -140,12 +140,13 @@ NODE_SHADER_MATERIALX_BEGIN } NodeTexEnvironment *tex_env = static_cast(node_->storage); - Scene *scene = DEG_get_input_scene(depsgraph_); - Main *bmain = DEG_get_bmain(depsgraph_); - std::string image_path = export_image_fn_ ? - export_image_fn_(bmain, scene, image, &tex_env->iuser) : - image->id.name; + std::string image_path = image->id.name; + if (export_image_fn_) { + Scene *scene = DEG_get_input_scene(depsgraph_); + Main *bmain = DEG_get_bmain(depsgraph_); + image_path = export_image_fn_(bmain, scene, image, &tex_env->iuser); + } NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2); if (!vector) { diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc index 56da8ce6ee18..19f24f6c9cb7 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.cc +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.cc @@ -189,12 +189,13 @@ NODE_SHADER_MATERIALX_BEGIN Image *image = (Image *)node_->id; if (image) { NodeTexImage *tex_image = static_cast(node_->storage); - Scene *scene = DEG_get_input_scene(depsgraph_); - Main *bmain = DEG_get_bmain(depsgraph_); - std::string image_path = export_image_fn_ ? - export_image_fn_(bmain, scene, image, &tex_image->iuser) : - image->id.name; + std::string image_path = image->id.name; + if (export_image_fn_) { + Scene *scene = DEG_get_input_scene(depsgraph_); + Main *bmain = DEG_get_bmain(depsgraph_); + image_path = export_image_fn_(bmain, scene, image, &tex_image->iuser); + } NodeItem vector = get_input_link("Vector", NodeItem::Type::Vector2); if (!vector) { -- 2.30.2