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
6 changed files with 69 additions and 58 deletions
Showing only changes of commit 414217ae73 - Show all commits

View File

@ -41,14 +41,18 @@ NodeItem GroupOutputNodeParser::compute()
{ {
Vector<NodeItem> values; Vector<NodeItem> values;
for (auto socket_in : node_->input_sockets()) { for (auto socket_in : node_->input_sockets()) {
values.append(get_input_value(socket_in->index(), NodeItem::Type::Any)); NodeItem value = get_input_value(socket_in->index(), NodeItem::Type::Any);
if (value.value) {
NodeItem constant = create_node("constant", value.type());
constant.set_input("value", value);
value = constant;
}
values.append(value);
} }
Vector<NodeItem> outputs; Vector<NodeItem> outputs;
for (int i = 0; i < values.size(); ++i) { for (int i = 0; i < values.size(); ++i) {
if (values[i]) { if (values[i]) {
outputs.append(create_output()); outputs.append(create_output("output" + std::to_string(i + 1), values[i]));
outputs[i].set_output(values[i]);
outputs[i].output->setName("output" + std::to_string(i + 1));
} }
} }
return outputs[socket_out_->index()]; return outputs[socket_out_->index()];
@ -80,4 +84,25 @@ NodeItem GroupInputNodeParser::compute()
return group_parser_->get_input_default(socket_out_->index(), to_type_); return group_parser_->get_input_default(socket_out_->index(), to_type_);
} }
NodeItem GroupInputNodeParser::compute_full()
{
NodeItem res = empty();
/* Checking if output was already computed */
res.output = graph_->getOutput("output" + std::to_string(socket_out_->index() + 1));
if (res.output) {
return res;
}
CLOG_INFO(LOG_MATERIALX_SHADER,
1,
"%s [%d] => %s",
node_->name,
node_->typeinfo->type,
NodeItem::type(to_type_).c_str());
res = compute();
return res;
}
} // namespace blender::nodes::materialx } // namespace blender::nodes::materialx

View File

@ -29,6 +29,7 @@ class GroupInputNodeParser : public NodeParser {
public: public:
using NodeParser::NodeParser; using NodeParser::NodeParser;
NodeItem compute() override; NodeItem compute() override;
NodeItem compute_full() override;
}; };
} // namespace blender::nodes::materialx } // namespace blender::nodes::materialx

View File

@ -678,6 +678,9 @@ void NodeItem::set_input(const std::string &in_name, const NodeItem &item)
else if (item.node) { else if (item.node) {
node->setConnectedNode(in_name, item.node); node->setConnectedNode(in_name, item.node);
} }
else if (item.input) {
node->setAttribute("interfacename", item.input->getName());
}
else if (item.output) { else if (item.output) {
node->setConnectedOutput(in_name, item.output); node->setConnectedOutput(in_name, item.output);
} }
@ -693,60 +696,41 @@ NodeItem NodeItem::add_output(const std::string &out_name, Type out_type)
return res; return res;
} }
NodeItem NodeItem::create_output() const NodeItem NodeItem::create_input(const std::string &name, const NodeItem &item) const
{ {
NodeItem res = empty(); NodeItem res = empty();
res.output = graph_->addOutput(); res.input = graph_->addInput(name);
Type item_type = item.type();
if (item.node) {
res.input->setConnectedNode(item.node);
}
else {
BLI_assert_unreachable();
}
res.input->setType(type(item_type));
return res; return res;
} }
void NodeItem::set_output(const NodeItem &item) const NodeItem NodeItem::create_output(const std::string &name, const NodeItem &item) const
{ {
NodeItem res = empty();
res.output = graph_->addOutput(name);
Type item_type = item.type(); Type item_type = item.type();
if (item.value) { if (item.node) {
switch (item_type) { res.output->setConnectedNode(item.node);
case Type::String:
set_output(item.value->asA<std::string>(), item_type);
break;
case Type::Boolean:
set_output(item.value->asA<bool>(), item_type);
break;
case Type::Integer:
set_output(item.value->asA<int>(), item_type);
break;
case Type::Float:
set_output(item.value->asA<float>(), item_type);
break;
case Type::Vector2:
set_output(item.value->asA<MaterialX::Vector2>(), item_type);
break;
case Type::Vector3:
set_output(item.value->asA<MaterialX::Vector3>(), item_type);
break;
case Type::Vector4:
set_output(item.value->asA<MaterialX::Vector4>(), item_type);
break;
case Type::Color3:
set_output(item.value->asA<MaterialX::Color3>(), item_type);
break;
case Type::Color4:
set_output(item.value->asA<MaterialX::Color4>(), item_type);
break;
default:
BLI_assert_unreachable();
}
} }
else if (item.node) { else if (item.input) {
output->setConnectedNode(item.node); res.output->setInterfaceName(item.input->getName());
output->setType(type(item_type));
}
else if (item.output) {
output->setConnectedOutput(item.output);
output->setType(type(item_type));
} }
else { else {
CLOG_WARN(LOG_MATERIALX_SHADER, "Empty item to output: %s", output->getName().c_str()); BLI_assert_unreachable();
} }
res.output->setType(type(item_type));
return res;
} }
NodeItem::Type NodeItem::cast_types(NodeItem &item1, NodeItem &item2) NodeItem::Type NodeItem::cast_types(NodeItem &item1, NodeItem &item2)

