forked from blender/blender
Implement export of Math node. Continue other arithmetic support for NodeItem #6
@ -152,11 +152,13 @@ if(WITH_MATERIALX)
|
|||||||
materialx/nodes/invert.cc
|
materialx/nodes/invert.cc
|
||||||
materialx/nodes/math.cc
|
materialx/nodes/math.cc
|
||||||
materialx/nodes/mix_rgb.cc
|
materialx/nodes/mix_rgb.cc
|
||||||
|
#materialx/nodes/node_item.cc
|
||||||
materialx/nodes/node_parser.cc
|
materialx/nodes/node_parser.cc
|
||||||
materialx/nodes/output_material.cc
|
materialx/nodes/output_material.cc
|
||||||
materialx/nodes/tex_image.cc
|
materialx/nodes/tex_image.cc
|
||||||
|
|
||||||
materialx/material.h
|
materialx/material.h
|
||||||
|
#materialx/nodes/node_item.h
|
||||||
materialx/nodes/node_parser.h
|
materialx/nodes/node_parser.h
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
@ -30,8 +30,8 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
NodeItem base_color = get_input_value("Base Color");
|
NodeItem base_color = get_input_value("Base Color");
|
||||||
|
|
||||||
NodeItem subsurface = get_input_value("Subsurface");
|
NodeItem subsurface = get_input_value("Subsurface");
|
||||||
NodeItem subsurface_radius = empty_value();
|
NodeItem subsurface_radius = empty();
|
||||||
NodeItem subsurface_color = empty_value();
|
NodeItem subsurface_color = empty();
|
||||||
if (enabled(subsurface)) {
|
if (enabled(subsurface)) {
|
||||||
subsurface_radius = get_input_value("Subsurface Radius");
|
subsurface_radius = get_input_value("Subsurface Radius");
|
||||||
subsurface_color = get_input_value("Subsurface Color");
|
subsurface_color = get_input_value("Subsurface Color");
|
||||||
@ -42,8 +42,8 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
// NodeItem specular_tint = get_input_value("Specular Tint");
|
// NodeItem specular_tint = get_input_value("Specular Tint");
|
||||||
NodeItem roughness = get_input_value("Roughness");
|
NodeItem roughness = get_input_value("Roughness");
|
||||||
|
|
||||||
NodeItem anisotropic = empty_value();
|
NodeItem anisotropic = empty();
|
||||||
NodeItem anisotropic_rotation = empty_value();
|
NodeItem anisotropic_rotation = empty();
|
||||||
if (enabled(metallic)) {
|
if (enabled(metallic)) {
|
||||||
/* TODO: use Specular Tint input */
|
/* TODO: use Specular Tint input */
|
||||||
anisotropic = get_input_value("Anisotropic");
|
anisotropic = get_input_value("Anisotropic");
|
||||||
@ -54,12 +54,12 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
}
|
}
|
||||||
|
|
||||||
NodeItem sheen = get_input_value("Sheen");
|
NodeItem sheen = get_input_value("Sheen");
|
||||||
// sheen_tint = empty_value();
|
// sheen_tint = empty();
|
||||||
// if enabled(sheen):
|
// if enabled(sheen):
|
||||||
// sheen_tint = get_input_value("Sheen Tint");
|
// sheen_tint = get_input_value("Sheen Tint");
|
||||||
|
|
||||||
NodeItem clearcoat = get_input_value("Clearcoat");
|
NodeItem clearcoat = get_input_value("Clearcoat");
|
||||||
NodeItem clearcoat_roughness = empty_value();
|
NodeItem clearcoat_roughness = empty();
|
||||||
if (enabled(clearcoat)) {
|
if (enabled(clearcoat)) {
|
||||||
clearcoat_roughness = get_input_value("Clearcoat Roughness");
|
clearcoat_roughness = get_input_value("Clearcoat Roughness");
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ NodeItem BSDFPrincipledNodeParser::compute()
|
|||||||
NodeItem ior = get_input_value("IOR");
|
NodeItem ior = get_input_value("IOR");
|
||||||
|
|
||||||
NodeItem transmission = get_input_value("Transmission");
|
NodeItem transmission = get_input_value("Transmission");
|
||||||
NodeItem transmission_roughness = empty_value();
|
NodeItem transmission_roughness = empty();
|
||||||
if (enabled(transmission)) {
|
if (enabled(transmission)) {
|
||||||
transmission_roughness = get_input_value("Transmission Roughness");
|
transmission_roughness = get_input_value("Transmission Roughness");
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ namespace blender::nodes::materialx {
|
|||||||
NodeItem MathNodeParser::compute()
|
NodeItem MathNodeParser::compute()
|
||||||
{
|
{
|
||||||
/* TODO: implement */
|
/* TODO: implement */
|
||||||
return empty_value();
|
return empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
} // namespace blender::nodes::materialx
|
||||||
|
@ -9,7 +9,7 @@ namespace blender::nodes::materialx {
|
|||||||
NodeItem MixRGBNodeParser::compute()
|
NodeItem MixRGBNodeParser::compute()
|
||||||
{
|
{
|
||||||
/* TODO: implement */
|
/* TODO: implement */
|
||||||
return empty_value();
|
return empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
} // namespace blender::nodes::materialx
|
||||||
|
@ -84,6 +84,17 @@ NodeItem NodeItem::operator/(const NodeItem &other) const
|
|||||||
return arithmetic(other, "divide", [](float a, float b) { return b == 0.0f ? 0.0f : a / b; });
|
return arithmetic(other, "divide", [](float a, float b) { return b == 0.0f ? 0.0f : a / b; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::operator%(const NodeItem &other) const
|
||||||
|
{
|
||||||
|
return arithmetic(
|
||||||
|
other, "modulo", [](float a, float b) { return b == 0.0f ? 0.0f : std::fmodf(a, b); });
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::operator^(const NodeItem &other) const
|
||||||
|
{
|
||||||
|
return arithmetic(other, "power", [](float a, float b) { return std::powf(a, b); });
|
||||||
|
}
|
||||||
|
|
||||||
bool NodeItem::operator==(const NodeItem &other) const
|
bool NodeItem::operator==(const NodeItem &other) const
|
||||||
{
|
{
|
||||||
if (node && node == other.node) {
|
if (node && node == other.node) {
|
||||||
@ -93,6 +104,21 @@ bool NodeItem::operator==(const NodeItem &other) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::abs() const
|
||||||
|
{
|
||||||
|
return arithmetic("absval", [](float a) { return std::fabsf(a); });
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::floor() const
|
||||||
|
{
|
||||||
|
return arithmetic("floor", [](float a) { return std::floorf(a); });
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::ceil() const
|
||||||
|
{
|
||||||
|
return arithmetic("ceil", [](float a) { return std::ceilf(a); });
|
||||||
|
}
|
||||||
|
|
||||||
NodeItem NodeItem::min(const NodeItem &other) const
|
NodeItem NodeItem::min(const NodeItem &other) const
|
||||||
{
|
{
|
||||||
return arithmetic(other, "min", [](float a, float b) { return std::min(a, b); });
|
return arithmetic(other, "min", [](float a, float b) { return std::min(a, b); });
|
||||||
@ -103,11 +129,122 @@ NodeItem NodeItem::max(const NodeItem &other) const
|
|||||||
return arithmetic(other, "max", [](float a, float b) { return std::max(a, b); });
|
return arithmetic(other, "max", [](float a, float b) { return std::max(a, b); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::dot(const NodeItem &other) const
|
||||||
|
{
|
||||||
|
NodeItem d = arithmetic(other, "dotproduct", [](float a, float b) { return a * b; });
|
||||||
|
if (d.value) {
|
||||||
|
std::string t = d.type();
|
||||||
|
float f = 0.0f;
|
||||||
|
if (t == "float") {
|
||||||
|
f = value->asA<float>();
|
||||||
|
}
|
||||||
|
else if (t == "color3") {
|
||||||
|
auto v = value->asA<MaterialX::Color3>();
|
||||||
|
f = v[0] + v[1] + v[2];
|
||||||
|
}
|
||||||
|
else if (t == "color4") {
|
||||||
|
auto v = value->asA<MaterialX::Color4>();
|
||||||
|
f = v[0] + v[1] + v[2] + v[3];
|
||||||
|
}
|
||||||
|
else if (t == "vector2") {
|
||||||
|
auto v = value->asA<MaterialX::Vector2>();
|
||||||
|
f = v[0] + v[1];
|
||||||
|
}
|
||||||
|
else if (t == "vector3") {
|
||||||
|
auto v = value->asA<MaterialX::Vector3>();
|
||||||
|
f = v[0] + v[1] + v[2];
|
||||||
|
}
|
||||||
|
else if (t == "vector4") {
|
||||||
|
auto v = value->asA<MaterialX::Vector4>();
|
||||||
|
f = v[0] + v[1] + v[2] + v[3];
|
||||||
|
}
|
||||||
|
d.value = MaterialX::Value::createValue(f);
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::if_else(char condition,
|
||||||
|
const NodeItem &other,
|
||||||
|
const NodeItem &if_val,
|
||||||
|
const NodeItem &else_val) const
|
||||||
|
{
|
||||||
|
//def if_else(self, cond: str, other, if_value, else_value):
|
||||||
|
// if cond == '>':
|
||||||
|
// res = self._arithmetic_helper(other, 'ifgreater', lambda a, b: float(a > b))
|
||||||
|
// elif cond == '>=':
|
||||||
|
// res = self._arithmetic_helper(other, 'ifgreatereq', lambda a, b: float(a >= b))
|
||||||
|
// elif cond == '==':
|
||||||
|
// res = self._arithmetic_helper(other, 'ifequal', lambda a, b: float(a == b))
|
||||||
|
// elif cond == '<':
|
||||||
|
// return self.node_item(other).if_else('>', self, else_value, if_value)
|
||||||
|
// elif cond == '<=':
|
||||||
|
// return self.node_item(other).if_else('>=', self, else_value, if_value)
|
||||||
|
// elif cond == '!=':
|
||||||
|
// return self.if_else('==', other, else_value, if_value)
|
||||||
|
// else:
|
||||||
|
// raise ValueError("Incorrect condition:", cond)
|
||||||
|
|
||||||
|
// if isinstance(res.data, float):
|
||||||
|
// return if_value if res.data == 1.0 else else_value
|
||||||
|
// elif isinstance(res.data, tuple):
|
||||||
|
// return if_value if res.data[0] == 1.0 else else_value
|
||||||
|
// else:
|
||||||
|
// res.set_input('value1', if_value)
|
||||||
|
// res.set_input('value2', else_value)
|
||||||
|
// return res
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
|
|
||||||
NodeItem NodeItem::blend(const NodeItem &a, const NodeItem &b) const
|
NodeItem NodeItem::blend(const NodeItem &a, const NodeItem &b) const
|
||||||
{
|
{
|
||||||
return (val(1.0f) - *this) * a + *this * b;
|
return (val(1.0f) - *this) * a + *this * b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::clamp(const NodeItem &min_val, const NodeItem &max_val) const
|
||||||
|
{
|
||||||
|
return min(max_val).max(min_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::clamp(float min_val, float max_val) const
|
||||||
|
{
|
||||||
|
return clamp(val(min_val), val(max_val));
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::sin() const
|
||||||
|
{
|
||||||
|
return arithmetic("sin", [](float a) { return std::sinf(a); });
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::cos() const
|
||||||
|
{
|
||||||
|
return arithmetic("cos", [](float a) { return std::cosf(a); });
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::tan() const
|
||||||
|
{
|
||||||
|
return arithmetic("tan", [](float a) { return std::tanf(a); });
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::asin() const
|
||||||
|
{
|
||||||
|
return arithmetic("asin", [](float a) { return std::asinf(a); });
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::acos() const
|
||||||
|
{
|
||||||
|
return arithmetic("acos", [](float a) { return std::acosf(a); });
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::atan() const
|
||||||
|
{
|
||||||
|
return arithmetic("atan", [](float a) { return std::atanf(a); });
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeItem NodeItem::log() const
|
||||||
|
{
|
||||||
|
return arithmetic("ln", [](float a) { return std::logf(a); });
|
||||||
|
}
|
||||||
|
|
||||||
NodeItem NodeItem::to_color3() const
|
NodeItem NodeItem::to_color3() const
|
||||||
{
|
{
|
||||||
std::string t = type();
|
std::string t = type();
|
||||||
@ -337,7 +474,7 @@ NodeItem NodeParser::create_node(const std::string &mx_category,
|
|||||||
const std::string &mx_type,
|
const std::string &mx_type,
|
||||||
bool accessory)
|
bool accessory)
|
||||||
{
|
{
|
||||||
NodeItem res = empty_value();
|
NodeItem res = empty();
|
||||||
res.node = graph->addNode(mx_category,
|
res.node = graph->addNode(mx_category,
|
||||||
accessory ? MaterialX::EMPTY_STRING :
|
accessory ? MaterialX::EMPTY_STRING :
|
||||||
MaterialX::createValidName(node->name),
|
MaterialX::createValidName(node->name),
|
||||||
@ -347,7 +484,7 @@ NodeItem NodeParser::create_node(const std::string &mx_category,
|
|||||||
|
|
||||||
NodeItem NodeParser::get_input_default(const std::string &name)
|
NodeItem NodeParser::get_input_default(const std::string &name)
|
||||||
{
|
{
|
||||||
NodeItem res = empty_value();
|
NodeItem res = empty();
|
||||||
|
|
||||||
const bNodeSocket &socket = node->input_by_identifier(name);
|
const bNodeSocket &socket = node->input_by_identifier(name);
|
||||||
switch (socket.type) {
|
switch (socket.type) {
|
||||||
@ -374,7 +511,7 @@ NodeItem NodeParser::get_input_default(const std::string &name)
|
|||||||
|
|
||||||
NodeItem NodeParser::get_input_link(const std::string &name)
|
NodeItem NodeParser::get_input_link(const std::string &name)
|
||||||
{
|
{
|
||||||
NodeItem res = empty_value();
|
NodeItem res = empty();
|
||||||
|
|
||||||
const bNodeLink *link = node->input_by_identifier(name).link;
|
const bNodeLink *link = node->input_by_identifier(name).link;
|
||||||
if (!(link && link->is_used())) {
|
if (!(link && link->is_used())) {
|
||||||
@ -428,7 +565,7 @@ NodeItem NodeParser::get_input_value(const std::string &name)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeItem NodeParser::empty_value()
|
NodeItem NodeParser::empty()
|
||||||
{
|
{
|
||||||
return NodeItem(graph);
|
return NodeItem(graph);
|
||||||
}
|
}
|
||||||
|
@ -38,11 +38,30 @@ class NodeItem {
|
|||||||
NodeItem operator-(const NodeItem &other) const;
|
NodeItem operator-(const NodeItem &other) const;
|
||||||
NodeItem operator*(const NodeItem &other) const;
|
NodeItem operator*(const NodeItem &other) const;
|
||||||
NodeItem operator/(const NodeItem &other) const;
|
NodeItem operator/(const NodeItem &other) const;
|
||||||
|
NodeItem operator%(const NodeItem &other) const;
|
||||||
|
NodeItem operator^(const NodeItem &other) const;
|
||||||
bool operator==(const NodeItem &other) const;
|
bool operator==(const NodeItem &other) const;
|
||||||
|
|
||||||
|
NodeItem abs() const;
|
||||||
|
NodeItem floor() const;
|
||||||
|
NodeItem ceil() const;
|
||||||
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 dot(const NodeItem &other) const;
|
||||||
|
NodeItem if_else(char condition,
|
||||||
|
const NodeItem &other,
|
||||||
|
const NodeItem &if_val,
|
||||||
|
const NodeItem &else_val) const;
|
||||||
NodeItem blend(const NodeItem &a, const NodeItem &b) const;
|
NodeItem blend(const NodeItem &a, const NodeItem &b) const;
|
||||||
|
NodeItem clamp(const NodeItem &min_val, const NodeItem &max_val) const;
|
||||||
|
NodeItem clamp(float min_val = 0.0f, float max_val = 1.0f) const;
|
||||||
|
NodeItem sin() const;
|
||||||
|
NodeItem cos() const;
|
||||||
|
NodeItem tan() const;
|
||||||
|
NodeItem asin() const;
|
||||||
|
NodeItem acos() const;
|
||||||
|
NodeItem atan() const;
|
||||||
|
NodeItem log() const;
|
||||||
|
|
||||||
NodeItem to_color3() const;
|
NodeItem to_color3() const;
|
||||||
bool is_numeric() const;
|
bool is_numeric() const;
|
||||||
@ -92,7 +111,7 @@ class NodeParser {
|
|||||||
NodeItem get_input_default(const std::string &name);
|
NodeItem get_input_default(const std::string &name);
|
||||||
NodeItem get_input_link(const std::string &name);
|
NodeItem get_input_link(const std::string &name);
|
||||||
NodeItem get_input_value(const std::string &name);
|
NodeItem get_input_value(const std::string &name);
|
||||||
NodeItem empty_value();
|
NodeItem empty();
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DECLARE_PARSER(T) \
|
#define DECLARE_PARSER(T) \
|
||||||
|
@ -8,7 +8,7 @@ namespace blender::nodes::materialx {
|
|||||||
|
|
||||||
NodeItem OutputMaterialNodeParser::compute()
|
NodeItem OutputMaterialNodeParser::compute()
|
||||||
{
|
{
|
||||||
NodeItem node = empty_value();
|
NodeItem node = empty();
|
||||||
NodeItem surface = get_input_link("Surface");
|
NodeItem surface = get_input_link("Surface");
|
||||||
if (surface) {
|
if (surface) {
|
||||||
node = create_node("surfacematerial", "material");
|
node = create_node("surfacematerial", "material");
|
||||||
|
Loading…
Reference in New Issue
Block a user