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