forked from blender/blender
Implement export of Shader BSDF nodes #13
@ -25,12 +25,10 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater
|
|||||||
if (material->use_nodes) {
|
if (material->use_nodes) {
|
||||||
material->nodetree->ensure_topology_cache();
|
material->nodetree->ensure_topology_cache();
|
||||||
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
|
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
|
||||||
OutputMaterialNodeParser(doc.get(), depsgraph, material, output_node, NodeItem::Type::Material)
|
OutputMaterialNodeParser(doc.get(), depsgraph, material, output_node).compute_full();
|
||||||
.compute();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
OutputMaterialNodeParser(doc.get(), depsgraph, material, nullptr, NodeItem::Type::Material)
|
OutputMaterialNodeParser(doc.get(), depsgraph, material, nullptr).compute_default();
|
||||||
.compute_default();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLOG_INFO(LOG_MATERIALX_SHADER,
|
CLOG_INFO(LOG_MATERIALX_SHADER,
|
||||||
|
@ -6,7 +6,17 @@
|
|||||||
|
|
||||||
namespace blender::nodes::materialx {
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
NodeItem BSDFPrincipledNodeParser::compute()
|
NodeItem BSDFPrincipledNodeParser::compute_bsdf()
|
||||||
|
{
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem BSDFPrincipledNodeParser::compute_edf()
|
||||||
|
{
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem BSDFPrincipledNodeParser::compute_surface()
|
||||||
{
|
{
|
||||||
/* Getting required inputs
|
/* Getting required inputs
|
||||||
* Note: if some inputs are not needed they won't be taken */
|
* Note: if some inputs are not needed they won't be taken */
|
||||||
|
@ -12,6 +12,86 @@ namespace blender::nodes::materialx {
|
|||||||
|
|
||||||
NodeItem::NodeItem(MaterialX::GraphElement *graph) : graph_(graph) {}
|
NodeItem::NodeItem(MaterialX::GraphElement *graph) : graph_(graph) {}
|
||||||
|
|
||||||
|
NodeItem::Type NodeItem::type(const std::string &type_str)
|
||||||
|
{
|
||||||
|
if (type_str == "string") {
|
||||||
|
return Type::String;
|
||||||
|
}
|
||||||
|
if (type_str == "filename") {
|
||||||
|
return Type::Filename;
|
||||||
|
}
|
||||||
|
if (type_str == "integer") {
|
||||||
|
return Type::Integer;
|
||||||
|
}
|
||||||
|
if (type_str == "float") {
|
||||||
|
return Type::Float;
|
||||||
|
}
|
||||||
|
if (type_str == "vector2") {
|
||||||
|
return Type::Vector2;
|
||||||
|
}
|
||||||
|
if (type_str == "vector3") {
|
||||||
|
return Type::Vector3;
|
||||||
|
}
|
||||||
|
if (type_str == "vector4") {
|
||||||
|
return Type::Vector4;
|
||||||
|
}
|
||||||
|
if (type_str == "color3") {
|
||||||
|
return Type::Color3;
|
||||||
|
}
|
||||||
|
if (type_str == "color4") {
|
||||||
|
return Type::Color4;
|
||||||
|
}
|
||||||
|
if (type_str == "BSDF") {
|
||||||
|
return Type::BSDF;
|
||||||
|
}
|
||||||
|
if (type_str == "EDF") {
|
||||||
|
return Type::EDF;
|
||||||
|
}
|
||||||
|
if (type_str == "surfaceshader") {
|
||||||
|
return Type::SurfaceShader;
|
||||||
|
}
|
||||||
|
if (type_str == "material") {
|
||||||
|
return Type::Material;
|
||||||
|
}
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
return Type::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string NodeItem::type(Type type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case Type::String:
|
||||||
|
return "string";
|
||||||
|
case Type::Filename:
|
||||||
|
return "filename";
|
||||||
|
case Type::Integer:
|
||||||
|
return "integer";
|
||||||
|
case Type::Float:
|
||||||
|
return "float";
|
||||||
|
case Type::Vector2:
|
||||||
|
return "vector2";
|
||||||
|
case Type::Vector3:
|
||||||
|
return "vector3";
|
||||||
|
case Type::Vector4:
|
||||||
|
return "vector4";
|
||||||
|
case Type::Color3:
|
||||||
|
return "color3";
|
||||||
|
case Type::Color4:
|
||||||
|
return "color4";
|
||||||
|
case Type::BSDF:
|
||||||
|
return "BSDF";
|
||||||
|
case Type::EDF:
|
||||||
|
return "EDF";
|
||||||
|
case Type::SurfaceShader:
|
||||||
|
return "surfaceshader";
|
||||||
|
case Type::Material:
|
||||||
|
return "material";
|
||||||
|
default:
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
NodeItem::operator bool() const
|
NodeItem::operator bool() const
|
||||||
{
|
{
|
||||||
return value || node;
|
return value || node;
|
||||||
@ -562,86 +642,6 @@ void NodeItem::add_output(const std::string &name, Type out_type)
|
|||||||
node->addOutput(name, type(out_type));
|
node->addOutput(name, type(out_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem::Type NodeItem::type(const std::string &type_str)
|
|
||||||
{
|
|
||||||
if (type_str == "string") {
|
|
||||||
return Type::String;
|
|
||||||
}
|
|
||||||
if (type_str == "filename") {
|
|
||||||
return Type::Filename;
|
|
||||||
}
|
|
||||||
if (type_str == "integer") {
|
|
||||||
return Type::Integer;
|
|
||||||
}
|
|
||||||
if (type_str == "float") {
|
|
||||||
return Type::Float;
|
|
||||||
}
|
|
||||||
if (type_str == "vector2") {
|
|
||||||
return Type::Vector2;
|
|
||||||
}
|
|
||||||
if (type_str == "vector3") {
|
|
||||||
return Type::Vector3;
|
|
||||||
}
|
|
||||||
if (type_str == "vector4") {
|
|
||||||
return Type::Vector4;
|
|
||||||
}
|
|
||||||
if (type_str == "color3") {
|
|
||||||
return Type::Color3;
|
|
||||||
}
|
|
||||||
if (type_str == "color4") {
|
|
||||||
return Type::Color4;
|
|
||||||
}
|
|
||||||
if (type_str == "BSDF") {
|
|
||||||
return Type::BSDF;
|
|
||||||
}
|
|
||||||
if (type_str == "EDF") {
|
|
||||||
return Type::EDF;
|
|
||||||
}
|
|
||||||
if (type_str == "surfaceshader") {
|
|
||||||
return Type::SurfaceShader;
|
|
||||||
}
|
|
||||||
if (type_str == "material") {
|
|
||||||
return Type::Material;
|
|
||||||
}
|
|
||||||
BLI_assert_unreachable();
|
|
||||||
return Type::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string NodeItem::type(Type type)
|
|
||||||
{
|
|
||||||
switch (type) {
|
|
||||||
case Type::String:
|
|
||||||
return "string";
|
|
||||||
case Type::Filename:
|
|
||||||
return "filename";
|
|
||||||
case Type::Integer:
|
|
||||||
return "integer";
|
|
||||||
case Type::Float:
|
|
||||||
return "float";
|
|
||||||
case Type::Vector2:
|
|
||||||
return "vector2";
|
|
||||||
case Type::Vector3:
|
|
||||||
return "vector3";
|
|
||||||
case Type::Vector4:
|
|
||||||
return "vector4";
|
|
||||||
case Type::Color3:
|
|
||||||
return "color3";
|
|
||||||
case Type::Color4:
|
|
||||||
return "color4";
|
|
||||||
case Type::BSDF:
|
|
||||||
return "BSDF";
|
|
||||||
case Type::EDF:
|
|
||||||
return "EDF";
|
|
||||||
case Type::SurfaceShader:
|
|
||||||
return "surfaceshader";
|
|
||||||
case Type::Material:
|
|
||||||
return "material";
|
|
||||||
default:
|
|
||||||
BLI_assert_unreachable();
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NodeItem::is_arithmetic(Type type)
|
bool NodeItem::is_arithmetic(Type type)
|
||||||
{
|
{
|
||||||
return type >= Type::Float && type <= Type::Color4;
|
return type >= Type::Float && type <= Type::Color4;
|
||||||
|
@ -45,6 +45,9 @@ class NodeItem {
|
|||||||
NodeItem(MaterialX::GraphElement *graph);
|
NodeItem(MaterialX::GraphElement *graph);
|
||||||
~NodeItem() = default;
|
~NodeItem() = default;
|
||||||
|
|
||||||
|
static Type type(const std::string &type_str);
|
||||||
|
static std::string type(Type type);
|
||||||
|
|
||||||
/* Operators */
|
/* Operators */
|
||||||
operator bool() const;
|
operator bool() const;
|
||||||
NodeItem operator+(const NodeItem &other) const;
|
NodeItem operator+(const NodeItem &other) const;
|
||||||
@ -106,8 +109,6 @@ class NodeItem {
|
|||||||
void add_output(const std::string &in_name, Type out_type);
|
void add_output(const std::string &in_name, Type out_type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static Type type(const std::string &type_str);
|
|
||||||
static std::string type(Type type);
|
|
||||||
static bool is_arithmetic(Type type);
|
static bool is_arithmetic(Type type);
|
||||||
static Type adjust_types(NodeItem &item1, NodeItem &item2);
|
static Type adjust_types(NodeItem &item1, NodeItem &item2);
|
||||||
|
|
||||||
|
@ -13,22 +13,30 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph,
|
|||||||
const Depsgraph *depsgraph,
|
const Depsgraph *depsgraph,
|
||||||
const Material *material,
|
const Material *material,
|
||||||
const bNode *node,
|
const bNode *node,
|
||||||
const bNodeSocket *socket_out,
|
const bNodeSocket *socket_out)
|
||||||
NodeItem::Type shader_type)
|
|
||||||
: graph_(graph),
|
: graph_(graph),
|
||||||
depsgraph_(depsgraph),
|
depsgraph_(depsgraph),
|
||||||
material_(material),
|
material_(material),
|
||||||
node_(node),
|
node_(node),
|
||||||
socket_out_(socket_out),
|
socket_out_(socket_out)
|
||||||
shader_type_(shader_type)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NodeParser::node_name(const bNode *node, const bNodeSocket *socket_out)
|
NodeItem NodeParser::compute_full()
|
||||||
{
|
{
|
||||||
return MaterialX::createValidName(node->output_sockets().size() <= 1 ?
|
CLOG_INFO(LOG_MATERIALX_SHADER, 1, "%s [%d]", node_->name, node_->typeinfo->type);
|
||||||
std::string(node->name) :
|
NodeItem res = compute();
|
||||||
std::string(node->name) + "_" + socket_out->name);
|
if (res.node) {
|
||||||
|
res.node->setName(node_name());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string NodeParser::node_name()
|
||||||
|
{
|
||||||
|
return MaterialX::createValidName(node_->output_sockets().size() <= 1 ?
|
||||||
|
std::string(node_->name) :
|
||||||
|
std::string(node_->name) + "_" + socket_out_->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type)
|
NodeItem NodeParser::create_node(const std::string &mx_category, const std::string &mx_type)
|
||||||
@ -48,14 +56,14 @@ NodeItem NodeParser::get_input_default(int index)
|
|||||||
return get_input_default(node_->input_socket(index));
|
return get_input_default(node_->input_socket(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeParser::get_input_link(const std::string &name, NodeItem::Type shader_type)
|
NodeItem NodeParser::get_input_link(const std::string &name)
|
||||||
{
|
{
|
||||||
return get_input_link(node_->input_by_identifier(name), shader_type);
|
return get_input_link(node_->input_by_identifier(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeParser::get_input_link(int index, NodeItem::Type shader_type)
|
NodeItem NodeParser::get_input_link(int index)
|
||||||
{
|
{
|
||||||
return get_input_link(node_->input_socket(index), shader_type);
|
return get_input_link(node_->input_socket(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeParser::get_input_value(const std::string &name)
|
NodeItem NodeParser::get_input_value(const std::string &name)
|
||||||
@ -101,7 +109,7 @@ NodeItem NodeParser::get_input_default(const bNodeSocket &socket)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type shader_type)
|
NodeItem NodeParser::get_input_link(const bNodeSocket &socket)
|
||||||
{
|
{
|
||||||
NodeItem res = empty();
|
NodeItem res = empty();
|
||||||
|
|
||||||
@ -122,7 +130,7 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type sh
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Checking if node was already computed */
|
/* Checking if node was already computed */
|
||||||
res.node = graph_->getNode(node_name(from_node, link->fromsock));
|
res.node = graph_->getNode(node_name());
|
||||||
if (res.node) {
|
if (res.node) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -131,12 +139,12 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type sh
|
|||||||
#define CASE_NODE_TYPE(type, T) \
|
#define CASE_NODE_TYPE(type, T) \
|
||||||
case type: \
|
case type: \
|
||||||
res = \
|
res = \
|
||||||
T(graph_, depsgraph_, material_, from_node, link->fromsock, shader_type).compute_full(); \
|
T(graph_, depsgraph_, material_, from_node, link->fromsock).compute_full(); \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (from_node->typeinfo->type) {
|
switch (from_node->typeinfo->type) {
|
||||||
CASE_NODE_TYPE(SH_NODE_BRIGHTCONTRAST, BrightContrastNodeParser)
|
CASE_NODE_TYPE(SH_NODE_BRIGHTCONTRAST, BrightContrastNodeParser)
|
||||||
CASE_NODE_TYPE(SH_NODE_BSDF_PRINCIPLED, BSDFPrincipledNodeParser)
|
//CASE_NODE_TYPE(SH_NODE_BSDF_PRINCIPLED, BSDFPrincipledNodeParser)
|
||||||
CASE_NODE_TYPE(SH_NODE_COMBINE_COLOR, CombineColorNodeParser)
|
CASE_NODE_TYPE(SH_NODE_COMBINE_COLOR, CombineColorNodeParser)
|
||||||
CASE_NODE_TYPE(SH_NODE_COMBXYZ, CombineXYZNodeParser)
|
CASE_NODE_TYPE(SH_NODE_COMBXYZ, CombineXYZNodeParser)
|
||||||
CASE_NODE_TYPE(SH_NODE_HUE_SAT, HueSatValNodeParser)
|
CASE_NODE_TYPE(SH_NODE_HUE_SAT, HueSatValNodeParser)
|
||||||
@ -164,20 +172,99 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type sh
|
|||||||
|
|
||||||
NodeItem NodeParser::get_input_value(const bNodeSocket &socket)
|
NodeItem NodeParser::get_input_value(const bNodeSocket &socket)
|
||||||
{
|
{
|
||||||
NodeItem res = get_input_link(socket, NodeItem::Type::None);
|
NodeItem res = get_input_link(socket);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
res = get_input_default(socket);
|
res = get_input_default(socket);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeParser::compute_full()
|
ShaderNodeParser::ShaderNodeParser(MaterialX::GraphElement *graph,
|
||||||
|
const Depsgraph *depsgraph,
|
||||||
|
const Material *material,
|
||||||
|
const bNode *node,
|
||||||
|
const bNodeSocket *socket_out,
|
||||||
|
NodeItem::Type shader_type)
|
||||||
|
: NodeParser(graph, depsgraph, material, node, socket_out), shader_type_(shader_type)
|
||||||
{
|
{
|
||||||
CLOG_INFO(LOG_MATERIALX_SHADER, 1, "%s [%d]", node_->name, node_->typeinfo->type);
|
|
||||||
NodeItem res = compute();
|
|
||||||
if (res.node) {
|
|
||||||
res.node->setName(node_name(node_, socket_out_));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeItem ShaderNodeParser::compute()
|
||||||
|
{
|
||||||
|
switch (shader_type_) {
|
||||||
|
case NodeItem::Type::BSDF:
|
||||||
|
return compute_bsdf();
|
||||||
|
case NodeItem::Type::EDF:
|
||||||
|
return compute_edf();
|
||||||
|
case NodeItem::Type::SurfaceShader:
|
||||||
|
return compute_surface();
|
||||||
|
default:
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
}
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ShaderNodeParser::node_name()
|
||||||
|
{
|
||||||
|
std::string name = NodeParser::node_name();
|
||||||
|
if (shader_type_ != NodeItem::Type::SurfaceShader) {
|
||||||
|
name += "_" + NodeItem::type(shader_type_);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem ShaderNodeParser::get_input_shader(const std::string &name, NodeItem::Type shader_type)
|
||||||
|
{
|
||||||
|
return get_input_shader(node_->input_by_identifier(name), shader_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem ShaderNodeParser::get_input_shader(int index, NodeItem::Type shader_type)
|
||||||
|
{
|
||||||
|
return get_input_shader(node_->input_socket(index), shader_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem ShaderNodeParser::get_input_shader(const bNodeSocket &socket, NodeItem::Type shader_type)
|
||||||
|
{
|
||||||
|
NodeItem res = empty();
|
||||||
|
|
||||||
|
const bNodeLink *link = socket.link;
|
||||||
|
if (!(link && link->is_used())) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bNode *from_node = link->fromnode;
|
||||||
|
|
||||||
|
/* Passing NODE_REROUTE nodes */
|
||||||
|
while (from_node->type == NODE_REROUTE) {
|
||||||
|
link = from_node->input_socket(0).link;
|
||||||
|
if (!(link && link->is_used())) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
from_node = link->fromnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Checking if node was already computed */
|
||||||
|
res.node = graph_->getNode(node_name());
|
||||||
|
if (res.node) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Computing from_node with required NodeParser object */
|
||||||
|
#define CASE_SHADER_NODE_TYPE(type, T) \
|
||||||
|
case type: \
|
||||||
|
res = T(graph_, depsgraph_, material_, from_node, link->fromsock, shader_type).compute_full(); \
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (from_node->typeinfo->type) {
|
||||||
|
CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_PRINCIPLED, BSDFPrincipledNodeParser)
|
||||||
|
|
||||||
|
default:
|
||||||
|
CLOG_WARN(LOG_MATERIALX_SHADER,
|
||||||
|
"Unsupported node: %s [%d]",
|
||||||
|
from_node->name,
|
||||||
|
from_node->typeinfo->type);
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,27 +19,25 @@ class NodeParser {
|
|||||||
const Material *material_;
|
const Material *material_;
|
||||||
const bNode *node_;
|
const bNode *node_;
|
||||||
const bNodeSocket *socket_out_;
|
const bNodeSocket *socket_out_;
|
||||||
NodeItem::Type shader_type_;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NodeParser(MaterialX::GraphElement *graph,
|
NodeParser(MaterialX::GraphElement *graph,
|
||||||
const Depsgraph *depsgraph,
|
const Depsgraph *depsgraph,
|
||||||
const Material *material,
|
const Material *material,
|
||||||
const bNode *node,
|
const bNode *node,
|
||||||
const bNodeSocket *socket_out,
|
const bNodeSocket *socket_out);
|
||||||
NodeItem::Type shader_type);
|
|
||||||
virtual ~NodeParser() = default;
|
virtual ~NodeParser() = default;
|
||||||
|
|
||||||
virtual NodeItem compute() = 0;
|
virtual NodeItem compute() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static std::string node_name(const bNode *node, const bNodeSocket *socket_out);
|
NodeItem compute_full();
|
||||||
|
virtual std::string node_name();
|
||||||
NodeItem create_node(const std::string &mx_category, const std::string &mx_type);
|
NodeItem create_node(const std::string &mx_category, const std::string &mx_type);
|
||||||
NodeItem get_input_default(const std::string &name);
|
NodeItem get_input_default(const std::string &name);
|
||||||
NodeItem get_input_default(int index);
|
NodeItem get_input_default(int index);
|
||||||
NodeItem get_input_link(const std::string &name,
|
NodeItem get_input_link(const std::string &name);
|
||||||
NodeItem::Type shader_type = NodeItem::Type::None);
|
NodeItem get_input_link(int index);
|
||||||
NodeItem get_input_link(int index, NodeItem::Type shader_type = NodeItem::Type::None);
|
|
||||||
NodeItem get_input_value(const std::string &name);
|
NodeItem get_input_value(const std::string &name);
|
||||||
NodeItem get_input_value(int index);
|
NodeItem get_input_value(int index);
|
||||||
NodeItem empty() const;
|
NodeItem empty() const;
|
||||||
@ -47,9 +45,34 @@ class NodeParser {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
NodeItem get_input_default(const bNodeSocket &socket);
|
NodeItem get_input_default(const bNodeSocket &socket);
|
||||||
NodeItem get_input_link(const bNodeSocket &socket, NodeItem::Type shader_type);
|
NodeItem get_input_link(const bNodeSocket &socket);
|
||||||
NodeItem get_input_value(const bNodeSocket &socket);
|
NodeItem get_input_value(const bNodeSocket &socket);
|
||||||
NodeItem compute_full();
|
};
|
||||||
|
|
||||||
|
class ShaderNodeParser : public NodeParser {
|
||||||
|
protected:
|
||||||
|
NodeItem::Type shader_type_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ShaderNodeParser(MaterialX::GraphElement *graph,
|
||||||
|
const Depsgraph *depsgraph,
|
||||||
|
const Material *material,
|
||||||
|
const bNode *node,
|
||||||
|
const bNodeSocket *socket_out,
|
||||||
|
NodeItem::Type shader_type);
|
||||||
|
|
||||||
|
NodeItem compute() override;
|
||||||
|
virtual NodeItem compute_bsdf() = 0;
|
||||||
|
virtual NodeItem compute_edf() = 0;
|
||||||
|
virtual NodeItem compute_surface() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string node_name() override;
|
||||||
|
NodeItem get_input_shader(const std::string &name, NodeItem::Type shader_type);
|
||||||
|
NodeItem get_input_shader(int index, NodeItem::Type shader_type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
NodeItem get_input_shader(const bNodeSocket &socket, NodeItem::Type shader_type);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T> NodeItem NodeParser::value(const T &data) const
|
template<class T> NodeItem NodeParser::value(const T &data) const
|
||||||
@ -57,28 +80,38 @@ template<class T> NodeItem NodeParser::value(const T &data) const
|
|||||||
return empty().val(data);
|
return empty().val(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DECLARE_PARSER(T) \
|
#define DECLARE_NODE_PARSER(T) \
|
||||||
class T : public NodeParser { \
|
class T : public NodeParser { \
|
||||||
public: \
|
public: \
|
||||||
using NodeParser::NodeParser; \
|
using NodeParser::NodeParser; \
|
||||||
NodeItem compute() override; \
|
NodeItem compute() override; \
|
||||||
};
|
};
|
||||||
|
|
||||||
DECLARE_PARSER(BrightContrastNodeParser)
|
#define DECLARE_SHADER_NODE_PARSER(T) \
|
||||||
DECLARE_PARSER(BSDFPrincipledNodeParser)
|
class T : public ShaderNodeParser { \
|
||||||
DECLARE_PARSER(CombineColorNodeParser)
|
public: \
|
||||||
DECLARE_PARSER(CombineXYZNodeParser)
|
using ShaderNodeParser::ShaderNodeParser; \
|
||||||
DECLARE_PARSER(HueSatValNodeParser)
|
NodeItem compute_bsdf() override; \
|
||||||
DECLARE_PARSER(InvertNodeParser)
|
NodeItem compute_edf() override; \
|
||||||
DECLARE_PARSER(MathNodeParser)
|
NodeItem compute_surface() override; \
|
||||||
DECLARE_PARSER(MixRGBNodeParser)
|
};
|
||||||
DECLARE_PARSER(NormalMapNodeParser)
|
|
||||||
DECLARE_PARSER(SeparateColorNodeParser)
|
DECLARE_NODE_PARSER(BrightContrastNodeParser)
|
||||||
DECLARE_PARSER(SeparateXYZNodeParser)
|
DECLARE_NODE_PARSER(CombineColorNodeParser)
|
||||||
DECLARE_PARSER(TexCheckerNodeParser)
|
DECLARE_NODE_PARSER(CombineXYZNodeParser)
|
||||||
DECLARE_PARSER(TexEnvironmentNodeParser)
|
DECLARE_NODE_PARSER(HueSatValNodeParser)
|
||||||
DECLARE_PARSER(TexImageNodeParser)
|
DECLARE_NODE_PARSER(InvertNodeParser)
|
||||||
DECLARE_PARSER(TexNoiseNodeParser)
|
DECLARE_NODE_PARSER(MathNodeParser)
|
||||||
DECLARE_PARSER(VectorMathNodeParser)
|
DECLARE_NODE_PARSER(MixRGBNodeParser)
|
||||||
|
DECLARE_NODE_PARSER(NormalMapNodeParser)
|
||||||
|
DECLARE_NODE_PARSER(SeparateColorNodeParser)
|
||||||
|
DECLARE_NODE_PARSER(SeparateXYZNodeParser)
|
||||||
|
DECLARE_NODE_PARSER(TexCheckerNodeParser)
|
||||||
|
DECLARE_NODE_PARSER(TexEnvironmentNodeParser)
|
||||||
|
DECLARE_NODE_PARSER(TexImageNodeParser)
|
||||||
|
DECLARE_NODE_PARSER(TexNoiseNodeParser)
|
||||||
|
DECLARE_NODE_PARSER(VectorMathNodeParser)
|
||||||
|
|
||||||
|
DECLARE_SHADER_NODE_PARSER(BSDFPrincipledNodeParser)
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
} // namespace blender::nodes::materialx
|
||||||
|
@ -8,9 +8,8 @@ namespace blender::nodes::materialx {
|
|||||||
OutputMaterialNodeParser::OutputMaterialNodeParser(MaterialX::GraphElement *graph,
|
OutputMaterialNodeParser::OutputMaterialNodeParser(MaterialX::GraphElement *graph,
|
||||||
const Depsgraph *depsgraph,
|
const Depsgraph *depsgraph,
|
||||||
const Material *material,
|
const Material *material,
|
||||||
const bNode *node,
|
const bNode *node)
|
||||||
NodeItem::Type shader_type)
|
: ShaderNodeParser(graph, depsgraph, material, node, nullptr, NodeItem::Type::Material)
|
||||||
: NodeParser(graph, depsgraph, material, node, nullptr, shader_type)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -18,18 +17,45 @@ NodeItem OutputMaterialNodeParser::compute()
|
|||||||
{
|
{
|
||||||
NodeItem surface = empty();
|
NodeItem surface = empty();
|
||||||
if (node_) {
|
if (node_) {
|
||||||
surface = get_input_link("Surface", NodeItem::Type::SurfaceShader);
|
NodeItem bsdf = compute_bsdf();
|
||||||
|
NodeItem edf = compute_edf();
|
||||||
|
if (bsdf || edf) {
|
||||||
|
surface = create_node("surface", "surfaceshader");
|
||||||
|
if (bsdf) {
|
||||||
|
surface.set_input("bsdf", bsdf);
|
||||||
|
}
|
||||||
|
if (edf) {
|
||||||
|
surface.set_input("edf", edf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
surface = compute_surface();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
surface = create_node("standard_surface", "surfaceshader");
|
surface = create_node("standard_surface", "surfaceshader");
|
||||||
surface.set_input("base_color", value(MaterialX::Color3(1.0f, 0.0f, 1.0f)));
|
surface.set_input("base_color", value(MaterialX::Color3(1.0f, 0.0f, 1.0f)));
|
||||||
}
|
}
|
||||||
NodeItem res = create_node("surfacematerial", "material");
|
NodeItem res = create_node("surfacematerial", "material");
|
||||||
res.node->setName(node_name(node_, nullptr));
|
|
||||||
res.set_input("surfaceshader", surface);
|
res.set_input("surfaceshader", surface);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeItem OutputMaterialNodeParser::compute_bsdf()
|
||||||
|
{
|
||||||
|
return get_input_shader("Surface", NodeItem::Type::BSDF);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem OutputMaterialNodeParser::compute_edf()
|
||||||
|
{
|
||||||
|
return get_input_shader("Surface", NodeItem::Type::EDF);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem OutputMaterialNodeParser::compute_surface()
|
||||||
|
{
|
||||||
|
return get_input_shader("Surface", NodeItem::Type::SurfaceShader);
|
||||||
|
}
|
||||||
|
|
||||||
NodeItem OutputMaterialNodeParser::compute_default()
|
NodeItem OutputMaterialNodeParser::compute_default()
|
||||||
{
|
{
|
||||||
NodeItem surface = create_node("standard_surface", "surfaceshader");
|
NodeItem surface = create_node("standard_surface", "surfaceshader");
|
||||||
@ -51,4 +77,9 @@ NodeItem OutputMaterialNodeParser::compute_default()
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string OutputMaterialNodeParser::node_name()
|
||||||
|
{
|
||||||
|
return node_->name;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
} // namespace blender::nodes::materialx
|
||||||
|
@ -8,15 +8,22 @@
|
|||||||
|
|
||||||
namespace blender::nodes::materialx {
|
namespace blender::nodes::materialx {
|
||||||
|
|
||||||
class OutputMaterialNodeParser : public NodeParser {
|
class OutputMaterialNodeParser : public ShaderNodeParser {
|
||||||
public:
|
public:
|
||||||
OutputMaterialNodeParser(MaterialX::GraphElement *graph,
|
OutputMaterialNodeParser(MaterialX::GraphElement *graph,
|
||||||
const Depsgraph *depsgraph,
|
const Depsgraph *depsgraph,
|
||||||
const Material *material,
|
const Material *material,
|
||||||
const bNode *node,
|
const bNode *node);
|
||||||
NodeItem::Type shader_type);
|
|
||||||
NodeItem compute() override;
|
NodeItem compute() override;
|
||||||
|
NodeItem compute_bsdf() override;
|
||||||
|
NodeItem compute_edf() override;
|
||||||
|
NodeItem compute_surface() override;
|
||||||
|
|
||||||
|
using ShaderNodeParser::compute_full;
|
||||||
NodeItem compute_default();
|
NodeItem compute_default();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string node_name() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
} // namespace blender::nodes::materialx
|
||||||
|
Loading…
Reference in New Issue
Block a user