forked from blender/blender
Implement type conversion for NodeItem #10
@ -187,29 +187,14 @@ bool NodeItem::operator==(const NodeItem &other) const
|
||||
return false;
|
||||
}
|
||||
|
||||
Type mx_type;
|
||||
auto val1 = value;
|
||||
auto val2 = other.value;
|
||||
if (!adjust_types(val1, val2, mx_type)) {
|
||||
|
||||
NodeItem item1 = *this;
|
||||
NodeItem item2 = other;
|
||||
Type tp = adjust_types(item1, item2);
|
||||
if (tp == Type::Empty) {
|
||||
return false;
|
||||
}
|
||||
switch (mx_type) {
|
||||
case Type::Vector2:
|
||||
return val1->asA<MaterialX::Vector2>() == val2->asA<MaterialX::Vector2>();
|
||||
case Type::Vector3:
|
||||
return val1->asA<MaterialX::Vector3>() == val2->asA<MaterialX::Vector3>();
|
||||
case Type::Vector4:
|
||||
return val1->asA<MaterialX::Vector4>() == val2->asA<MaterialX::Vector4>();
|
||||
case Type::Float:
|
||||
return val1->asA<float>() == val2->asA<float>();
|
||||
case Type::Color3:
|
||||
return val1->asA<MaterialX::Color3>() == val2->asA<MaterialX::Color3>();
|
||||
case Type::Color4:
|
||||
return val1->asA<MaterialX::Color4>() == val2->asA<MaterialX::Color4>();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
return item1.value->getValueString() == item2.value->getValueString();
|
||||
}
|
||||
|
||||
bool NodeItem::operator!=(const NodeItem &other) const
|
||||
@ -307,10 +292,10 @@ NodeItem NodeItem::if_else(IfType condition,
|
||||
return res;
|
||||
}
|
||||
|
||||
auto val1 = if_val;
|
||||
auto val2 = else_val;
|
||||
Type mx_type;
|
||||
if (!adjust_types(val1, val2, mx_type)) {
|
||||
auto item1 = if_val;
|
||||
auto item2 = else_val;
|
||||
Type tp = adjust_types(item1, item2);
|
||||
if (tp == Type::Empty) {
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -334,14 +319,14 @@ NodeItem NodeItem::if_else(IfType condition,
|
||||
}
|
||||
|
||||
if (value && other.value) {
|
||||
res = func(value->asA<float>(), other.value->asA<float>()) ? val1 : val2;
|
||||
res = func(value->asA<float>(), other.value->asA<float>()) ? item1 : item2;
|
||||
}
|
||||
else {
|
||||
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, type(mx_type));
|
||||
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, type(tp));
|
||||
res.set_input("value1", *this);
|
||||
res.set_input("value2", other);
|
||||
res.set_input("in1", val1);
|
||||
res.set_input("in2", val2);
|
||||
res.set_input("in1", item1);
|
||||
res.set_input("in2", item2);
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -626,7 +611,7 @@ bool NodeItem::is_arithmetic() const
|
||||
return is_arithmetic(type());
|
||||
}
|
||||
|
||||
NodeItem NodeItem::arithmetic(const std::string &mx_category,
|
||||
NodeItem NodeItem::arithmetic(const std::string &category,
|
||||
std::function<float(float)> func) const
|
||||
{
|
||||
NodeItem res = empty();
|
||||
@ -675,67 +660,63 @@ NodeItem NodeItem::arithmetic(const std::string &mx_category,
|
||||
}
|
||||
}
|
||||
else {
|
||||
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, type(t));
|
||||
res.node = graph_->addNode(category, MaterialX::EMPTY_STRING, type(t));
|
||||
res.set_input("in", *this);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
NodeItem NodeItem::arithmetic(const NodeItem &other,
|
||||
const std::string &mx_category,
|
||||
const std::string &category,
|
||||
std::function<float(float, float)> func) const
|
||||
{
|
||||
NodeItem res = empty();
|
||||
if (!is_arithmetic() || !other.is_arithmetic()) {
|
||||
NodeItem item1 = *this;
|
||||
NodeItem item2 = other;
|
||||
Type tp = adjust_types(item1, item2);
|
||||
if (tp == Type::Empty) {
|
||||
return res;
|
||||
}
|
||||
|
||||
Type mx_type;
|
||||
if (value && other.value) {
|
||||
auto val1 = value;
|
||||
auto val2 = other.value;
|
||||
if (!adjust_types(val1, val2, mx_type)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
switch (mx_type) {
|
||||
switch (tp) {
|
||||
case Type::Float: {
|
||||
float v1 = val1->asA<float>();
|
||||
float v2 = val2->asA<float>();
|
||||
float v1 = item1.value->asA<float>();
|
||||
float v2 = item2.value->asA<float>();
|
||||
res.value = MaterialX::Value::createValue<float>(func(v1, v2));
|
||||
break;
|
||||
}
|
||||
case Type::Color3: {
|
||||
auto v1 = val1->asA<MaterialX::Color3>();
|
||||
auto v2 = val2->asA<MaterialX::Color3>();
|
||||
auto v1 = item1.value->asA<MaterialX::Color3>();
|
||||
auto v2 = item2.value->asA<MaterialX::Color3>();
|
||||
res.value = MaterialX::Value::createValue<MaterialX::Color3>(
|
||||
{func(v1[0], v2[0]), func(v1[1], v2[1]), func(v1[2], v2[2])});
|
||||
break;
|
||||
}
|
||||
case Type::Color4: {
|
||||
auto v1 = val1->asA<MaterialX::Color4>();
|
||||
auto v2 = val2->asA<MaterialX::Color4>();
|
||||
auto v1 = item1.value->asA<MaterialX::Color4>();
|
||||
auto v2 = item2.value->asA<MaterialX::Color4>();
|
||||
res.value = MaterialX::Value::createValue<MaterialX::Color4>(
|
||||
{func(v1[0], v2[0]), func(v1[1], v2[1]), func(v1[2], v2[2]), func(v1[3], v2[3])});
|
||||
break;
|
||||
}
|
||||
case Type::Vector2: {
|
||||
auto v1 = val1->asA<MaterialX::Vector2>();
|
||||
auto v2 = val2->asA<MaterialX::Vector2>();
|
||||
auto v1 = item1.value->asA<MaterialX::Vector2>();
|
||||
auto v2 = item2.value->asA<MaterialX::Vector2>();
|
||||
res.value = MaterialX::Value::createValue<MaterialX::Vector2>(
|
||||
{func(v1[0], v2[0]), func(v1[1], v2[1])});
|
||||
break;
|
||||
}
|
||||
case Type::Vector3: {
|
||||
auto v1 = val1->asA<MaterialX::Vector3>();
|
||||
auto v2 = val2->asA<MaterialX::Vector3>();
|
||||
auto v1 = item1.value->asA<MaterialX::Vector3>();
|
||||
auto v2 = item2.value->asA<MaterialX::Vector3>();
|
||||
res.value = MaterialX::Value::createValue<MaterialX::Vector3>(
|
||||
{func(v1[0], v2[0]), func(v1[1], v2[1]), func(v1[2], v2[2])});
|
||||
break;
|
||||
}
|
||||
case Type::Vector4: {
|
||||
auto v1 = val1->asA<MaterialX::Vector4>();
|
||||
auto v2 = val2->asA<MaterialX::Vector4>();
|
||||
auto v1 = item1.value->asA<MaterialX::Vector4>();
|
||||
auto v2 = item2.value->asA<MaterialX::Vector4>();
|
||||
res.value = MaterialX::Value::createValue<MaterialX::Vector4>(
|
||||
{func(v1[0], v2[0]), func(v1[1], v2[1]), func(v1[2], v2[2]), func(v1[3], v2[3])});
|
||||
break;
|
||||
@ -745,91 +726,31 @@ NodeItem NodeItem::arithmetic(const NodeItem &other,
|
||||
}
|
||||
}
|
||||
else {
|
||||
auto val1 = *this;
|
||||
auto val2 = other;
|
||||
if (!adjust_types(val1, val2, mx_type)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, type(mx_type));
|
||||
res.set_input("in1", val1);
|
||||
res.set_input("in2", val2);
|
||||
res.node = graph_->addNode(category, MaterialX::EMPTY_STRING, type(tp));
|
||||
res.set_input("in1", item1);
|
||||
res.set_input("in2", item2);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
MaterialX::ValuePtr NodeItem::float_to_type(float v, Type mx_type)
|
||||
NodeItem::Type NodeItem::adjust_types(NodeItem &item1, NodeItem &item2)
|
||||
{
|
||||
MaterialX::ValuePtr res;
|
||||
switch (mx_type) {
|
||||
case Type::Float:
|
||||
res = MaterialX::Value::createValue<float>(v);
|
||||
break;
|
||||
case Type::Vector2:
|
||||
res = MaterialX::Value::createValue<MaterialX::Vector2>({v, v});
|
||||
break;
|
||||
case Type::Vector3:
|
||||
res = MaterialX::Value::createValue<MaterialX::Vector3>({v, v, v});
|
||||
break;
|
||||
case Type::Vector4:
|
||||
res = MaterialX::Value::createValue<MaterialX::Vector4>({v, v, v, v});
|
||||
break;
|
||||
case Type::Color3:
|
||||
res = MaterialX::Value::createValue<MaterialX::Color3>({v, v, v});
|
||||
break;
|
||||
case Type::Color4:
|
||||
res = MaterialX::Value::createValue<MaterialX::Color4>({v, v, v, v});
|
||||
break;
|
||||
default:
|
||||
BLI_assert_unreachable();
|
||||
Type t1 = item1.type();
|
||||
Type t2 = item2.type();
|
||||
if (t1 == t2) {
|
||||
return t1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool NodeItem::adjust_types(MaterialX::ValuePtr &val1, MaterialX::ValuePtr &val2, Type &mx_type)
|
||||
{
|
||||
Type t1 = type(val1->getTypeString());
|
||||
Type t2 = type(val2->getTypeString());
|
||||
if (t1 != t2) {
|
||||
if (t1 == Type::Float) {
|
||||
val1 = float_to_type(val1->asA<float>(), t2);
|
||||
mx_type = t2;
|
||||
if (!is_arithmetic(t1) || !is_arithmetic(t2)) {
|
||||
return Type::Empty;
|
||||
}
|
||||
else if (t2 == Type::Float) {
|
||||
val2 = float_to_type(val2->asA<float>(), t1);
|
||||
mx_type = t1;
|
||||
if (t1 < t2) {
|
||||
item1 = item1.convert(t2);
|
||||
return t2;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
item2 = item2.convert(t1);
|
||||
return t1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mx_type = t1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NodeItem::adjust_types(NodeItem &val1, NodeItem &val2, Type &mx_type)
|
||||
{
|
||||
Type t1 = val1.type();
|
||||
Type t2 = val2.type();
|
||||
if (t1 != t2) {
|
||||
if (val1.value && t1 == Type::Float) {
|
||||
val1.value = float_to_type(val1.value->asA<float>(), t2);
|
||||
mx_type = t2;
|
||||
}
|
||||
else if (val2.value && t2 == Type::Float) {
|
||||
val2.value = float_to_type(val2.value->asA<float>(), t1);
|
||||
mx_type = t1;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mx_type = t1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace blender::nodes::materialx
|
||||
|
@ -88,14 +88,11 @@ class NodeItem {
|
||||
|
||||
bool is_arithmetic() const;
|
||||
|
||||
NodeItem arithmetic(const std::string &mx_category, std::function<float(float)> func) const;
|
||||
NodeItem arithmetic(const std::string &category, std::function<float(float)> func) const;
|
||||
NodeItem arithmetic(const NodeItem &other,
|
||||
const std::string &mx_category,
|
||||
const std::string &category,
|
||||
std::function<float(float, float)> func) const;
|
||||
static MaterialX::ValuePtr float_to_type(float v, Type mx_type);
|
||||
/* Functions for adjusting values to make equal types */
|
||||
static bool adjust_types(MaterialX::ValuePtr &val1, MaterialX::ValuePtr &val2, Type &mx_type);
|
||||
static bool adjust_types(NodeItem &val1, NodeItem &val2, Type &mx_type);
|
||||
static Type adjust_types(NodeItem &item1, NodeItem &item2);
|
||||
};
|
||||
|
||||
template<class T> NodeItem NodeItem::val(const T &data) const
|
||||
|
Loading…
Reference in New Issue
Block a user