forked from blender/blender
Support group nodes #22
@ -149,10 +149,12 @@ if(WITH_MATERIALX)
|
||||
materialx/material.cc
|
||||
materialx/node_item.cc
|
||||
materialx/node_parser.cc
|
||||
materialx/group_nodes.cc
|
||||
|
||||
materialx/material.h
|
||||
materialx/node_item.h
|
||||
materialx/node_parser.h
|
||||
materialx/group_nodes.h
|
||||
)
|
||||
list(APPEND LIB
|
||||
MaterialXCore
|
||||
|
65
source/blender/nodes/shader/materialx/group_nodes.cc
Normal file
65
source/blender/nodes/shader/materialx/group_nodes.cc
Normal file
@ -0,0 +1,65 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "node_parser.h"
|
||||
#include "group_nodes.h"
|
||||
|
||||
namespace blender::nodes::materialx {
|
||||
|
||||
NodeItem GroupNodeParser::compute()
|
||||
{
|
||||
NodeItem res = empty();
|
||||
|
||||
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 res;
|
||||
}
|
||||
|
||||
std::string name = MaterialX::createValidName(node_->name); /* or ngroup->name */
|
||||
MaterialX::NodeGraphPtr group_graph = graph_->getChildOfType<MaterialX::NodeGraph>(name);
|
||||
if (!group_graph) {
|
||||
group_graph = graph_->addChild<MaterialX::NodeGraph>(name);
|
||||
}
|
||||
|
||||
GroupOutputNodeParser parser(
|
||||
group_graph.get(), depsgraph_, material_, node_out, socket_out_, NodeItem::Type::Any);
|
||||
NodeItem out = parser.compute_full();
|
||||
res.node = group_graph;
|
||||
if (parser.output) {
|
||||
res = create_node("constant", out.type());
|
||||
res.set_input("value", parser.output);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NodeItem GroupOutputNodeParser::compute()
|
||||
{
|
||||
NodeItem res = get_input_link(socket_out_->index(), to_type_);
|
||||
if (res) {
|
||||
output = graph_->addOutput(MaterialX::EMPTY_STRING, NodeItem::type(res.type()));
|
||||
output->setValue(1.0f);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NodeItem GroupInputNodeParser::compute()
|
||||
{
|
||||
return empty();
|
||||
}
|
||||
|
||||
NodeItem GroupInputNodeParser::compute_full()
|
||||
{
|
||||
CLOG_INFO(LOG_MATERIALX_SHADER,
|
||||
1,
|
||||
"%s [%d] => %s",
|
||||
node_->name,
|
||||
node_->typeinfo->type,
|
||||
NodeItem::type(to_type_).c_str());
|
||||
|
||||
return compute();
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::materialx
|
33
source/blender/nodes/shader/materialx/group_nodes.h
Normal file
33
source/blender/nodes/shader/materialx/group_nodes.h
Normal file
@ -0,0 +1,33 @@
|
||||
/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "node_parser.h"
|
||||
|
||||
namespace blender::nodes::materialx {
|
||||
|
||||
class GroupNodeParser : public NodeParser {
|
||||
public:
|
||||
using NodeParser::NodeParser;
|
||||
NodeItem compute() override;
|
||||
};
|
||||
|
||||
class GroupOutputNodeParser : public NodeParser {
|
||||
public:
|
||||
MaterialX::OutputPtr output;
|
||||
|
||||
public:
|
||||
using NodeParser::NodeParser;
|
||||
NodeItem compute() override;
|
||||
};
|
||||
|
||||
class GroupInputNodeParser : public NodeParser {
|
||||
public:
|
||||
using NodeParser::NodeParser;
|
||||
NodeItem compute() override;
|
||||
NodeItem compute_full() override;
|
||||
};
|
||||
|
||||
} // namespace blender::nodes::materialx
|
@ -675,13 +675,15 @@ void NodeItem::set_input(const std::string &in_name, const NodeItem &item)
|
||||
}
|
||||
}
|
||||
|
||||
void NodeItem::set_input(const std::string &in_name, MaterialX::OutputPtr output)
|
||||
{
|
||||
node->setConnectedOutput(in_name, output);
|
||||
}
|
||||
|
||||
void NodeItem::set_input_output(const std::string &in_name,
|
||||
const NodeItem &item,
|
||||
const std::string &out_name)
|
||||
{
|
||||
if (!item.node) {
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
node->setConnectedNode(in_name, item.node);
|
||||
node->setConnectedOutput(in_name, item.node->getOutput(out_name));
|
||||
}
|
||||
|
@ -104,6 +104,7 @@ class NodeItem {
|
||||
/* Functions to set input and output */
|
||||
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, MaterialX::OutputPtr output);
|
||||
void set_input_output(const std::string &in_name,
|
||||
const NodeItem &item,
|
||||
const std::string &out_name);
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include "node_parser.h"
|
||||
|
||||
#include "group_nodes.h"
|
||||
|
||||
#include "BKE_node_runtime.hh"
|
||||
|
||||
namespace blender::nodes::materialx {
|
||||
@ -54,7 +56,7 @@ NodeItem NodeParser::compute_full()
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string NodeParser::node_name()
|
||||
std::string NodeParser::node_name() const
|
||||
{
|
||||
std::string name = node_->name;
|
||||
if (node_->output_sockets().size() > 1) {
|
||||
@ -155,7 +157,7 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
|
||||
const bNode *from_node = link->fromnode;
|
||||
|
||||
/* Passing NODE_REROUTE nodes */
|
||||
while (from_node->type == NODE_REROUTE) {
|
||||
while (from_node->is_reroute()) {
|
||||
link = from_node->input_socket(0).link;
|
||||
if (!(link && link->is_used())) {
|
||||
return empty();
|
||||
@ -163,6 +165,11 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
|
||||
from_node = link->fromnode;
|
||||
}
|
||||
|
||||
if (from_node->is_group()) {
|
||||
return GroupNodeParser(graph_, depsgraph_, material_, from_node, link->fromsock, to_type)
|
||||
.compute_full();
|
||||
}
|
||||
|
||||
if (!from_node->typeinfo->materialx_fn) {
|
||||
CLOG_WARN(LOG_MATERIALX_SHADER,
|
||||
"Unsupported node: %s [%d]",
|
||||
|
@ -38,7 +38,7 @@ class NodeParser {
|
||||
virtual NodeItem compute_full();
|
||||
|
||||
protected:
|
||||
std::string node_name();
|
||||
std::string node_name() const;
|
||||
NodeItem create_node(const std::string &category, NodeItem::Type type);
|
||||
NodeItem get_input_default(const std::string &name, NodeItem::Type to_type);
|
||||
NodeItem get_input_default(int index, NodeItem::Type to_type);
|
||||
|
@ -260,7 +260,7 @@ static void sh_node_noise_build_multi_function(NodeMultiFunctionBuilder &builder
|
||||
NODE_SHADER_MATERIALX_BEGIN
|
||||
{
|
||||
NodeItem scale = get_input_value("Scale", NodeItem::Type::Float);
|
||||
NodeItem detail = get_input_value("Detail", NodeItem::Type::Float);
|
||||
NodeItem detail = get_input_default("Detail", NodeItem::Type::Float);
|
||||
NodeItem lacunarity = get_input_value("Lacunarity", NodeItem::Type::Float);
|
||||
|
||||
NodeItem position = create_node("position", NodeItem::Type::Vector3);
|
||||
@ -268,9 +268,7 @@ NODE_SHADER_MATERIALX_BEGIN
|
||||
|
||||
NodeItem res = create_node("fractal3d", NodeItem::Type::Color3);
|
||||
res.set_input("position", position);
|
||||
if (detail.value) {
|
||||
res.set_input("octaves", val(int(detail.value->asA<float>())));
|
||||
}
|
||||
res.set_input("octaves", val(int(detail.value->asA<float>())));
|
||||
res.set_input("lacunarity", lacunarity);
|
||||
return res;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user