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 94 additions and 38 deletions
Showing only changes of commit 1bd4ae1663 - Show all commits

View File

@ -24,24 +24,19 @@ NodeItem GroupNodeParser::compute()
group_graph = graph_->addChild<MaterialX::NodeGraph>(name); group_graph = graph_->addChild<MaterialX::NodeGraph>(name);
} }
GroupOutputNodeParser parser( NodeItem out =
group_graph.get(), depsgraph_, material_, node_out, socket_out_, NodeItem::Type::Any); GroupOutputNodeParser(
NodeItem out = parser.compute_full(); group_graph.get(), depsgraph_, material_, node_out, socket_out_, NodeItem::Type::Any)
res.node = group_graph; .compute_full();
if (parser.output) { res.output = out.output;
res = create_node("constant", out.type());
res.set_input("value", parser.output);
}
return res; return res;
} }
NodeItem GroupOutputNodeParser::compute() NodeItem GroupOutputNodeParser::compute()
{ {
NodeItem res = get_input_link(socket_out_->index(), to_type_); NodeItem value = get_input_link(socket_out_->index(), to_type_);
if (res) { NodeItem res = create_output();
output = graph_->addOutput(MaterialX::EMPTY_STRING, NodeItem::type(res.type())); res.set_output(value);
output->setValue(1.0f);
}
return res; return res;
} }

View File

@ -15,9 +15,6 @@ class GroupNodeParser : public NodeParser {
}; };
class GroupOutputNodeParser : public NodeParser { class GroupOutputNodeParser : public NodeParser {
public:
MaterialX::OutputPtr output;
public: public:
using NodeParser::NodeParser; using NodeParser::NodeParser;
NodeItem compute() override; NodeItem compute() override;

View File

@ -98,9 +98,14 @@ std::string NodeItem::type(Type type)
return ""; return "";
} }
bool NodeItem::is_arithmetic(Type type)
{
return type >= Type::Float && type <= Type::Color4;
}
NodeItem::operator bool() const NodeItem::operator bool() const
{ {
return value || node; return value || node || output;
} }
NodeItem NodeItem::operator+(const NodeItem &other) const NodeItem NodeItem::operator+(const NodeItem &other) const
@ -619,6 +624,9 @@ NodeItem::Type NodeItem::type() const
if (node) { if (node) {
return type(node->getType()); return type(node->getType());
} }
if (output) {
return type(output->getType());
}
return Type::Empty; return Type::Empty;
} }
@ -670,32 +678,75 @@ 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.output) {
node->setConnectedOutput(in_name, item.output);
}
else { else {
CLOG_WARN(LOG_MATERIALX_SHADER, "Empty item to input: %s", in_name.c_str()); CLOG_WARN(LOG_MATERIALX_SHADER, "Empty item to input: %s", in_name.c_str());
} }
} }
void NodeItem::set_input(const std::string &in_name, MaterialX::OutputPtr output) NodeItem NodeItem::add_output(const std::string &out_name, Type out_type)
{ {
node->setConnectedOutput(in_name, output); NodeItem res = empty();
res.output = node->addOutput(out_name, type(out_type));
return res;
} }
void NodeItem::set_input_output(const std::string &in_name, NodeItem NodeItem::create_output(const std::string &out_name) const
const NodeItem &item,
const std::string &out_name)
{ {
node->setConnectedNode(in_name, item.node); NodeItem res = empty();
node->setConnectedOutput(in_name, item.node->getOutput(out_name)); res.output = graph_->addOutput(out_name);
return res;
} }
void NodeItem::add_output(const std::string &name, Type out_type) void NodeItem::set_output(const NodeItem &item) const
{ {
node->addOutput(name, type(out_type)); Type item_type = item.type();
} if (item.value) {
switch (item_type) {
bool NodeItem::is_arithmetic(Type type) case Type::String:
{ set_output(item.value->asA<std::string>(), item_type);
return type >= Type::Float && type <= Type::Color4; 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) {
output->setConnectedNode(item.node);
output->setType(type(item_type));
}
else if (item.output) {
output->setConnectedOutput(item.output);
output->setType(type(item_type));
}
else {
CLOG_WARN(LOG_MATERIALX_SHADER, "Empty item to output: %s", output->getName().c_str());
}
} }
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::OutputPtr output;
private: private:
MaterialX::GraphElement *graph_; MaterialX::GraphElement *graph_;
@ -102,16 +103,17 @@ class NodeItem {
NodeItem empty() const; NodeItem empty() const;
template<class T> NodeItem val(const T &data) const; template<class T> NodeItem val(const T &data) const;
Type type() const; Type type() const;
NodeItem create_node(const std::string &category, NodeItem::Type type) const;
/* Functions to set input and output */ /* Node functions */
NodeItem create_node(const std::string &category, NodeItem::Type type) const;
template<class T> void set_input(const std::string &in_name, const T &value, Type in_type); template<class T> void set_input(const std::string &in_name, const T &value, Type in_type);
void set_input(const std::string &in_name, const NodeItem &item); void set_input(const std::string &in_name, const NodeItem &item);
void set_input(const std::string &in_name, MaterialX::OutputPtr output); NodeItem add_output(const std::string &out_name, Type out_type);
void set_input_output(const std::string &in_name,
const NodeItem &item, /* Output functions */
const std::string &out_name); NodeItem create_output(const std::string &out_name) const;
void add_output(const std::string &in_name, Type out_type); template<class T> void set_output(const T &value, Type out_type) 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);
@ -136,4 +138,9 @@ 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

@ -73,6 +73,11 @@ 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()
{
return empty().create_output("");
}
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)
{ {
return get_input_default(node_->input_by_identifier(name), to_type); return get_input_default(node_->input_by_identifier(name), to_type);

View File

@ -40,6 +40,7 @@ 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 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);