forked from blender/blender
Move the MaterialX export code into the existing shader node files #18
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -62,9 +62,4 @@ NodeItem OutputMaterialNodeParser::compute_default()
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string OutputMaterialNodeParser::node_name()
|
||||
{
|
||||
return NodeParser::node_name();
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::materialx
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user