Blender  V2.93
select_utils.c
Go to the documentation of this file.
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 
21 #include "BLI_kdtree.h"
22 #include "BLI_math.h"
23 #include "BLI_utildefines.h"
24 
25 #include "ED_select_utils.h"
26 
27 #include "float.h"
28 
30 int ED_select_op_action(const eSelectOp sel_op, const bool is_select, const bool is_inside)
31 {
32  switch (sel_op) {
33  case SEL_OP_ADD:
34  return (!is_select && (is_inside)) ? 1 : -1;
35  case SEL_OP_SUB:
36  return (is_select && is_inside) ? 0 : -1;
37  case SEL_OP_SET:
38  return is_inside ? 1 : 0;
39  case SEL_OP_AND:
40  return (is_select && is_inside) ? -1 : (is_select ? 0 : -1);
41  case SEL_OP_XOR:
42  return (is_select && is_inside) ? 0 : ((!is_select && is_inside) ? 1 : -1);
43  }
44  BLI_assert(!"invalid sel_op");
45  return -1;
46 }
54  const bool is_select,
55  const bool is_inside)
56 {
57  switch (sel_op) {
58  case SEL_OP_ADD:
59  return (!is_select && is_inside) ? 1 : -1;
60  case SEL_OP_SUB:
61  return (is_select && is_inside) ? 0 : -1;
62  case SEL_OP_SET:
63  /* Only difference w/ function above. */
64  return is_inside ? 1 : -1;
65  case SEL_OP_AND:
66  return (is_select && is_inside) ? -1 : (is_select ? 0 : -1);
67  case SEL_OP_XOR:
68  return (is_select && is_inside) ? 0 : ((!is_select && is_inside) ? 1 : -1);
69  }
70  BLI_assert(!"invalid sel_op");
71  return -1;
72 }
73 
77 eSelectOp ED_select_op_modal(const eSelectOp sel_op, const bool is_first)
78 {
79  if (sel_op == SEL_OP_SET) {
80  if (is_first == false) {
81  return SEL_OP_ADD;
82  }
83  }
84  return sel_op;
85 }
86 
87 int ED_select_similar_compare_float(const float delta, const float thresh, const int compare)
88 {
89  switch (compare) {
90  case SIM_CMP_EQ:
91  return (fabsf(delta) <= thresh);
92  case SIM_CMP_GT:
93  return ((delta + thresh) >= 0.0);
94  case SIM_CMP_LT:
95  return ((delta - thresh) <= 0.0);
96  default:
98  return 0;
99  }
100 }
101 
103  const float length,
104  const float thresh,
105  const int compare)
106 {
107  /* Length of the edge we want to compare against. */
108  float nearest_edge_length;
109 
110  switch (compare) {
111  case SIM_CMP_EQ:
112  /* Compare to the edge closest to the current edge. */
113  nearest_edge_length = length;
114  break;
115  case SIM_CMP_GT:
116  /* Compare against the shortest edge. */
117  /* -FLT_MAX leads to some precision issues and the wrong edge being selected.
118  * For example, in a tree with 1, 2 and 3, which is stored squared as 1, 4, 9,
119  * it returns as the nearest length/node the "4" instead of "1". */
120  nearest_edge_length = -1.0f;
121  break;
122  case SIM_CMP_LT:
123  /* Compare against the longest edge. */
124  nearest_edge_length = FLT_MAX;
125  break;
126  default:
128  return false;
129  }
130 
131  KDTreeNearest_1d nearest;
132  if (BLI_kdtree_1d_find_nearest(tree, &nearest_edge_length, &nearest) != -1) {
133  float delta = length - nearest.co[0];
134  return ED_select_similar_compare_float(delta, thresh, compare);
135  }
136 
137  return false;
138 }
#define BLI_assert_unreachable()
Definition: BLI_assert.h:96
#define BLI_assert(a)
Definition: BLI_assert.h:58
A kd-tree for nearest neighbor search.
@ SIM_CMP_LT
@ SIM_CMP_GT
@ SIM_CMP_EQ
eSelectOp
@ SEL_OP_ADD
@ SEL_OP_SUB
@ SEL_OP_SET
@ SEL_OP_AND
@ SEL_OP_XOR
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
void * tree
static bool is_inside(int x, int y, int cols, int rows)
Definition: filesel.c:663
#define fabsf(x)
int ED_select_similar_compare_float(const float delta, const float thresh, const int compare)
Definition: select_utils.c:87
int ED_select_op_action(const eSelectOp sel_op, const bool is_select, const bool is_inside)
Definition: select_utils.c:30
eSelectOp ED_select_op_modal(const eSelectOp sel_op, const bool is_first)
Definition: select_utils.c:77
int ED_select_op_action_deselected(const eSelectOp sel_op, const bool is_select, const bool is_inside)
Definition: select_utils.c:53
bool ED_select_similar_compare_float_tree(const KDTree_1d *tree, const float length, const float thresh, const int compare)
Definition: select_utils.c:102