Implement type conversion for NodeItem #9

Merged
Bogdan Nagirniak merged 12 commits from BogdanNagirniak/blender:matx-nodeitem-type into matx-export-material 2023-09-05 12:03:24 +02:00
2 changed files with 188 additions and 0 deletions
Showing only changes of commit 87237c88e3 - Show all commits

View File

@ -431,6 +431,179 @@ NodeItem NodeItem::exp() const
return arithmetic("exp", [](float a) { return std::expf(a); }); return arithmetic("exp", [](float a) { return std::expf(a); });
} }
NodeItem NodeItem::convert(Type to_type) const
{
Type t = type();
BogdanNagirniak marked this conversation as resolved
Review

Should Integer be here?

Should `Integer` be here?
Review

Discussed: let it be here

Discussed: let it be here
if (t == to_type) {
return *this;
}
if (!is_arithmetic(t) || !is_arithmetic(to_type)) {
return empty();
}
switch (t) {
case Type::Vector2:
switch (to_type) {
case Type::Vector4:
return convert(Type::Vector3).convert(Type::Vector4);
case Type::Color3:
return convert(Type::Vector3).convert(Type::Color3);
case Type::Color4:
return convert(Type::Vector3).convert(Type::Color3).convert(Type::Color4);
default:
break;
}
break;
case Type::Vector3:
switch (to_type) {
case Type::Color4:
return convert(Type::Color3).convert(Type::Color4);
default:
break;
}
break;
case Type::Vector4:
switch (to_type) {
case Type::Vector2:
return convert(Type::Vector3).convert(Type::Vector2);
case Type::Color3:
return convert(Type::Vector3).convert(Type::Color3);
default:
break;
}
break;
case Type::Color3:
switch (to_type) {
case Type::Vector2:
return convert(Type::Vector3).convert(Type::Vector2);
case Type::Vector4:
return convert(Type::Vector3).convert(Type::Vector4);
default:
break;
}
break;
case Type::Color4:
switch (to_type) {
case Type::Vector2:
return convert(Type::Vector4).convert(Type::Vector3).convert(Type::Vector2);
case Type::Vector3:
return convert(Type::Vector4).convert(Type::Vector3);
default:
break;
}
break;
default:
break;
}
NodeItem res = empty();
if (value) {
switch (t) {
case Type::Float: {
float v = value->asA<float>();
switch (to_type) {
case Type::Vector2:
res.value = MaterialX::Value::createValue<MaterialX::Vector2>({v, v});
break;
case Type::Vector3:
res.value = MaterialX::Value::createValue<MaterialX::Vector3>({v, v, v});
break;
case Type::Vector4:
res.value = MaterialX::Value::createValue<MaterialX::Vector4>({v, v, v, 1.0f});
break;
case Type::Color3:
res.value = MaterialX::Value::createValue<MaterialX::Color3>({v, v, v});
break;
case Type::Color4:
res.value = MaterialX::Value::createValue<MaterialX::Color4>({v, v, v, 1.0f});
break;
default:
BLI_assert_unreachable();
}
break;
}
case Type::Vector2: {
auto v = value->asA<MaterialX::Vector2>();
switch (to_type) {
case Type::Vector3:
res.value = MaterialX::Value::createValue<MaterialX::Vector3>({v[0], v[1], 0.0f});
break;
default:
BLI_assert_unreachable();
}
break;
}
case Type::Vector3: {
auto v = value->asA<MaterialX::Vector3>();
switch (to_type) {
case Type::Vector2:
res.value = MaterialX::Value::createValue<MaterialX::Vector2>({v[0], v[1]});
break;
case Type::Vector4:
res.value =
MaterialX::Value::createValue<MaterialX::Vector4>({v[0], v[1], v[2], 0.0f});
break;
case Type::Color3:
res.value = MaterialX::Value::createValue<MaterialX::Color3>({v[0], v[1], v[2]});
break;
default:
BLI_assert_unreachable();
}
break;
}
case Type::Vector4: {
auto v = value->asA<MaterialX::Vector4>();
switch (to_type) {
case Type::Vector3:
res.value = MaterialX::Value::createValue<MaterialX::Vector3>({v[0], v[1], v[2]});
break;
case Type::Color4:
res.value = MaterialX::Value::createValue<MaterialX::Color4>({v[0], v[1], v[2], v[3]});
break;
default:
BLI_assert_unreachable();
}
break;
}
case Type::Color3: {
auto v = value->asA<MaterialX::Color3>();
switch (to_type) {
case Type::Vector3:
res.value = MaterialX::Value::createValue<MaterialX::Vector3>({v[0], v[1], v[2]});
break;
case Type::Color4:
res.value = MaterialX::Value::createValue<MaterialX::Color4>({v[0], v[1], v[2], 1.0f});
break;
default:
BLI_assert_unreachable();
}
break;
}
case Type::Color4: {
auto v = value->asA<MaterialX::Color4>();
switch (to_type) {
case Type::Vector4:
res.value = MaterialX::Value::createValue<MaterialX::Vector4>({v[0], v[1], v[2], v[3]});
break;
case Type::Color3:
res.value = MaterialX::Value::createValue<MaterialX::Color3>({v[0], v[1], v[2]});
break;
default:
BLI_assert_unreachable();
}
break;
}
default:
BLI_assert_unreachable();
}
}
else {
res.node = graph_->addNode("convert", MaterialX::EMPTY_STRING, type(to_type));
res.set_input("in", *this);
}
return res;
}
NodeItem NodeItem::to_color3() const NodeItem NodeItem::to_color3() const
{ {
Type mx_type = type(); Type mx_type = type();
@ -493,6 +666,16 @@ NodeItem::Type NodeItem::type() const
return Type::Empty; return Type::Empty;
} }
bool NodeItem::is_arithmetic(Type t)
{
return t >= Type::Float;
}
bool NodeItem::is_arithmetic() const
{
return is_arithmetic(type());
}
NodeItem NodeItem::arithmetic(const std::string &mx_category, NodeItem NodeItem::arithmetic(const std::string &mx_category,
std::function<float(float)> func) const std::function<float(float)> func) const
{ {

View File

@ -79,11 +79,16 @@ class NodeItem {
NodeItem sign() const; NodeItem sign() const;
NodeItem exp() const; NodeItem exp() const;
NodeItem convert(Type to_type) const;
NodeItem to_color3() const; NodeItem to_color3() const;
bool is_numeric() const; bool is_numeric() const;
Type type() const; Type type() const;
private: private:
static bool is_arithmetic(Type t);
bool is_arithmetic() const;
NodeItem arithmetic(const std::string &mx_category, std::function<float(float)> func) const; NodeItem arithmetic(const std::string &mx_category, std::function<float(float)> func) const;
NodeItem arithmetic(const NodeItem &other, NodeItem arithmetic(const NodeItem &other,
const std::string &mx_category, const std::string &mx_category,