Blender V4.3
group_nodes.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "group_nodes.h"
6#include "node_parser.h"
7
8#include "BLI_vector.hh"
9
10#include "BKE_node.hh"
11#include "BKE_node_runtime.hh"
12
14
15GroupNodeParser::GroupNodeParser(MaterialX::GraphElement *graph,
16 const Depsgraph *depsgraph,
17 const Material *material,
18 const bNode *node,
19 const bNodeSocket *socket_out,
21 GroupNodeParser *group_parser,
22 ExportParams export_params,
23 bool use_group_default)
25 graph, depsgraph, material, node, socket_out, to_type, group_parser, export_params),
26 use_group_default_(use_group_default)
27{
28}
29
31{
32 NodeItem res = empty();
33
34 const bNodeTree *ngroup = reinterpret_cast<const bNodeTree *>(node_->id);
35 ngroup->ensure_topology_cache();
36 const bNode *node_out = ngroup->group_output_node();
37 if (!node_out) {
38 return res;
39 }
40
41 MaterialX::GraphElement *graph = graph_;
42#ifdef USE_MATERIALX_NODEGRAPH
43 std::string name = MaterialX::createValidName(ngroup->id.name);
44 MaterialX::NodeGraphPtr group_graph = graph_->getChildOfType<MaterialX::NodeGraph>(name);
45 if (!group_graph) {
46 CLOG_INFO(LOG_MATERIALX_SHADER, 1, "<nodegraph name=%s>", name.c_str());
47 group_graph = graph_->addChild<MaterialX::NodeGraph>(name);
48 }
49 graph = group_graph.get();
50#endif
51
55 node_out,
58 this,
61 .compute_full();
62
63#ifdef USE_MATERIALX_NODEGRAPH
64 /* We have to be in NodeParser's graph_, therefore copying output */
65 res.output = out.output;
66#else
67 res = out;
68#endif
69 return res;
70}
71
73{
74 NodeItem res = compute();
75 if (NodeItem::is_arithmetic(to_type_)) {
76 res = res.convert(to_type_);
77 }
78 return res;
79}
80
82{
83#ifdef USE_MATERIALX_NODEGRAPH
84 Vector<NodeItem> values;
85 for (auto socket_in : node_->input_sockets()) {
87 socket_in->index(), NodeItem::is_arithmetic(to_type_) ? NodeItem::Type::Any : to_type_);
88 if (value.value) {
89 value = create_node("constant", value.type(), {{"value", value}});
90 }
91 values.append(value);
92 }
94 for (int i = 0; i < values.size(); ++i) {
95 if (values[i]) {
96 outputs.append(create_output(out_name(node_->input_sockets()[i]), values[i]));
97 }
98 }
99 return outputs[socket_out_->index()];
100#else
101 if (use_group_default_) {
102 return get_input_value(socket_out_->index(), to_type_);
103 }
104 return get_input_link(socket_out_->index(), to_type_);
105#endif
106}
107
108NodeItem GroupOutputNodeParser::compute_full()
109{
111 1,
112 "%s [%d] => %s",
113 node_->name,
114 node_->typeinfo->type,
115 NodeItem::type(to_type_).c_str());
116
117#ifdef USE_MATERIALX_NODEGRAPH
118 NodeItem res = empty();
119
120 /* Checking if output was already computed */
121 res.output = graph_->getOutput(out_name(socket_out_));
122 if (res.output) {
123 return res;
124 }
125
126 res = compute();
127 return res;
128#else
129 return compute();
130#endif
131}
132
133std::string GroupOutputNodeParser::out_name(const bNodeSocket *out_socket)
134{
135 return MaterialX::createValidName(std::string("out_") + out_socket->name);
136}
137
138NodeItem GroupInputNodeParser::compute()
139{
140#ifdef USE_MATERIALX_NODEGRAPH
141 NodeItem value = group_parser_->get_input_link(socket_out_->index(), to_type_);
142 if (!value) {
143 return empty();
144 }
145
146 if (value.value) {
147 value = group_parser_->create_node("constant", value.type(), {{"value", value}});
148 }
149 return create_input(in_name(), value);
150#else
151 if (use_group_default_) {
152 return group_parser_->get_input_value(socket_out_->index(), to_type_);
153 }
154 return group_parser_->get_input_link(socket_out_->index(), to_type_);
155#endif
156}
157
158NodeItem GroupInputNodeParser::compute_full()
159{
161 1,
162 "%s [%d] => %s",
163 node_->name,
164 node_->typeinfo->type,
165 NodeItem::type(to_type_).c_str());
166
167#ifdef USE_MATERIALX_NODEGRAPH
168 NodeItem res = empty();
169
170 /* Checking if input was already computed */
171 res.input = graph_->getInput(in_name());
172 if (res.input) {
173 return res;
174 }
175
176 res = compute();
177 return res;
178#else
179 return compute();
180#endif
181}
182
183std::string GroupInputNodeParser::in_name() const
184{
185 return MaterialX::createValidName(std::string("in_") + socket_out_->name);
186}
187
188} // namespace blender::nodes::materialx
#define CLOG_INFO(clg_ref, level,...)
Definition CLG_log.h:179
GroupNodeParser(MaterialX::GraphElement *graph, const Depsgraph *depsgraph, const Material *material, const bNode *node, const bNodeSocket *socket_out, NodeItem::Type to_type, GroupNodeParser *group_parser, ExportParams export_params, bool use_group_default)
MaterialX::OutputPtr output
Definition node_item.h:57
NodeItem convert(Type to_type) const
Definition node_item.cc:481
NodeItem get_input_value(const std::string &name, NodeItem::Type to_type)
MaterialX::GraphElement * graph_
Definition node_parser.h:28
NodeItem create_node(const std::string &category, NodeItem::Type type)
const Depsgraph * depsgraph
static Type to_type(const eGPUType type)
struct CLG_LogRef * LOG_MATERIALX_SHADER
static blender::bke::bNodeSocketTemplate outputs[]
CLG_LogType * type
Definition CLG_log.h:108
char name[66]
Definition DNA_ID.h:425
struct ID * id