Files
test/source/blender/nodes/shader/materialx/group_nodes.cc

165 lines
4.2 KiB
C++

/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#include "group_nodes.h"
#include "node_parser.h"
#include "BKE_node_runtime.hh"
#ifdef USE_MATERIALX_NODEGRAPH
# include "BLI_vector.hh"
#endif
namespace blender::nodes::materialx {
GroupNodeParser::GroupNodeParser(NodeGraph &graph,
const bNode *node,
const bNodeSocket *socket_out,
NodeItem::Type to_type,
GroupNodeParser *group_parser,
bool use_group_default)
: NodeParser(graph, node, socket_out, to_type, group_parser),
use_group_default_(use_group_default)
{
}
NodeItem GroupNodeParser::compute()
{
const bNodeTree *ngroup = reinterpret_cast<const bNodeTree *>(node_->id);
ngroup->ensure_topology_cache();
const bNode *node_out = ngroup->group_output_node();
if (!node_out) {
return empty();
}
NodeGraph group_graph(graph_, ngroup->id.name + 2);
NodeItem out = GroupOutputNodeParser(
group_graph, node_out, socket_out_, to_type_, this, use_group_default_)
.compute_full();
#ifdef USE_MATERIALX_NODEGRAPH
/* We have to be in NodeParser's graph_, therefore copying output */
NodeItem res = empty();
res.output = out.output;
return res;
#else
return out;
#endif
}
NodeItem GroupNodeParser::compute_full()
{
NodeItem res = compute();
if (NodeItem::is_arithmetic(to_type_)) {
res = res.convert(to_type_);
}
return res;
}
NodeItem GroupOutputNodeParser::compute()
{
#ifdef USE_MATERIALX_NODEGRAPH
Vector<NodeItem> values;
for (const auto *socket_in : node_->input_sockets()) {
NodeItem value = get_input_value(
socket_in->index(), NodeItem::is_arithmetic(to_type_) ? NodeItem::Type::Any : to_type_);
if (value.value) {
value = create_node("constant", value.type(), {{"value", value}});
}
values.append(value);
}
Vector<NodeItem> outputs;
for (int i = 0; i < values.size(); ++i) {
if (values[i]) {
outputs.append(create_output(out_name(node_->input_sockets()[i]), values[i]));
}
}
return outputs[socket_out_->index()];
#else
if (use_group_default_) {
return get_input_value(socket_out_->index(), to_type_);
}
return get_input_link(socket_out_->index(), to_type_);
#endif
}
NodeItem GroupOutputNodeParser::compute_full()
{
CLOG_INFO(LOG_MATERIALX_SHADER,
1,
"%s [%d] => %s",
node_->name,
node_->typeinfo->type_legacy,
NodeItem::type(to_type_).c_str());
#ifdef USE_MATERIALX_NODEGRAPH
/* Checking if output was already computed */
NodeItem res = graph_.get_output(out_name(socket_out_));
if (res.output) {
return res;
}
res = compute();
return res;
#else
return compute();
#endif
}
std::string GroupOutputNodeParser::out_name(const bNodeSocket *out_socket)
{
return MaterialX::createValidName(std::string("out_") + out_socket->name);
}
NodeItem GroupInputNodeParser::compute()
{
#ifdef USE_MATERIALX_NODEGRAPH
NodeItem value = group_parser_->get_input_link(socket_out_->index(), to_type_);
if (!value) {
return empty();
}
if (value.value) {
value = group_parser_->create_node("constant", value.type(), {{"value", value}});
}
return create_input(in_name(), value);
#else
if (use_group_default_) {
return group_parser_->get_input_value(socket_out_->index(), to_type_);
}
return group_parser_->get_input_link(socket_out_->index(), to_type_);
#endif
}
NodeItem GroupInputNodeParser::compute_full()
{
CLOG_INFO(LOG_MATERIALX_SHADER,
1,
"%s [%d] => %s",
node_->name,
node_->typeinfo->type_legacy,
NodeItem::type(to_type_).c_str());
#ifdef USE_MATERIALX_NODEGRAPH
/* Checking if input was already computed */
NodeItem res = graph_.get_input(in_name());
if (res.input) {
return res;
}
res = compute();
return res;
#else
return compute();
#endif
}
std::string GroupInputNodeParser::in_name() const
{
return MaterialX::createValidName(std::string("in_") + socket_out_->name);
}
} // namespace blender::nodes::materialx