Files
test2/source/blender/nodes/shader/materialx/node_parser.h
2023-09-27 13:03:29 +10:00

140 lines
4.5 KiB
C++

/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "node_item.h"
#include "DEG_depsgraph.hh"
#include "DNA_material_types.h"
#include "DNA_node_types.h"
#include "CLG_log.h"
namespace blender::nodes::materialx {
extern struct CLG_LogRef *LOG_MATERIALX_SHADER;
class GroupNodeParser;
using ExportImageFunction = std::function<std::string(Main *, Scene *, Image *, ImageUser *)>;
/**
* This is base abstraction class for parsing Blender nodes into MaterialX nodes.
* #NodeParser::compute() should be overridden in child classes.
*/
class NodeParser {
protected:
MaterialX::GraphElement *graph_;
const Depsgraph *depsgraph_;
const Material *material_;
const bNode *node_;
const bNodeSocket *socket_out_;
NodeItem::Type to_type_;
GroupNodeParser *group_parser_;
ExportImageFunction export_image_fn_;
public:
NodeParser(MaterialX::GraphElement *graph,
const Depsgraph *depsgraph,
const Material *material,
const bNode *node,
const bNodeSocket *socket_out,
NodeItem::Type to_type,
GroupNodeParser *group_parser,
ExportImageFunction export_image_fn);
virtual ~NodeParser() = default;
virtual NodeItem compute() = 0;
virtual NodeItem compute_full();
protected:
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,
const NodeItem::Inputs &inputs);
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(int index, NodeItem::Type to_type);
NodeItem get_output_default(const std::string &name, NodeItem::Type to_type);
NodeItem get_output_default(int index, NodeItem::Type to_type);
NodeItem get_input_link(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_link(int index, NodeItem::Type to_type);
NodeItem get_input_value(const std::string &name, NodeItem::Type to_type);
NodeItem get_input_value(int index, NodeItem::Type to_type);
NodeItem empty() const;
template<class T> NodeItem val(const T &data) const;
NodeItem texcoord_node(NodeItem::Type type = NodeItem::Type::Vector2);
private:
NodeItem get_default(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_input_link(const bNodeSocket &socket,
NodeItem::Type to_type,
bool use_group_default);
NodeItem get_input_value(const bNodeSocket &socket, NodeItem::Type to_type);
};
template<class T> NodeItem NodeParser::val(const T &data) const
{
return empty().val(data);
}
/**
* Defines for including MaterialX node parsing code into node_shader_<name>.cc
*
* Example:
* \code{.c}
* NODE_SHADER_MATERIALX_BEGIN
* #ifdef WITH_MATERIALX
* {
* NodeItem color = get_input_value("Color", NodeItem::Type::Color4);
* NodeItem gamma = get_input_value("Gamma", NodeItem::Type::Float);
* return color ^ gamma;
* }
* #endif
* NODE_SHADER_MATERIALX_END
* \endcode
*/
struct NodeParserData {
MaterialX::GraphElement *graph;
const Depsgraph *depsgraph;
const Material *material;
NodeItem::Type to_type;
GroupNodeParser *group_parser;
NodeItem result;
ExportImageFunction export_image_fn;
};
#define NODE_SHADER_MATERIALX_BEGIN \
class MaterialXNodeParser : public materialx::NodeParser { \
public: \
using materialx::NodeParser::NodeParser; \
materialx::NodeItem compute() override; \
}; \
\
materialx::NodeItem MaterialXNodeParser::compute() \
{ \
using NodeItem = materialx::NodeItem;
#define NODE_SHADER_MATERIALX_END \
} \
\
static void node_shader_materialx(void *data, struct bNode *node, struct bNodeSocket *out) \
{ \
materialx::NodeParserData *d = reinterpret_cast<materialx::NodeParserData *>(data); \
d->result = MaterialXNodeParser(d->graph, \
d->depsgraph, \
d->material, \
node, \
out, \
d->to_type, \
d->group_parser, \
d->export_image_fn) \
.compute_full(); \
}
} // namespace blender::nodes::materialx