forked from blender/blender
Implement export of Math node. Continue other arithmetic support for NodeItem #6
@ -103,13 +103,44 @@ NodeItem NodeItem::operator^(const NodeItem &other) const
|
|||||||
|
|
||||||
bool NodeItem::operator==(const NodeItem &other) const
|
bool NodeItem::operator==(const NodeItem &other) const
|
||||||
{
|
{
|
||||||
|
if (!*this) {
|
||||||
|
return !other;
|
||||||
|
}
|
||||||
|
if (!other) {
|
||||||
|
return !*this;
|
||||||
|
}
|
||||||
if (node && node == other.node) {
|
if (node && node == other.node) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (value && other.value) {
|
if ((node && other.value) || (value && other.node)) {
|
||||||
NodeItem cmp = if_else("==", other, val(1.0f), val(0.0f));
|
return false;
|
||||||
return cmp.value->asA<float>() == 1.0f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string t;
|
||||||
|
auto val1 = value;
|
||||||
|
auto val2 = other.value;
|
||||||
|
if (!adjust_types(val1, val2, t)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (t == "float") {
|
||||||
|
return val1->asA<float>() == val2->asA<float>();
|
||||||
|
}
|
||||||
|
if (t == "color3") {
|
||||||
|
return val1->asA<MaterialX::Color3>() == val2->asA<MaterialX::Color3>();
|
||||||
|
}
|
||||||
|
if (t == "color4") {
|
||||||
|
return val1->asA<MaterialX::Color4>() == val2->asA<MaterialX::Color4>();
|
||||||
|
}
|
||||||
|
if (t == "vector2") {
|
||||||
|
return val1->asA<MaterialX::Vector2>() == val2->asA<MaterialX::Vector2>();
|
||||||
|
}
|
||||||
|
if (t == "vector3") {
|
||||||
|
return val1->asA<MaterialX::Vector3>() == val2->asA<MaterialX::Vector3>();
|
||||||
|
}
|
||||||
|
if (t == "vector4") {
|
||||||
|
return val1->asA<MaterialX::Vector4>() == val2->asA<MaterialX::Vector4>();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,17 +213,6 @@ NodeItem NodeItem::if_else(const std::string &condition,
|
|||||||
const NodeItem &if_val,
|
const NodeItem &if_val,
|
||||||
const NodeItem &else_val) const
|
const NodeItem &else_val) const
|
||||||
{
|
{
|
||||||
/* TODO: if_else() doesn't work correctly. Here is description
|
|
||||||
* Node: <ifgreater>
|
|
||||||
* Output the value of in1 if value1>value2, or the value of in2 if value1<=value2.
|
|
||||||
<nodedef name="ND_ifgreater_color3" node="ifgreater" nodegroup="conditional">
|
|
||||||
<input name="value1" type="float" value="1.0" />
|
|
||||||
<input name="value2" type="float" value="0.0" />
|
|
||||||
<input name="in1" type="color3" value="0.0, 0.0, 0.0" />
|
|
||||||
<input name="in2" type="color3" value="0.0, 0.0, 0.0" />
|
|
||||||
<output name="out" type="color3" defaultinput="in1" />
|
|
||||||
</nodedef>
|
|
||||||
*/
|
|
||||||
if (condition == "<") {
|
if (condition == "<") {
|
||||||
return other.if_else(">", *this, else_val, if_val);
|
return other.if_else(">", *this, else_val, if_val);
|
||||||
}
|
}
|
||||||
@ -204,27 +224,46 @@ NodeItem NodeItem::if_else(const std::string &condition,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NodeItem res = empty();
|
NodeItem res = empty();
|
||||||
|
if (type() != "float" || other.type() != "float") {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto val1 = if_val;
|
||||||
|
auto val2 = else_val;
|
||||||
|
std::string t;
|
||||||
|
if (!adjust_types(val1, val2, t)) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::function<bool(float, float)> func = nullptr;
|
||||||
|
std::string mx_category;
|
||||||
if (condition == ">") {
|
if (condition == ">") {
|
||||||
res = arithmetic(other, "ifgreater", [](float a, float b) { return float(a > b); });
|
mx_category = "ifgreater";
|
||||||
|
func = [](float a, float b) { return a > b; };
|
||||||
}
|
}
|
||||||
else if (condition == ">=") {
|
else if (condition == ">=") {
|
||||||
res = arithmetic(other, "ifgreatereq", [](float a, float b) { return float(a >= b); });
|
mx_category = "ifgreatereq";
|
||||||
|
func = [](float a, float b) { return a >= b; };
|
||||||
}
|
}
|
||||||
else if (condition == "==") {
|
else if (condition == "==") {
|
||||||
res = arithmetic(other, "ifequal", [](float a, float b) { return float(a == b); });
|
mx_category = "ifequal";
|
||||||
|
func = [](float a, float b) { return a == b; };
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.value) {
|
if (value && other.value) {
|
||||||
/* Getting sum of elements via dot product with 1.0f and comparing to 0.0f */
|
res = func(value->asA<float>(), other.value->asA<float>()) ? val1 : val2;
|
||||||
res = res.dot(val(1.0f)).value->asA<float>() == 0.0f ? else_val : if_val;
|
|
||||||
}
|
}
|
||||||
else if (res.node) {
|
else {
|
||||||
res.set_input("value1", if_val);
|
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, t);
|
||||||
res.set_input("value2", else_val);
|
res.set_input("value1", *this);
|
||||||
|
res.set_input("value2", other);
|
||||||
|
res.set_input("in1", val1);
|
||||||
|
res.set_input("in2", val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,24 +461,12 @@ NodeItem NodeItem::arithmetic(const NodeItem &other,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string t1 = type();
|
std::string t;
|
||||||
std::string t2 = other.type();
|
|
||||||
|
|
||||||
if (value && other.value) {
|
if (value && other.value) {
|
||||||
std::string t = t1;
|
|
||||||
auto val1 = value;
|
auto val1 = value;
|
||||||
auto val2 = other.value;
|
auto val2 = other.value;
|
||||||
if (t1 != t2) {
|
if (!adjust_types(val1, val2, t)) {
|
||||||
if (t1 == "float") {
|
return res;
|
||||||
val1 = float_to_type(val1->asA<float>(), t2);
|
|
||||||
t = t2;
|
|
||||||
}
|
|
||||||
else if (t2 == "float") {
|
|
||||||
val2 = float_to_type(val2->asA<float>(), t1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t == "float") {
|
if (t == "float") {
|
||||||
@ -482,20 +509,10 @@ NodeItem NodeItem::arithmetic(const NodeItem &other,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::string t = t1;
|
|
||||||
auto val1 = *this;
|
auto val1 = *this;
|
||||||
auto val2 = other;
|
auto val2 = other;
|
||||||
if (t1 != t2) {
|
if (!adjust_types(val1, val2, t)) {
|
||||||
if (val1.value && t1 == "float") {
|
return res;
|
||||||
val1.value = float_to_type(val1.value->asA<float>(), t2);
|
|
||||||
t = t2;
|
|
||||||
}
|
|
||||||
else if (val2.value && t2 == "float") {
|
|
||||||
val2.value = float_to_type(val2.value->asA<float>(), t1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, t);
|
res.node = graph_->addNode(mx_category, MaterialX::EMPTY_STRING, t);
|
||||||
@ -505,7 +522,7 @@ NodeItem NodeItem::arithmetic(const NodeItem &other,
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialX::ValuePtr NodeItem::float_to_type(float v, std::string t) const
|
MaterialX::ValuePtr NodeItem::float_to_type(float v, std::string t)
|
||||||
{
|
{
|
||||||
if (t == "float") {
|
if (t == "float") {
|
||||||
return MaterialX::Value::createValue<float>(v);
|
return MaterialX::Value::createValue<float>(v);
|
||||||
@ -530,4 +547,50 @@ MaterialX::ValuePtr NodeItem::float_to_type(float v, std::string t) const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NodeItem::adjust_types(MaterialX::ValuePtr &val1, MaterialX::ValuePtr &val2, std::string &t)
|
||||||
|
{
|
||||||
|
std::string t1 = val1->getTypeString();
|
||||||
|
std::string t2 = val2->getTypeString();
|
||||||
|
if (t1 != t2) {
|
||||||
|
if (t1 == "float") {
|
||||||
|
val1 = float_to_type(val1->asA<float>(), t2);
|
||||||
|
t = t2;
|
||||||
|
}
|
||||||
|
else if (t2 == "float") {
|
||||||
|
val2 = float_to_type(val2->asA<float>(), t1);
|
||||||
|
t = t1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
t = t1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NodeItem::adjust_types(NodeItem &val1, NodeItem &val2, std::string &t)
|
||||||
|
{
|
||||||
|
std::string t1 = val1.type();
|
||||||
|
std::string t2 = val2.type();
|
||||||
|
if (t1 != t2) {
|
||||||
|
if (val1.value && t1 == "float") {
|
||||||
|
val1.value = float_to_type(val1.value->asA<float>(), t2);
|
||||||
|
t = t2;
|
||||||
|
}
|
||||||
|
else if (val2.value && t2 == "float") {
|
||||||
|
val2.value = float_to_type(val2.value->asA<float>(), t1);
|
||||||
|
t = t2;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
t = t1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::nodes::materialx
|
} // namespace blender::nodes::materialx
|
||||||
|
@ -77,7 +77,9 @@ class NodeItem {
|
|||||||
NodeItem arithmetic(const NodeItem &other,
|
NodeItem arithmetic(const NodeItem &other,
|
||||||
const std::string &mx_category,
|
const std::string &mx_category,
|
||||||
std::function<float(float, float)> func) const;
|
std::function<float(float, float)> func) const;
|
||||||
MaterialX::ValuePtr float_to_type(float v, std::string t) const;
|
static MaterialX::ValuePtr float_to_type(float v, std::string t);
|
||||||
|
static bool adjust_types(MaterialX::ValuePtr &val1, MaterialX::ValuePtr &val2, std::string &t);
|
||||||
|
static bool adjust_types(NodeItem &val1, NodeItem &val2, std::string &t);
|
||||||
};
|
};
|
||||||
|
|
||||||
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