forked from blender/blender
Implement export of Shader BSDF nodes #13
@ -25,13 +25,11 @@ MaterialX::DocumentPtr export_to_materialx(Depsgraph *depsgraph, Material *mater
|
||||
if (material->use_nodes) {
|
||||
material->nodetree->ensure_topology_cache();
|
||||
bNode *output_node = ntreeShaderOutputNode(material->nodetree, SHD_OUTPUT_ALL);
|
||||
OutputMaterialNodeParser(
|
||||
doc.get(), depsgraph, material, output_node, NodeParser::ShaderType::SurfaceMaterial)
|
||||
OutputMaterialNodeParser(doc.get(), depsgraph, material, output_node, NodeItem::Type::Material)
|
||||
.compute();
|
||||
}
|
||||
else {
|
||||
OutputMaterialNodeParser(
|
||||
doc.get(), depsgraph, material, nullptr, NodeParser::ShaderType::SurfaceMaterial)
|
||||
OutputMaterialNodeParser(doc.get(), depsgraph, material, nullptr, NodeItem::Type::Material)
|
||||
.compute_default();
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ bool NodeItem::operator==(const NodeItem &other) const
|
||||
NodeItem item1 = *this;
|
||||
NodeItem item2 = other;
|
||||
Type to_type = adjust_types(item1, item2);
|
||||
if (to_type == Type::Empty) {
|
||||
if (to_type == Type::None) {
|
||||
return false;
|
||||
}
|
||||
return item1.value->getValueString() == item2.value->getValueString();
|
||||
@ -449,7 +449,7 @@ NodeItem NodeItem::if_else(CompareOp op,
|
||||
auto item1 = if_val;
|
||||
auto item2 = else_val;
|
||||
Type to_type = adjust_types(item1, item2);
|
||||
if (to_type == Type::Empty) {
|
||||
if (to_type == Type::None) {
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -499,7 +499,7 @@ NodeItem::Type NodeItem::type() const
|
||||
if (node) {
|
||||
return type(node->getType());
|
||||
}
|
||||
return Type::Empty;
|
||||
return Type::None;
|
||||
}
|
||||
|
||||
void NodeItem::set_input(const std::string &name,
|
||||
@ -567,6 +567,9 @@ 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;
|
||||
}
|
||||
@ -588,7 +591,20 @@ NodeItem::Type NodeItem::type(const std::string &type_str)
|
||||
if (type_str == "color4") {
|
||||
return Type::Color4;
|
||||
}
|
||||
return Type::Other;
|
||||
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)
|
||||
@ -596,6 +612,8 @@ 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:
|
||||
@ -610,15 +628,23 @@ std::string NodeItem::type(Type type)
|
||||
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:
|
||||
break;
|
||||
BLI_assert_unreachable();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
bool NodeItem::is_arithmetic(Type type)
|
||||
{
|
||||
return type >= Type::Float;
|
||||
return type >= Type::Float && type <= Type::Color4;
|
||||
}
|
||||
|
||||
NodeItem::Type NodeItem::adjust_types(NodeItem &item1, NodeItem &item2)
|
||||
@ -629,7 +655,7 @@ NodeItem::Type NodeItem::adjust_types(NodeItem &item1, NodeItem &item2)
|
||||
return t1;
|
||||
}
|
||||
if (!is_arithmetic(t1) || !is_arithmetic(t2)) {
|
||||
return Type::Empty;
|
||||
return Type::None;
|
||||
}
|
||||
if (t1 < t2) {
|
||||
item1 = item1.convert(t2);
|
||||
@ -710,7 +736,7 @@ NodeItem NodeItem::arithmetic(const NodeItem &other,
|
||||
NodeItem item1 = *this;
|
||||
NodeItem item2 = other;
|
||||
Type to_type = adjust_types(item1, item2);
|
||||
if (to_type == Type::Empty) {
|
||||
if (to_type == Type::None) {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -11,16 +11,26 @@ namespace blender::nodes::materialx {
|
||||
class NodeItem {
|
||||
public:
|
||||
enum class Type {
|
||||
Empty = 0,
|
||||
Other, /* For MaterialX types like: surfaceshader, bsdf, edf, ...*/
|
||||
None = 0,
|
||||
|
||||
/* Value types */
|
||||
String,
|
||||
Filename,
|
||||
Integer,
|
||||
Float,
|
||||
Vector2,
|
||||
Vector3,
|
||||
Vector4,
|
||||
Color3,
|
||||
Color4
|
||||
Color4,
|
||||
|
||||
/* Shader types
|
||||
* Note: There are only supported types */
|
||||
BSDF,
|
||||
EDF,
|
||||
SurfaceShader,
|
||||
Material,
|
||||
|
||||
};
|
||||
enum class CompareOp { Less = 0, LessEq, Eq, GreaterEq, Greater, NotEq };
|
||||
|
||||
|
@ -14,13 +14,13 @@ NodeParser::NodeParser(MaterialX::GraphElement *graph,
|
||||
const Material *material,
|
||||
const bNode *node,
|
||||
const bNodeSocket *socket_out,
|
||||
ShaderType shader)
|
||||
NodeItem::Type shader_type)
|
||||
: graph_(graph),
|
||||
depsgraph_(depsgraph),
|
||||
material_(material),
|
||||
node_(node),
|
||||
socket_out_(socket_out),
|
||||
shader_(shader)
|
||||
shader_type_(shader_type)
|
||||
{
|
||||
}
|
||||
|
||||
@ -48,14 +48,14 @@ NodeItem NodeParser::get_input_default(int index)
|
||||
return get_input_default(node_->input_socket(index));
|
||||
}
|
||||
|
||||
NodeItem NodeParser::get_input_link(const std::string &name, ShaderType shader)
|
||||
NodeItem NodeParser::get_input_link(const std::string &name, NodeItem::Type shader_type)
|
||||
{
|
||||
return get_input_link(node_->input_by_identifier(name), shader);
|
||||
return get_input_link(node_->input_by_identifier(name), shader_type);
|
||||
}
|
||||
|
||||
NodeItem NodeParser::get_input_link(int index, ShaderType shader)
|
||||
NodeItem NodeParser::get_input_link(int index, NodeItem::Type shader_type)
|
||||
{
|
||||
return get_input_link(node_->input_socket(index), shader);
|
||||
return get_input_link(node_->input_socket(index), shader_type);
|
||||
}
|
||||
|
||||
NodeItem NodeParser::get_input_value(const std::string &name)
|
||||
@ -101,7 +101,7 @@ NodeItem NodeParser::get_input_default(const bNodeSocket &socket)
|
||||
return res;
|
||||
}
|
||||
|
||||
NodeItem NodeParser::get_input_link(const bNodeSocket &socket, ShaderType channel)
|
||||
NodeItem NodeParser::get_input_link(const bNodeSocket &socket, NodeItem::Type shader_type)
|
||||
{
|
||||
NodeItem res = empty();
|
||||
|
||||
@ -130,7 +130,8 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, ShaderType channe
|
||||
/* Computing from_node with required NodeParser object */
|
||||
#define CASE_NODE_TYPE(type, T) \
|
||||
case type: \
|
||||
res = T(graph_, depsgraph_, material_, from_node, link->fromsock, channel).compute_full(); \
|
||||
res = \
|
||||
T(graph_, depsgraph_, material_, from_node, link->fromsock, shader_type).compute_full(); \
|
||||
break;
|
||||
|
||||
switch (from_node->typeinfo->type) {
|
||||
@ -163,7 +164,7 @@ NodeItem NodeParser::get_input_link(const bNodeSocket &socket, ShaderType channe
|
||||
|
||||
NodeItem NodeParser::get_input_value(const bNodeSocket &socket)
|
||||
{
|
||||
NodeItem res = get_input_link(socket, ShaderType::Value);
|
||||
NodeItem res = get_input_link(socket, NodeItem::Type::None);
|
||||
if (!res) {
|
||||
res = get_input_default(socket);
|
||||
}
|
||||
|
@ -13,16 +13,13 @@
|
||||
namespace blender::nodes::materialx {
|
||||
|
||||
class NodeParser {
|
||||
public:
|
||||
enum class ShaderType { Value = 0, BSDF, EDF, VDF, SurfaceShader, SurfaceMaterial };
|
||||
|
||||
protected:
|
||||
MaterialX::GraphElement *graph_;
|
||||
const Depsgraph *depsgraph_;
|
||||
const Material *material_;
|
||||
const bNode *node_;
|
||||
const bNodeSocket *socket_out_;
|
||||
ShaderType shader_;
|
||||
NodeItem::Type shader_type_;
|
||||
|
||||
public:
|
||||
NodeParser(MaterialX::GraphElement *graph,
|
||||
@ -30,7 +27,7 @@ class NodeParser {
|
||||
const Material *material,
|
||||
const bNode *node,
|
||||
const bNodeSocket *socket_out,
|
||||
ShaderType shader);
|
||||
NodeItem::Type shader_type);
|
||||
virtual ~NodeParser() = default;
|
||||
|
||||
virtual NodeItem compute() = 0;
|
||||
@ -40,8 +37,9 @@ class NodeParser {
|
||||
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(int index);
|
||||
NodeItem get_input_link(const std::string &name, ShaderType shader = ShaderType::Value);
|
||||
NodeItem get_input_link(int index, ShaderType shader = ShaderType::Value);
|
||||
NodeItem get_input_link(const std::string &name,
|
||||
NodeItem::Type shader_type = NodeItem::Type::None);
|
||||
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(int index);
|
||||
NodeItem empty() const;
|
||||
@ -49,7 +47,7 @@ class NodeParser {
|
||||
|
||||
private:
|
||||
NodeItem get_input_default(const bNodeSocket &socket);
|
||||
NodeItem get_input_link(const bNodeSocket &socket, ShaderType shader);
|
||||
NodeItem get_input_link(const bNodeSocket &socket, NodeItem::Type shader_type);
|
||||
NodeItem get_input_value(const bNodeSocket &socket);
|
||||
NodeItem compute_full();
|
||||
};
|
||||
|
@ -9,8 +9,8 @@ OutputMaterialNodeParser::OutputMaterialNodeParser(MaterialX::GraphElement *grap
|
||||
const Depsgraph *depsgraph,
|
||||
const Material *material,
|
||||
const bNode *node,
|
||||
ShaderType shader)
|
||||
: NodeParser(graph, depsgraph, material, node, nullptr, shader)
|
||||
NodeItem::Type shader_type)
|
||||
: NodeParser(graph, depsgraph, material, node, nullptr, shader_type)
|
||||
{
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ NodeItem OutputMaterialNodeParser::compute()
|
||||
{
|
||||
NodeItem surface = empty();
|
||||
if (node_) {
|
||||
surface = get_input_link("Surface", ShaderType::SurfaceShader);
|
||||
surface = get_input_link("Surface", NodeItem::Type::SurfaceShader);
|
||||
}
|
||||
else {
|
||||
surface = create_node("standard_surface", "surfaceshader");
|
||||
|
@ -14,7 +14,7 @@ class OutputMaterialNodeParser : public NodeParser {
|
||||
const Depsgraph *depsgraph,
|
||||
const Material *material,
|
||||
const bNode *node,
|
||||
ShaderType shader);
|
||||
NodeItem::Type shader_type);
|
||||
NodeItem compute() override;
|
||||
NodeItem compute_default();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user