1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #include <cmath>
18 
19 #include "BLI_listbase.h"
20 #include "BLI_string.h"
21 
22 #include "RNA_enum_types.h"
23 
24 #include "node_function_util.hh"
25 
26 static bNodeSocketTemplate fn_node_float_compare_in[] = {
27     {SOCK_FLOAT, N_("A"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
28     {SOCK_FLOAT, N_("B"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
29     {SOCK_FLOAT, N_("Epsilon"), 0.001f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
30     {-1, ""},
31 };
32 
33 static bNodeSocketTemplate fn_node_float_compare_out[] = {
34     {SOCK_BOOLEAN, N_("Result")},
35     {-1, ""},
36 };
37 
node_float_compare_update(bNodeTree * UNUSED (ntree),bNode * node)38 static void node_float_compare_update(bNodeTree *UNUSED(ntree), bNode *node)
39 {
40   bNodeSocket *sockEpsilon = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
41 
42   nodeSetSocketAvailability(
43       sockEpsilon, ELEM(node->custom1, NODE_FLOAT_COMPARE_EQUAL, NODE_FLOAT_COMPARE_NOT_EQUAL));
44 }
45 
node_float_compare_label(bNodeTree * UNUSED (ntree),bNode * node,char * label,int maxlen)46 static void node_float_compare_label(bNodeTree *UNUSED(ntree),
47                                      bNode *node,
48                                      char *label,
49                                      int maxlen)
50 {
51   const char *name;
52   bool enum_label = RNA_enum_name(rna_enum_node_float_compare_items, node->custom1, &name);
53   if (!enum_label) {
54     name = "Unknown";
55   }
56   BLI_strncpy(label, IFACE_(name), maxlen);
57 }
58 
get_multi_function(bNode & node)59 static const blender::fn::MultiFunction &get_multi_function(bNode &node)
60 {
61   static blender::fn::CustomMF_SI_SI_SO<float, float, bool> less_than_fn{
62       "Less Than", [](float a, float b) { return a < b; }};
63   static blender::fn::CustomMF_SI_SI_SO<float, float, bool> less_equal_fn{
64       "Less Equal", [](float a, float b) { return a <= b; }};
65   static blender::fn::CustomMF_SI_SI_SO<float, float, bool> greater_than_fn{
66       "Greater Than", [](float a, float b) { return a > b; }};
67   static blender::fn::CustomMF_SI_SI_SO<float, float, bool> greater_equal_fn{
68       "Greater Equal", [](float a, float b) { return a >= b; }};
69   static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, bool> equal_fn{
70       "Equal", [](float a, float b, float epsilon) { return std::abs(a - b) <= epsilon; }};
71   static blender::fn::CustomMF_SI_SI_SI_SO<float, float, float, bool> not_equal_fn{
72       "Not Equal", [](float a, float b, float epsilon) { return std::abs(a - b) > epsilon; }};
73 
74   switch (node.custom1) {
75     case NODE_FLOAT_COMPARE_LESS_THAN:
76       return less_than_fn;
77     case NODE_FLOAT_COMPARE_LESS_EQUAL:
78       return less_equal_fn;
79     case NODE_FLOAT_COMPARE_GREATER_THAN:
80       return greater_than_fn;
81     case NODE_FLOAT_COMPARE_GREATER_EQUAL:
82       return greater_equal_fn;
83     case NODE_FLOAT_COMPARE_EQUAL:
84       return equal_fn;
85     case NODE_FLOAT_COMPARE_NOT_EQUAL:
86       return not_equal_fn;
87   }
88 
89   BLI_assert(false);
90   return blender::fn::dummy_multi_function;
91 }
92 
node_float_compare_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder & builder)93 static void node_float_compare_expand_in_mf_network(blender::nodes::NodeMFNetworkBuilder &builder)
94 {
95   const blender::fn::MultiFunction &fn = get_multi_function(builder.bnode());
96   builder.set_matching_fn(fn);
97 }
98 
register_node_type_fn_float_compare()99 void register_node_type_fn_float_compare()
100 {
101   static bNodeType ntype;
102 
103   fn_node_type_base(&ntype, FN_NODE_FLOAT_COMPARE, "Boolean Math", 0, 0);
104   node_type_socket_templates(&ntype, fn_node_float_compare_in, fn_node_float_compare_out);
105   node_type_label(&ntype, node_float_compare_label);
106   node_type_update(&ntype, node_float_compare_update);
107   ntype.expand_in_mf_network = node_float_compare_expand_in_mf_network;
108   nodeRegisterType(&ntype);
109 }
110