forked from blender/blender
Support group nodes #22
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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.input) {
|
||||||
else if (item.node) {
|
res.output->setInterfaceName(item.input->getName());
|
||||||
output->setConnectedNode(item.node);
|
|
||||||
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)
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user