View File

@ -43,6 +43,7 @@ class NodeItem {
public: public:
MaterialX::ValuePtr value; MaterialX::ValuePtr value;
MaterialX::NodePtr node; MaterialX::NodePtr node;
MaterialX::InputPtr input;
MaterialX::OutputPtr output; MaterialX::OutputPtr output;
private: private:
@ -111,9 +112,8 @@ class NodeItem {
NodeItem add_output(const std::string &out_name, Type out_type); NodeItem add_output(const std::string &out_name, Type out_type);
/* Output functions */ /* Output functions */
NodeItem create_output() const; NodeItem create_input(const std::string &name, const NodeItem &item) const;
template<class T> void set_output(const T &value, Type out_type) const; NodeItem create_output(const std::string &name, const NodeItem &item) const;
void set_output(const NodeItem &item) const;
private: private:
static Type cast_types(NodeItem &item1, NodeItem &item2); static Type cast_types(NodeItem &item1, NodeItem &item2);
@ -138,9 +138,4 @@ void NodeItem::set_input(const std::string &in_name, const T &value, Type in_typ
node->setInputValue(in_name, value, type(in_type)); node->setInputValue(in_name, value, type(in_type));
} }
template<class T> void NodeItem::set_output(const T &value, Type out_type) const
{
output->setValue(value, type(out_type));
}
} // namespace blender::nodes::materialx } // namespace blender::nodes::materialx

View File

@ -75,9 +75,14 @@ NodeItem NodeParser::create_node(const std::string &category, NodeItem::Type typ
return empty().create_node(category, type); return empty().create_node(category, type);
} }
NodeItem NodeParser::create_output() NodeItem NodeParser::create_input(const std::string &name, const NodeItem &item)
{ {
return empty().create_output(); return empty().create_input(name, item);
}
NodeItem NodeParser::create_output(const std::string &name, const NodeItem &item)
{
return empty().create_output(name, item);
} }
NodeItem NodeParser::get_input_default(const std::string &name, NodeItem::Type to_type) NodeItem NodeParser::get_input_default(const std::string &name, NodeItem::Type to_type)

View File

@ -44,7 +44,8 @@ class NodeParser {
protected: protected:
std::string node_name() const; std::string node_name() const;
NodeItem create_node(const std::string &category, NodeItem::Type type); NodeItem create_node(const std::string &category, NodeItem::Type type);
NodeItem create_output(); NodeItem create_input(const std::string &name, const NodeItem &item);
NodeItem create_output(const std::string &name, const NodeItem &item);
NodeItem get_input_default(const std::string &name, NodeItem::Type to_type); NodeItem get_input_default(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_default(int index, NodeItem::Type to_type); NodeItem get_input_default(int index, NodeItem::Type to_type);
NodeItem get_input_link(const std::string &name, NodeItem::Type to_type); NodeItem get_input_link(const std::string &name, NodeItem::Type to_type);