18 if (type_str ==
"multioutput") {
21 if (type_str ==
"string") {
24 if (type_str ==
"filename") {
27 if (type_str ==
"boolean") {
30 if (type_str ==
"integer") {
33 if (type_str ==
"float") {
36 if (type_str ==
"vector2") {
39 if (type_str ==
"vector3") {
42 if (type_str ==
"vector4") {
45 if (type_str ==
"color3") {
48 if (type_str ==
"color4") {
51 if (type_str ==
"BSDF") {
54 if (type_str ==
"EDF") {
57 if (type_str ==
"displacementshader") {
60 if (type_str ==
"surfaceshader") {
63 if (type_str ==
"material") {
102 return "displacementshader";
104 return "surfaceshader";
115bool NodeItem::is_arithmetic(
Type type)
120NodeItem::operator bool()
const
122 return value || node || input ||
output;
131 if (other.type() == type) {
132 res =
create_node(
"add", type, {{
"in1", *
this}, {
"in2", other}});
140 return arithmetic(other,
"add", [](
float a,
float b) {
return a +
b; });
145 return arithmetic(other,
"subtract", [](
float a,
float b) {
return a -
b; });
150 return val(0.0f) - *
this;
159 Type other_type = other.type();
161 res =
create_node(
"multiply", type, {{
"in1", *
this}, {
"in2", other}});
169 return arithmetic(other,
"multiply", [](
float a,
float b) {
return a *
b; });
174 return arithmetic(other,
"divide", [](
float a,
float b) {
return b == 0.0f ? 0.0f : a /
b; });
180 other,
"modulo", [](
float a,
float b) {
return b == 0.0f ? 0.0f : std::fmod(a,
b); });
185 return arithmetic(other,
"power", [](
float a,
float b) {
return std::pow(a,
b); });
196 v = value->asA<
float>();
199 v = value->asA<MaterialX::Vector2>()[index];
202 v = value->asA<MaterialX::Vector3>()[index];
205 v = value->asA<MaterialX::Vector4>()[index];
208 v = value->asA<MaterialX::Color3>()[index];
211 v = value->asA<MaterialX::Color4>()[index];
229 if (node && node == other.node) {
232 if ((node && other.value) || (value && other.node)) {
242 return item1.
value->getValueString() == item2.
value->getValueString();
247 return !(*
this == other);
252 return arithmetic(
"absval", [](
float a) {
return std::abs(a); });
257 return arithmetic(
"floor", [](
float a) {
return std::floor(a); });
262 return arithmetic(
"ceil", [](
float a) {
return std::ceil(a); });
283 return arithmetic(other,
"min", [](
float a,
float b) {
return std::min(a,
b); });
288 return arithmetic(other,
"max", [](
float a,
float b) {
return std::max(a,
b); });
293 if (value && other.value) {
298 f = d.
value->asA<
float>();
302 auto v = d.
value->asA<MaterialX::Vector2>();
307 auto v = d.
value->asA<MaterialX::Vector3>();
308 f =
v[0] +
v[1] +
v[2];
312 auto v = d.
value->asA<MaterialX::Vector4>();
313 f =
v[0] +
v[1] +
v[2] +
v[3];
317 auto v = d.
value->asA<MaterialX::Color3>();
318 f =
v[0] +
v[1] +
v[2];
322 auto v = d.
value->asA<MaterialX::Color4>();
323 f =
v[0] +
v[1] +
v[2] +
v[3];
334 cast_types(item1, item2);
341 return (
val(1.0f) - *
this) * val1 + *
this * val2;
349 return create_node(
"mix", type1, {{
"bg", val1}, {
"fg", val2}, {
"mix", *
this}});
360 if (value && min_val.
value && max_val.
value) {
361 return min(max_val).
max(min_val);
365 return create_node(
"clamp",
type(), {{
"in", *
this}, {
"low", min_val}, {
"high", max_val}});
372 {{
"in", *
this}, {
"low", min_val.
convert(type)}, {
"high", max_val.
convert(type)}});
396 NodeItem x_axis =
val(MaterialX::Vector3(1.0f, 0.0f, 0.0f));
397 NodeItem y_axis =
val(MaterialX::Vector3(0.0f, 1.0f, 0.0f));
398 NodeItem z_axis =
val(MaterialX::Vector3(0.0f, 0.0f, 1.0f));
408 return to_vector().arithmetic(
"sin", [](
float a) {
return std::sin(a); });
413 return to_vector().arithmetic(
"cos", [](
float a) {
return std::cos(a); });
418 return to_vector().arithmetic(
"tan", [](
float a) {
return std::tan(a); });
423 return to_vector().arithmetic(
"asin", [](
float a) {
return std::asin(a); });
428 return to_vector().arithmetic(
"acos", [](
float a) {
return std::acos(a); });
433 return to_vector().arithmetic(
"atan", [](
float a) {
return std::atan(a); });
438 return to_vector().arithmetic(other,
"atan2", [](
float a,
float b) {
return std::atan2(a,
b); });
444 return (
v.exp() - (-
v).exp()) /
val(2.0f);
450 return (
v.exp() + (-
v).exp()) /
val(2.0f);
458 return (a -
b) / (a +
b);
463 return to_vector().arithmetic(
"ln", [](
float a) {
return std::log(a); });
468 return to_vector().arithmetic(
"sqrt", [](
float a) {
return std::sqrt(a); });
473 return arithmetic(
"sign", [](
float a) {
return a < 0.0f ? -1.0f : (a == 0.0f ? 0.0f : 1.0f); });
478 return to_vector().arithmetic(
"exp", [](
float a) {
return std::exp(a); });
489 "Cannot convert: %s -> %s",
490 type(from_type).c_str(),
560 float v = value->asA<
float>();
563 res.
value = MaterialX::Value::createValue<MaterialX::Vector2>({
v,
v});
566 res.
value = MaterialX::Value::createValue<MaterialX::Vector3>({
v,
v,
v});
569 res.
value = MaterialX::Value::createValue<MaterialX::Vector4>({
v,
v,
v, 1.0f});
572 res.
value = MaterialX::Value::createValue<MaterialX::Color3>({
v,
v,
v});
575 res.
value = MaterialX::Value::createValue<MaterialX::Color4>({
v,
v,
v, 1.0f});
583 auto v = value->asA<MaterialX::Vector2>();
586 res.
value = MaterialX::Value::createValue<MaterialX::Vector3>({
v[0],
v[1], 0.0f});
594 auto v = value->asA<MaterialX::Vector3>();
597 res.
value = MaterialX::Value::createValue<MaterialX::Vector2>({
v[0],
v[1]});
600 res.
value = MaterialX::Value::createValue<MaterialX::Vector4>(
601 {
v[0],
v[1],
v[2], 0.0f});
604 res.
value = MaterialX::Value::createValue<MaterialX::Color3>({
v[0],
v[1],
v[2]});
612 auto v = value->asA<MaterialX::Vector4>();
615 res.
value = MaterialX::Value::createValue<MaterialX::Vector3>({
v[0],
v[1],
v[2]});
618 res.
value = MaterialX::Value::createValue<MaterialX::Color4>({
v[0],
v[1],
v[2],
v[3]});
626 auto v = value->asA<MaterialX::Color3>();
629 res.
value = MaterialX::Value::createValue<MaterialX::Vector3>({
v[0],
v[1],
v[2]});
632 res.
value = MaterialX::Value::createValue<MaterialX::Color4>({
v[0],
v[1],
v[2], 1.0f});
640 auto v = value->asA<MaterialX::Color4>();
643 res.
value = MaterialX::Value::createValue<MaterialX::Vector4>(
644 {
v[0],
v[1],
v[2],
v[3]});
647 res.
value = MaterialX::Value::createValue<MaterialX::Color3>({
v[0],
v[1],
v[2]});
707 auto item2 = else_val;
713 std::function<bool(
float,
float)> func =
nullptr;
714 std::string category;
717 category =
"ifgreater";
718 func = [](
float a,
float b) {
return a >
b; };
721 category =
"ifgreatereq";
722 func = [](
float a,
float b) {
return a >=
b; };
725 category =
"ifequal";
726 func = [](
float a,
float b) {
return a ==
b; };
732 if (value && other.value) {
733 res = func(value->asA<
float>(), other.value->asA<
float>()) ? item1 : item2;
737 category,
to_type, {{
"value1", *
this}, {
"value2", other}, {
"in1", item1}, {
"in2", item2}});
751 return type(value->getTypeString());
754 return type(node->getType());
757 return type(output->getType());
764 std::string type_str = this->
type(type);
770 res.
node = graph_->getDocument()->addNode(category, MaterialX::EMPTY_STRING, type_str);
773 res.
node = graph_->addNode(category, MaterialX::EMPTY_STRING, type_str);
807 set_input(in_name, item.
value->asA<MaterialX::Vector2>(), item_type);
810 set_input(in_name, item.
value->asA<MaterialX::Vector3>(), item_type);
813 set_input(in_name, item.
value->asA<MaterialX::Vector4>(), item_type);
816 set_input(in_name, item.
value->asA<MaterialX::Color3>(), item_type);
819 set_input(in_name, item.
value->asA<MaterialX::Color4>(), item_type);
825 else if (item.
node) {
827 auto output_name = item.
node->getName() +
"_out";
829 auto output = graph_->getOutput(output_name);
831 auto output_type = MaterialX::DEFAULT_TYPE_STRING;
832 if (item.
node->getType() ==
"BSDF") {
833 output_type =
"BSDF";
835 output = graph_->addOutput(output_name, output_type);
838 output->setConnectedNode(item.
node);
839 node->setConnectedOutput(in_name, output);
842 node->setConnectedNode(in_name, item.
node);
845 else if (item.
input) {
846 node->setAttribute(
"interfacename", item.
input->getName());
849 node->setConnectedOutput(in_name, item.
output);
859 res.
output = node->addOutput(out_name,
type(out_type));
866 res.
input = graph_->addInput(name);
883 res.
output = graph_->addOutput(name);
889 else if (item.
input) {
890 res.
output->setInterfaceName(item.
input->getName());
907 if (!is_arithmetic(t1) || !is_arithmetic(t2)) {
922bool NodeItem::is_arithmetic()
const
927NodeItem NodeItem::arithmetic(
const std::string &category, std::function<
float(
float)> func)
const
930 Type type = this->
type();
936 float v = value->asA<
float>();
937 res.value = MaterialX::Value::createValue<float>(func(
v));
941 auto v = value->asA<MaterialX::Color3>();
942 res.value = MaterialX::Value::createValue<MaterialX::Color3>(
943 {func(
v[0]), func(
v[1]), func(
v[2])});
947 auto v = value->asA<MaterialX::Color4>();
948 res.value = MaterialX::Value::createValue<MaterialX::Color4>(
949 {func(
v[0]), func(
v[1]), func(
v[2]), func(
v[3])});
953 auto v = value->asA<MaterialX::Vector2>();
954 res.value = MaterialX::Value::createValue<MaterialX::Vector2>({func(
v[0]), func(
v[1])});
958 auto v = value->asA<MaterialX::Vector3>();
959 res.value = MaterialX::Value::createValue<MaterialX::Vector3>(
960 {func(
v[0]), func(
v[1]), func(
v[2])});
964 auto v = value->asA<MaterialX::Vector4>();
965 res.value = MaterialX::Value::createValue<MaterialX::Vector4>(
966 {func(
v[0]), func(
v[1]), func(
v[2]), func(
v[3])});
974 res =
create_node(category, type, {{
"in", *
this}});
979NodeItem NodeItem::arithmetic(
const NodeItem &other,
980 const std::string &category,
981 std::function<
float(
float,
float)> func,
992 if (value && other.value) {
995 float v1 = item1.value->asA<
float>();
996 float v2 = item2.value->asA<
float>();
997 res.value = MaterialX::Value::createValue<float>(func(v1,
v2));
1001 auto v1 = item1.value->asA<MaterialX::Color3>();
1002 auto v2 = item2.value->asA<MaterialX::Color3>();
1003 res.value = MaterialX::Value::createValue<MaterialX::Color3>(
1004 {func(v1[0],
v2[0]), func(v1[1],
v2[1]), func(v1[2],
v2[2])});
1008 auto v1 = item1.value->asA<MaterialX::Color4>();
1009 auto v2 = item2.value->asA<MaterialX::Color4>();
1010 res.value = MaterialX::Value::createValue<MaterialX::Color4>(
1011 {func(v1[0],
v2[0]), func(v1[1],
v2[1]), func(v1[2],
v2[2]), func(v1[3],
v2[3])});
1015 auto v1 = item1.value->asA<MaterialX::Vector2>();
1016 auto v2 = item2.value->asA<MaterialX::Vector2>();
1017 res.value = MaterialX::Value::createValue<MaterialX::Vector2>(
1018 {func(v1[0],
v2[0]), func(v1[1],
v2[1])});
1022 auto v1 = item1.value->asA<MaterialX::Vector3>();
1023 auto v2 = item2.value->asA<MaterialX::Vector3>();
1024 res.value = MaterialX::Value::createValue<MaterialX::Vector3>(
1025 {func(v1[0],
v2[0]), func(v1[1],
v2[1]), func(v1[2],
v2[2])});
1029 auto v1 = item1.value->asA<MaterialX::Vector4>();
1030 auto v2 = item2.value->asA<MaterialX::Vector4>();
1031 res.value = MaterialX::Value::createValue<MaterialX::Vector4>(
1032 {func(v1[0],
v2[0]), func(v1[1],
v2[1]), func(v1[2],
v2[2]), func(v1[3],
v2[3])});
#define BLI_assert_unreachable()
#define CLOG_WARN(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert * v
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
NodeItem operator*(const NodeItem &other) const
NodeItem operator[](int index) const
NodeItem add_output(const std::string &out_name, Type out_type)
NodeItem operator-() const
NodeItem clamp(const NodeItem &min_val, const NodeItem &max_val) const
NodeItem dotproduct(const NodeItem &other) const
MaterialX::InputPtr input
NodeItem max(const NodeItem &other) const
NodeItem val(const T &data) const
void set_input(const std::string &in_name, const T &value, Type in_type)
bool operator!=(const NodeItem &other) const
NodeItem min(const NodeItem &other) const
bool operator==(const NodeItem &other) const
NodeItem atan2(const NodeItem &other) const
NodeItem create_input(const std::string &name, const NodeItem &item) const
MaterialX::OutputPtr output
NodeItem operator+(const NodeItem &other) const
static bool is_arithmetic(Type type)
NodeItem if_else(CompareOp op, const NodeItem &other, const NodeItem &if_val, const NodeItem &else_val) const
NodeItem to_vector() const
NodeItem rotate(const NodeItem &angle, const NodeItem &axis)
MaterialX::ValuePtr value
NodeItem convert(Type to_type) const
NodeItem create_output(const std::string &name, const NodeItem &item) const
NodeItem operator^(const NodeItem &other) const
NodeItem mix(const NodeItem &val1, const NodeItem &val2) const
static Type type(const std::string &type_str)
NodeItem operator/(const NodeItem &other) const
std::vector< std::pair< std::string, NodeItem > > Inputs
NodeItem normalize() const
NodeItem operator%(const NodeItem &other) const
NodeItem create_node(const std::string &category, Type type) const
local_group_size(16, 16) .push_constant(Type b
CCL_NAMESPACE_BEGIN ccl_device float invert(float color, float factor)
static Type to_type(const eGPUType type)
struct CLG_LogRef * LOG_MATERIALX_SHADER
static blender::bke::bNodeSocketTemplate inputs[]