forked from blender/blender
Implement type conversion for NodeItem #10
@ -66,7 +66,7 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
/* Creating standard_surface */
|
/* Creating standard_surface */
|
||||||
NodeItem res = create_node("standard_surface", "surfaceshader");
|
NodeItem res = create_node("standard_surface", "surfaceshader");
|
||||||
res.set_input("base", 1.0, "float");
|
res.set_input("base", 1.0, "float");
|
||||||
res.set_input("base_color", base_color.to_color3());
|
res.set_input("base_color", base_color, NodeItem::Type::Color3);
|
||||||
res.set_input("diffuse_roughness", roughness);
|
res.set_input("diffuse_roughness", roughness);
|
||||||
if (normal) {
|
if (normal) {
|
||||||
res.set_input("normal", normal);
|
res.set_input("normal", normal);
|
||||||
@ -81,7 +81,7 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
|
|
||||||
if (specular != zero) {
|
if (specular != zero) {
|
||||||
res.set_input("specular", specular);
|
res.set_input("specular", specular);
|
||||||
res.set_input("specular_color", base_color.to_color3());
|
res.set_input("specular_color", base_color, NodeItem::Type::Color3);
|
||||||
res.set_input("specular_roughness", roughness);
|
res.set_input("specular_roughness", roughness);
|
||||||
res.set_input("specular_IOR", ior);
|
res.set_input("specular_IOR", ior);
|
||||||
if (anisotropic) {
|
if (anisotropic) {
|
||||||
@ -94,7 +94,7 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
|
|
||||||
if (transmission != zero) {
|
if (transmission != zero) {
|
||||||
res.set_input("transmission", transmission);
|
res.set_input("transmission", transmission);
|
||||||
res.set_input("transmission_color", base_color.to_color3());
|
res.set_input("transmission_color", base_color, NodeItem::Type::Color3);
|
||||||
res.set_input("transmission_extra_roughness", transmission_roughness);
|
res.set_input("transmission_extra_roughness", transmission_roughness);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,13 +107,13 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
|
|
||||||
if (sheen != zero) {
|
if (sheen != zero) {
|
||||||
res.set_input("sheen", sheen);
|
res.set_input("sheen", sheen);
|
||||||
res.set_input("sheen_color", base_color.to_color3());
|
res.set_input("sheen_color", base_color, NodeItem::Type::Color3);
|
||||||
res.set_input("sheen_roughness", roughness);
|
res.set_input("sheen_roughness", roughness);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clearcoat != zero) {
|
if (clearcoat != zero) {
|
||||||
res.set_input("coat", clearcoat);
|
res.set_input("coat", clearcoat);
|
||||||
res.set_input("coat_color", base_color.to_color3());
|
res.set_input("coat_color", base_color, NodeItem::Type::Color3);
|
||||||
res.set_input("coat_roughness", clearcoat_roughness);
|
res.set_input("coat_roughness", clearcoat_roughness);
|
||||||
res.set_input("coat_IOR", ior);
|
res.set_input("coat_IOR", ior);
|
||||||
if (anisotropic) {
|
if (anisotropic) {
|
||||||
@ -125,7 +125,7 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
|
|
||||||
if (emission != zero) {
|
if (emission != zero) {
|
||||||
res.set_input("emission", emission_strength);
|
res.set_input("emission", emission_strength);
|
||||||
res.set_input("emission_color", emission.to_color3());
|
res.set_input("emission_color", emission, NodeItem::Type::Color3);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -109,10 +109,10 @@ NodeItem MathNodeParser::compute()
|
|||||||
res = x.max(y);
|
res = x.max(y);
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_LESS_THAN:
|
case NODE_MATH_LESS_THAN:
|
||||||
res = x.if_else("<", y, value(1.0f), value(0.0f));
|
res = x.if_else(NodeItem::IfType::Less, y, value(1.0f), value(0.0f));
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_GREATER_THAN:
|
case NODE_MATH_GREATER_THAN:
|
||||||
res = x.if_else(">", y, value(1.0f), value(0.0f));
|
res = x.if_else(NodeItem::IfType::Greater, y, value(1.0f), value(0.0f));
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_MODULO:
|
case NODE_MATH_MODULO:
|
||||||
res = x % y;
|
res = x % y;
|
||||||
@ -138,7 +138,7 @@ NodeItem MathNodeParser::compute()
|
|||||||
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
|
CLOG_WARN(LOG_MATERIALX_SHADER, "Unimplemented math operation %d", op);
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_COMPARE:
|
case NODE_MATH_COMPARE:
|
||||||
res = z.if_else("<", (x - y).abs(), value(1.0f), value(0.0f));
|
res = z.if_else(NodeItem::IfType::Less, (x - y).abs(), value(1.0f), value(0.0f));
|
||||||
break;
|
break;
|
||||||
case NODE_MATH_MULTIPLY_ADD:
|
case NODE_MATH_MULTIPLY_ADD:
|
||||||
res = x * y + z;
|
res = x * y + z;
|
||||||
|
@ -75,56 +75,54 @@ void NodeItem::set_input(const std::string &name,
|
|||||||
const std::string &output_name)
|
const std::string &output_name)
|
||||||
{
|
{
|
||||||
if (item.value) {
|
if (item.value) {
|
||||||
set_input(name, item.value);
|
Type t = item.type();
|
||||||
|
std::string mx_type = type(t);
|
||||||
|
switch (t) {
|
||||||
|
case Type::String:
|
||||||
|
set_input(name, item.value->asA<std::string>(), mx_type);
|
||||||
|
break;
|
||||||
|
case Type::Integer:
|
||||||
|
set_input(name, item.value->asA<int>(), mx_type);
|
||||||
|
break;
|
||||||
|
case Type::Float:
|
||||||
|
set_input(name, item.value->asA<float>(), mx_type);
|
||||||
|
break;
|
||||||
|
case Type::Vector2:
|
||||||
|
set_input(name, item.value->asA<MaterialX::Vector2>(), mx_type);
|
||||||
|
break;
|
||||||
|
case Type::Vector3:
|
||||||
|
set_input(name, item.value->asA<MaterialX::Vector3>(), mx_type);
|
||||||
|
break;
|
||||||
|
case Type::Vector4:
|
||||||
|
set_input(name, item.value->asA<MaterialX::Vector4>(), mx_type);
|
||||||
|
break;
|
||||||
|
case Type::Color3:
|
||||||
|
set_input(name, item.value->asA<MaterialX::Color3>(), mx_type);
|
||||||
|
break;
|
||||||
|
case Type::Color4:
|
||||||
|
set_input(name, item.value->asA<MaterialX::Color4>(), mx_type);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BLI_assert_unreachable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (item.node) {
|
else if (item.node) {
|
||||||
set_input(name, item.node, output_name);
|
node->setConnectedNode(name, item.node);
|
||||||
|
if (output_name != "") {
|
||||||
|
node->setConnectedOutput(name, item.node->getOutput(output_name));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
CLOG_WARN(LOG_MATERIALX_SHADER, "Empty item to input: %s", name.c_str());
|
CLOG_WARN(LOG_MATERIALX_SHADER, "Empty item to input: %s", name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeItem::set_input(const std::string &name, const MaterialX::ValuePtr value)
|
|
||||||
{
|
|
||||||
std::string mx_type = value->getTypeString();
|
|
||||||
if (mx_type == "float") {
|
|
||||||
set_input(name, value->asA<float>(), mx_type);
|
|
||||||
}
|
|
||||||
else if (mx_type == "integer") {
|
|
||||||
set_input(name, value->asA<int>(), mx_type);
|
|
||||||
}
|
|
||||||
else if (mx_type == "vector2") {
|
|
||||||
set_input(name, value->asA<MaterialX::Vector2>(), mx_type);
|
|
||||||
}
|
|
||||||
else if (mx_type == "vector3") {
|
|
||||||
set_input(name, value->asA<MaterialX::Vector3>(), mx_type);
|
|
||||||
}
|
|
||||||
else if (mx_type == "vector4") {
|
|
||||||
set_input(name, value->asA<MaterialX::Vector4>(), mx_type);
|
|
||||||
}
|
|
||||||
else if (mx_type == "color3") {
|
|
||||||
set_input(name, value->asA<MaterialX::Color3>(), mx_type);
|
|
||||||
}
|
|
||||||
else if (mx_type == "color4") {
|
|
||||||
set_input(name, value->asA<MaterialX::Color4>(), mx_type);
|
|
||||||
}
|
|
||||||
else if (mx_type == "string") {
|
|
||||||
set_input(name, value->asA<std::string>(), mx_type);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
BLI_assert_unreachable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void NodeItem::set_input(const std::string &name,
|
void NodeItem::set_input(const std::string &name,
|
||||||
const MaterialX::NodePtr node,
|
const NodeItem &item,
|
||||||
|
Type to_type,
|
||||||
const std::string &output_name)
|
const std::string &output_name)
|
||||||
{
|
{
|
||||||
this->node->setConnectedNode(name, node);
|
set_input(name, item.convert(to_type), output_name);
|
||||||
if (output_name != "") {
|
|
||||||
this->node->setConnectedOutput("in1", node->getOutput(output_name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeItem::add_output(const std::string &name, const std::string &mx_type)
|
void NodeItem::add_output(const std::string &name, const std::string &mx_type)
|
||||||
@ -287,19 +285,20 @@ NodeItem NodeItem::dotproduct(const NodeItem &other) const
|
|||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeItem::if_else(const std::string &condition,
|
NodeItem NodeItem::if_else(IfType condition,
|
||||||
const NodeItem &other,
|
const NodeItem &other,
|
||||||
const NodeItem &if_val,
|
const NodeItem &if_val,
|
||||||
const NodeItem &else_val) const
|
const NodeItem &else_val) const
|
||||||
{
|
{
|
||||||
if (condition == "<") {
|
switch (condition) {
|
||||||
return other.if_else(">", *this, else_val, if_val);
|
case IfType::Less:
|
||||||
}
|
return other.if_else(IfType::Greater, *this, else_val, if_val);
|
||||||
if (condition == "<=") {
|
case IfType::LessEq:
|
||||||
return other.if_else(">=", *this, else_val, if_val);
|
return other.if_else(IfType::GreaterEq, *this, else_val, if_val);
|
||||||
}
|
case IfType::NotEq:
|
||||||
if (condition == "!=") {
|
return if_else(IfType::Eq, other, else_val, if_val);
|
||||||
return if_else("==", other, else_val, if_val);
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem res = empty();
|
NodeItem res = empty();
|
||||||
@ -316,20 +315,21 @@ NodeItem NodeItem::if_else(const std::string &condition,
|
|||||||
|
|
||||||
std::function<bool(float, float)> func = nullptr;
|
std::function<bool(float, float)> func = nullptr;
|
||||||
std::string mx_category;
|
std::string mx_category;
|
||||||
if (condition == ">") {
|
switch (condition) {
|
||||||
mx_category = "ifgreater";
|
case IfType::Greater:
|
||||||
func = [](float a, float b) { return a > b; };
|
mx_category = "ifgreater";
|
||||||
}
|
func = [](float a, float b) { return a > b; };
|
||||||
else if (condition == ">=") {
|
break;
|
||||||
mx_category = "ifgreatereq";
|
case IfType::GreaterEq:
|
||||||
func = [](float a, float b) { return a >= b; };
|
mx_category = "ifgreatereq";
|
||||||
}
|
func = [](float a, float b) { return a >= b; };
|
||||||
else if (condition == "==") {
|
break;
|
||||||
mx_category = "ifequal";
|
case IfType::Eq:
|
||||||
func = [](float a, float b) { return a == b; };
|
mx_category = "ifequal";
|
||||||
}
|
func = [](float a, float b) { return a == b; };
|
||||||
else {
|
break;
|
||||||
BLI_assert_unreachable();
|
default:
|
||||||
|
BLI_assert_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value && other.value) {
|
if (value && other.value) {
|
||||||
@ -604,52 +604,6 @@ NodeItem NodeItem::convert(Type to_type) const
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeItem::to_color3() const
|
|
||||||
{
|
|
||||||
Type mx_type = type();
|
|
||||||
NodeItem res = empty();
|
|
||||||
if (value) {
|
|
||||||
MaterialX::Color3 c;
|
|
||||||
switch (mx_type) {
|
|
||||||
case Type::Float: {
|
|
||||||
float v = value->asA<float>();
|
|
||||||
c = {v, v, v};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Type::Color3: {
|
|
||||||
auto v = value->asA<MaterialX::Color3>();
|
|
||||||
c = {v[0], v[1], v[2]};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Type::Color4: {
|
|
||||||
auto v = value->asA<MaterialX::Color4>();
|
|
||||||
c = {v[0], v[1], v[2]};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Type::Vector3: {
|
|
||||||
auto v = value->asA<MaterialX::Vector3>();
|
|
||||||
c = {v[0], v[1], v[2]};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Type::Vector4: {
|
|
||||||
auto v = value->asA<MaterialX::Vector4>();
|
|
||||||
c = {v[0], v[1], v[2]};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
res.value = MaterialX::Value::createValue<MaterialX::Color3>(c);
|
|
||||||
}
|
|
||||||
else if (node) {
|
|
||||||
if (mx_type !=Type::Color3) {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
res.node = node;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeItem::Type NodeItem::type() const
|
NodeItem::Type NodeItem::type() const
|
||||||
{
|
{
|
||||||
if (value) {
|
if (value) {
|
||||||
@ -720,7 +674,7 @@ NodeItem NodeItem::arithmetic(const std::string &mx_category,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, t);
|
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, type(t));
|
||||||
res.set_input("in", *this);
|
res.set_input("in", *this);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@ -731,7 +685,7 @@ NodeItem NodeItem::arithmetic(const NodeItem &other,
|
|||||||
std::function<float(float, float)> func) const
|
std::function<float(float, float)> func) const
|
||||||
{
|
{
|
||||||
NodeItem res = empty();
|
NodeItem res = empty();
|
||||||
if (!is_numeric() || !other.is_numeric()) {
|
if (!is_arithmetic() || !other.is_arithmetic()) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ namespace blender::nodes::materialx {
|
|||||||
class NodeItem {
|
class NodeItem {
|
||||||
public:
|
public:
|
||||||
enum class Type { Empty = 0, Other, String, Integer, Float, Vector2, Vector3, Vector4, Color3, Color4 };
|
enum class Type { Empty = 0, Other, String, Integer, Float, Vector2, Vector3, Vector4, Color3, Color4 };
|
||||||
|
enum class IfType { Less = 0, LessEq, Eq, GreaterEq, Greater, NotEq };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MaterialX::ValuePtr value;
|
MaterialX::ValuePtr value;
|
||||||
@ -34,9 +35,9 @@ class NodeItem {
|
|||||||
void set_input(const std::string &name,
|
void set_input(const std::string &name,
|
||||||
const NodeItem &item,
|
const NodeItem &item,
|
||||||
const std::string &output_name = "");
|
const std::string &output_name = "");
|
||||||
void set_input(const std::string &name, const MaterialX::ValuePtr value);
|
|
||||||
void set_input(const std::string &name,
|
void set_input(const std::string &name,
|
||||||
const MaterialX::NodePtr node,
|
const NodeItem &item,
|
||||||
|
Type to_type,
|
||||||
const std::string &output_name = "");
|
const std::string &output_name = "");
|
||||||
void add_output(const std::string &name, const std::string &mx_type);
|
void add_output(const std::string &name, const std::string &mx_type);
|
||||||
|
|
||||||
@ -57,7 +58,7 @@ class NodeItem {
|
|||||||
NodeItem min(const NodeItem &other) const;
|
NodeItem min(const NodeItem &other) const;
|
||||||
NodeItem max(const NodeItem &other) const;
|
NodeItem max(const NodeItem &other) const;
|
||||||
NodeItem dotproduct(const NodeItem &other) const;
|
NodeItem dotproduct(const NodeItem &other) const;
|
||||||
NodeItem if_else(const std::string &condition,
|
NodeItem if_else(IfType condition,
|
||||||
const NodeItem &other,
|
const NodeItem &other,
|
||||||
const NodeItem &if_val,
|
const NodeItem &if_val,
|
||||||
const NodeItem &else_val) const;
|
const NodeItem &else_val) const;
|
||||||
@ -80,7 +81,6 @@ class NodeItem {
|
|||||||
NodeItem exp() const;
|
NodeItem exp() const;
|
||||||
|
|
||||||
NodeItem convert(Type to_type) const;
|
NodeItem convert(Type to_type) const;
|
||||||
NodeItem to_color3() const;
|
|
||||||
Type type() const;
|
Type type() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -32,11 +32,11 @@ NodeItem TexCheckerNodeParser::compute()
|
|||||||
modulo_y.set_input("in2", value(2.0f));
|
modulo_y.set_input("in2", value(2.0f));
|
||||||
|
|
||||||
NodeItem ifequal =
|
NodeItem ifequal =
|
||||||
(modulo_x.floor() + modulo_y.floor()).if_else("==", value(1.0f), value(0.0f), value(1.0f));
|
(modulo_x.floor() + modulo_y.floor()).if_else(NodeItem::IfType::Eq, value(1.0f), value(0.0f), value(1.0f));
|
||||||
|
|
||||||
NodeItem res = create_node("mix", "color3");
|
NodeItem res = create_node("mix", "color3");
|
||||||
res.set_input("bg", color1.to_color3());
|
res.set_input("bg", color1, NodeItem::Type::Color3);
|
||||||
res.set_input("fg", color2.to_color3());
|
res.set_input("fg", color2, NodeItem::Type::Color3);
|
||||||
res.set_input("mix", ifequal);
|
res.set_input("mix", ifequal);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user