Move the MaterialX export code into the existing shader node files #18

Merged
Bogdan Nagirniak merged 14 commits from BogdanNagirniak/blender:matx-move-code into matx-export-material 2023-09-12 13:55:27 +02:00
11 changed files with 58 additions and 118 deletions
Showing only changes of commit b431e57174 - Show all commits

View File

@ -9,11 +9,11 @@ namespace blender::nodes::materialx {
NodeItem AddShaderNodeParser::compute()
{
NodeItem res = empty();
switch (shader_type_) {
switch (to_type_) {
case NodeItem::Type::BSDF:
case NodeItem::Type::EDF: {
NodeItem shader1 = get_input_shader(0, shader_type_);
NodeItem shader2 = get_input_shader(1, shader_type_);
NodeItem shader1 = get_input_shader(0, to_type_);
NodeItem shader2 = get_input_shader(1, to_type_);
if (shader1 && !shader2) {
res = shader1;
@ -27,9 +27,9 @@ NodeItem AddShaderNodeParser::compute()
break;
}
case NodeItem::Type::SurfaceShader: {
res = get_input_shader(0, shader_type_);
res = get_input_shader(0, to_type_);
if (!res) {
res = get_input_shader(1, shader_type_);
res = get_input_shader(1, to_type_);
}
break;
}

View File

@ -8,7 +8,7 @@ namespace blender::nodes::materialx {
NodeItem BSDFDiffuseNodeParser::compute()
{
if (shader_type_ != NodeItem::Type::BSDF) {
if (to_type_ != NodeItem::Type::BSDF) {
return empty();
}

View File

@ -8,7 +8,7 @@ namespace blender::nodes::materialx {
NodeItem BSDFPrincipledNodeParser::compute()
{
if (shader_type_ != NodeItem::Type::SurfaceShader) {
if (to_type_ != NodeItem::Type::SurfaceShader) {
/* TODO: implement for BSDF and EDF */
return empty();
}

View File

@ -8,7 +8,7 @@ namespace blender::nodes::materialx {
NodeItem EmissionNodeParser::compute()
{
if (shader_type_ != NodeItem::Type::EDF) {
if (to_type_ != NodeItem::Type::EDF) {
return empty();
}

View File

@ -9,12 +9,12 @@ namespace blender::nodes::materialx {
NodeItem MixShaderNodeParser::compute()
{
NodeItem res = empty();
switch (shader_type_) {
switch (to_type_) {
case NodeItem::Type::BSDF:
case NodeItem::Type::EDF: {
NodeItem fac = get_input_value(0, NodeItem::Type::Float);
NodeItem shader1 = get_input_shader(1, shader_type_);
NodeItem shader2 = get_input_shader(2, shader_type_);
NodeItem shader1 = get_input_shader(1, to_type_);
NodeItem shader2 = get_input_shader(2, to_type_);
if (shader1 && !shader2) {
res = shader1 * (val(1.0f) - fac);
@ -23,7 +23,7 @@ NodeItem MixShaderNodeParser::compute()
res = shader2 * fac;
}
else if (shader1 && shader2) {
res = create_node("mix", shader_type_);
res = create_node("mix", to_type_);
res.set_input("fg", shader1);
res.set_input("bg", shader2);
res.set_input("mix", fac);

View File

@ -50,6 +50,7 @@ class NodeItem {
static Type type(const std::string &type_str);
static std::string type(Type type);
static bool is_arithmetic(Type type);
/* Operators */
operator bool() const;
@ -109,7 +110,6 @@ class NodeItem {
void add_output(const std::string &in_name, Type out_type);
private:
static bool is_arithmetic(Type type);
static Type cast_types(NodeItem &item1, NodeItem &item2);
bool is_arithmetic() const;

View File

@ -16,28 +16,40 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph,
const Material *material,
const bNode *node,
const bNodeSocket *socket_out,
NodeItem::Type shader_type)
NodeItem::Type to_type)
: graph_(graph),
depsgraph_(depsgraph),
material_(material),
node_(node),
socket_out_(socket_out),
shader_type_(shader_type)
to_type_(to_type)
{
}
NodeItem NodeParser::compute_full()
{
NodeItem res = empty();
/* Checking if node was already computed */
res.node = graph_->getNode(node_name());
if (res.node) {
return res;
}
CLOG_INFO(LOG_MATERIALX_SHADER,
1,
"%s [%d] %s",
"%s [%d] - %s",
node_->name,
node_->typeinfo->type,
NodeItem::type(shader_type_).c_str());
NodeItem res = compute();
NodeItem::type(to_type_).c_str());
res = compute();
if (res.node) {
res.node->setName(node_name());
}
if (NodeItem::is_arithmetic(to_type_)) {
res = res.convert(to_type_);
}
return res;
}
@ -47,8 +59,8 @@ std::string NodeParser::node_name()
if (node_->output_sockets().size() > 1) {
name += std::string("_") + socket_out_->name;
}
if (ELEM(shader_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF)) {
name += "_" + NodeItem::type(shader_type_);
if (ELEM(to_type_, NodeItem::Type::BSDF, NodeItem::Type::EDF)) {
name += "_" + NodeItem::type(to_type_);
}
return MaterialX::createValidName(name);
}
@ -158,7 +170,7 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
#define CASE_NODE_TYPE(type, T) \
case type: \
parser = std::make_unique<T>( \
graph_, depsgraph_, material_, from_node, link->fromsock, NodeItem::Type::Any); \
graph_, depsgraph_, material_, from_node, link->fromsock, to_type); \
break;
switch (from_node->typeinfo->type) {
@ -189,6 +201,20 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
CASE_NODE_TYPE(SH_NODE_VECTOR_MATH, VectorMathNodeParser)
CASE_NODE_TYPE(SH_NODE_WAVELENGTH, WavelengthNodeParser)
CASE_NODE_TYPE(SH_NODE_ADD_SHADER, AddShaderNodeParser)
CASE_NODE_TYPE(SH_NODE_BSDF_DIFFUSE, BSDFDiffuseNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_GLASS, BSDFGlassNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_GLOSSY, BSDFGlossyNodeParser)
CASE_NODE_TYPE(SH_NODE_BSDF_PRINCIPLED, BSDFPrincipledNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_REFRACTION, BSDFRefractionNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_SHEEN, BSDFSheenNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_TOON, BSDFToonNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_TRANSLUCENT, BSDFTranslucentNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_TRANSPARENT, BSDFTransparentNodeParser)
CASE_NODE_TYPE(SH_NODE_EMISSION, EmissionNodeParser)
CASE_NODE_TYPE(SH_NODE_MIX_SHADER, MixShaderNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_SUBSURFACE_SCATTERING, SubsurfaceScatteringNodeParser)
default:
CLOG_WARN(LOG_MATERIALX_SHADER,
"Unsupported node: %s [%d]",
@ -199,15 +225,9 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type to
return res;
}
/* Checking if node was already computed */
res.node = graph_->getNode(parser->node_name());
if (res.node) {
return res;
}
/* Computing */
res = parser->compute_full();
return res.convert(to_type);
return res;
}
NodeItem NodeParser::get_input_value(const bNodeSocket &socket, NodeItem::Type to_type)
@ -221,77 +241,12 @@ NodeItem NodeParser::get_input_value(const bNodeSocket &socket, NodeItem::Type t
NodeItem NodeParser::get_input_shader(const std::string &name, NodeItem::Type shader_type)
{
return get_input_shader(node_->input_by_identifier(name), shader_type);
return get_input_link(node_->input_by_identifier(name), shader_type);
}
NodeItem NodeParser::get_input_shader(int index, NodeItem::Type shader_type)
{
return get_input_shader(node_->input_socket(index), shader_type);
}
NodeItem NodeParser::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;
}
/* Creating required ShaderNodeParser object */
std::unique_ptr<NodeParser> parser;
#define CASE_SHADER_NODE_TYPE(type, T) \
case type: \
parser = std::make_unique<T>( \
graph_, depsgraph_, material_, from_node, link->fromsock, shader_type); \
break;
switch (from_node->typeinfo->type) {
CASE_SHADER_NODE_TYPE(SH_NODE_ADD_SHADER, AddShaderNodeParser)
CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_DIFFUSE, BSDFDiffuseNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_GLASS, BSDFGlassNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_GLOSSY, BSDFGlossyNodeParser)
CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_PRINCIPLED, BSDFPrincipledNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_REFRACTION, BSDFRefractionNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_SHEEN, BSDFSheenNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_TOON, BSDFToonNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_TRANSLUCENT, BSDFTranslucentNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_BSDF_TRANSPARENT, BSDFTransparentNodeParser)
CASE_SHADER_NODE_TYPE(SH_NODE_EMISSION, EmissionNodeParser)
CASE_SHADER_NODE_TYPE(SH_NODE_MIX_SHADER, MixShaderNodeParser)
// CASE_SHADER_NODE_TYPE(SH_NODE_SUBSURFACE_SCATTERING, SubsurfaceScatteringNodeParser)
default:
CLOG_WARN(LOG_MATERIALX_SHADER,
"Unsupported node: %s [%d]",
from_node->name,
from_node->typeinfo->type);
}
if (!parser) {
return res;
}
/* Checking if node was already computed */
res.node = graph_->getNode(parser->node_name());
if (res.node) {
return res;
}
/* Computing */
res = parser->compute_full();
return res;
return get_input_link(node_->input_socket(index), shader_type);
}
} // namespace blender::nodes::materialx

View File

@ -19,7 +19,7 @@ class NodeParser {
const Material *material_;
const bNode *node_;
const bNodeSocket *socket_out_;
NodeItem::Type shader_type_;
NodeItem::Type to_type_;
public:
NodeParser(MaterialX::GraphElement *graph,
@ -31,10 +31,10 @@ class NodeParser {
virtual ~NodeParser() = default;
virtual NodeItem compute() = 0;
virtual NodeItem compute_full();
protected:
virtual NodeItem compute_full();
virtual std::string node_name();
std::string node_name();
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);
@ -52,7 +52,6 @@ class NodeParser {
NodeItem get_input_default(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_input_link(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_input_value(const bNodeSocket &socket, NodeItem::Type to_type);
NodeItem get_input_shader(const bNodeSocket &socket, NodeItem::Type shader_type);
};
template<class T> NodeItem NodeParser::val(const T &data) const
@ -67,13 +66,6 @@ template<class T> NodeItem NodeParser::val(const T &data) const
NodeItem compute() override; \
};
#define DECLARE_SHADER_NODE_PARSER(T) \
class T : public ShaderNodeParser { \
public: \
using ShaderNodeParser::ShaderNodeParser; \
NodeItem compute() override; \
};
DECLARE_NODE_PARSER(BlackbodyNodeParser)
DECLARE_NODE_PARSER(BrightContrastNodeParser)
DECLARE_NODE_PARSER(ClampNodeParser)
@ -129,7 +121,8 @@ void node_shader_materialx(void *data, struct bNode *node, struct bNodeSocket *o
{
materialx::NodeParserData *d = reinterpret_cast<materialx::NodeParserData *>(data);
T parser(d->graph, d->depsgraph, d->material, node, out, d->shader_type);
d->result = parser.compute();
d->result = parser.compute_full();
}
#define NODE_SHADER_MATERIALX_BEGIN \

View File

@ -62,9 +62,4 @@ NodeItem OutputMaterialNodeParser::compute_default()
return res;
}
std::string OutputMaterialNodeParser::node_name()
{
return NodeParser::node_name();
}
} // namespace blender::nodes::materialx

View File

@ -18,9 +18,6 @@ class OutputMaterialNodeParser : public NodeParser {
using NodeParser::compute_full;
NodeItem compute_default();
protected:
std::string node_name() override;
};
} // namespace blender::nodes::materialx

View File

@ -14,7 +14,7 @@ NodeItem VectorMathNodeParser::compute()
NodeItem res = empty();
/* Single operand operations */
NodeItem x = get_input_value(0, NodeItem::Type::Any);
NodeItem x = get_input_value(0, NodeItem::Type::Vector3);
switch (op) {
case NODE_VECTOR_MATH_SINE:
res = x.sin();
@ -46,7 +46,7 @@ NodeItem VectorMathNodeParser::compute()
default: {
/* 2-operand operations */
NodeItem y = get_input_value(1, NodeItem::Type::Any);
NodeItem y = get_input_value(1, NodeItem::Type::Vector3);
switch (op) {
case NODE_VECTOR_MATH_ADD:
res = x + y;
@ -93,7 +93,7 @@ NodeItem VectorMathNodeParser::compute()
default: {
/* 3-operand operations */
NodeItem z = get_input_value(2, NodeItem::Type::Any);
NodeItem z = get_input_value(2, NodeItem::Type::Vector3);
switch (op) {
case NODE_VECTOR_MATH_MULTIPLY_ADD:
res = x * y + z;