Support group nodes #22

Merged
Bogdan Nagirniak merged 18 commits from BogdanNagirniak/blender:matx-group-nodes into matx-export-material 2023-09-18 12:49:19 +02:00
4 changed files with 46 additions and 11 deletions
Showing only changes of commit 61e0e05430 - Show all commits

View File

@ -81,8 +81,9 @@ void MaterialData::init()
MaterialX::DocumentPtr doc = blender::nodes::materialx::export_to_materialx(
scene_delegate_->depsgraph, (Material *)id);
pxr::UsdMtlxRead(doc, stage);
pxr::UsdMtlxReadNodeGraphs(doc, stage);
/* Logging stage: creating lambda stage_str() for not to call stage->ExportToString()
* if log doesn't execute. */
auto stage_str = [&stage]() {
std::string str;
stage->ExportToString(&str);

View File

@ -20,29 +20,34 @@ NodeItem GroupNodeParser::compute()
return res;
}
MaterialX::GraphElement *graph = graph_;
#ifdef USE_MATERIALX_NODEGRAPH
std::string name = MaterialX::createValidName(ngroup->id.name);
MaterialX::NodeGraphPtr group_graph = graph_->getChildOfType<MaterialX::NodeGraph>(name);
if (!group_graph) {
CLOG_INFO(LOG_MATERIALX_SHADER, 1, "<nodegraph name=%s>", name.c_str());
group_graph = graph_->addChild<MaterialX::NodeGraph>(name);
}
graph = group_graph.get();
#endif
NodeItem out = GroupOutputNodeParser(group_graph.get(),
depsgraph_,
material_,
node_out,
socket_out_,
NodeItem::Type::Any,
this)
.compute_full();
NodeItem out =
GroupOutputNodeParser(
graph, depsgraph_, material_, node_out, socket_out_, NodeItem::Type::Any, this)
.compute_full();
#ifdef USE_MATERIALX_NODEGRAPH
/* We have to be in NodeParser's graph_, therefore copying output */
res.output = out.output;
#else
res = out;
#endif
return res;
}
NodeItem GroupOutputNodeParser::compute()
{
#ifdef USE_MATERIALX_NODEGRAPH
Vector<NodeItem> values;
for (auto socket_in : node_->input_sockets()) {
NodeItem value = get_input_value(socket_in->index(), NodeItem::Type::Any);
@ -59,12 +64,15 @@ NodeItem GroupOutputNodeParser::compute()
outputs.append(create_output("output" + std::to_string(i + 1), values[i]));
}
}
return outputs[socket_out_->index()];
#else
return get_input_value(socket_out_->index(), NodeItem::Type::Any);
#endif
}
NodeItem GroupOutputNodeParser::compute_full()
{
#ifdef USE_MATERIALX_NODEGRAPH
NodeItem res = empty();
/* Checking if output was already computed */
@ -82,22 +90,29 @@ NodeItem GroupOutputNodeParser::compute_full()
res = compute();
return res;
#else
return NodeParser::compute_full();
#endif
}
NodeItem GroupInputNodeParser::compute()
{
#ifdef USE_MATERIALX_NODEGRAPH
NodeItem value = group_parser_->get_input_value(socket_out_->index(), to_type_);
if (value.value) {
NodeItem constant = create_node("constant", value.type());
constant.set_input("value", value);
value = constant;
}
return create_input("input" + std::to_string(socket_out_->index() + 1), value);
#else
return group_parser_->get_input_value(socket_out_->index(), to_type_);
#endif
}
NodeItem GroupInputNodeParser::compute_full()
{
#ifdef USE_MATERIALX_NODEGRAPH
NodeItem res = empty();
/* Checking if output was already computed */
@ -115,6 +130,9 @@ NodeItem GroupInputNodeParser::compute_full()
res = compute();
return res;
#else
return NodeParser::compute_full();
#endif
}
} // namespace blender::nodes::materialx

View File

@ -6,11 +6,16 @@
#include "node_parser.h"
/* TODO: pxr::UsdMtlxRead() doesn't perform nodegraphs.
* Uncomment USE_MATERIALX_NODEGRAPH after fixing it. */
/* #define USE_MATERIALX_NODEGRAPH */
namespace blender::nodes::materialx {
class GroupInputNodeParser;
class GroupNodeParser : public NodeParser {
friend NodeParser;
friend GroupInputNodeParser;
public:

View File

@ -67,7 +67,18 @@ std::string NodeParser::node_name() const
if (ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF)) {
name += "_" + NodeItem::type(to_type_);
}
#ifdef USE_MATERIALX_NODEGRAPH
return MaterialX::createValidName(name);
#else
std::string prefix;
GroupNodeParser *gr = group_parser_;
while (gr) {
const bNodeTree *ngroup = reinterpret_cast<const bNodeTree *>(gr->node_->id);
prefix = MaterialX::createValidName(ngroup->id.name) + "_" + prefix;
gr = gr->group_parser_;
}
return prefix + MaterialX::createValidName(name);
#endif
}
NodeItem NodeParser::create_node(const std::string &category, NodeItem::Type type)