Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGermano Cavalcante <germano.costa@ig.com.br>2021-03-09 22:02:40 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2021-03-09 22:03:56 +0300
commitcfd7b4d1cd48ecffbf61d45dfa4f24ccda3d6a71 (patch)
treed15eba83bd4baae7853a69c4dbe178fead669769 /source/blender/draw
parent80f7f1070f177ae543f2fa35dd5d458e87ff30c1 (diff)
BLI: New 'BLI_array_iter_spiral_square'
No functional changes. This function replaces some of the logic in `DRW_select_buffer_find_nearest_to_point` that traverses a buffer in a spiral way to search for a closer pixel (not the closest). Differential Revision: https://developer.blender.org/D10548
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/intern/draw_select_buffer.c92
1 files changed, 33 insertions, 59 deletions
diff --git a/source/blender/draw/intern/draw_select_buffer.c b/source/blender/draw/intern/draw_select_buffer.c
index b5151293c1b..d7438b7e0f0 100644
--- a/source/blender/draw/intern/draw_select_buffer.c
+++ b/source/blender/draw/intern/draw_select_buffer.c
@@ -24,6 +24,7 @@
#include "MEM_guardedalloc.h"
+#include "BLI_array_utils.h"
#include "BLI_bitmap.h"
#include "BLI_bitmap_draw_2d.h"
#include "BLI_rect.h"
@@ -336,6 +337,26 @@ uint DRW_select_buffer_sample_point(struct Depsgraph *depsgraph,
return ret;
}
+struct SelectReadData {
+ const void *val_ptr;
+ uint id_min;
+ uint id_max;
+ uint r_index;
+};
+
+static bool select_buffer_test_fn(const void *__restrict value, void *__restrict userdata)
+{
+ struct SelectReadData *data = userdata;
+ uint hit_id = *(uint *)value;
+ if (hit_id && hit_id >= data->id_min && hit_id < data->id_max) {
+ /* Start at 1 to confirm. */
+ data->val_ptr = value;
+ data->r_index = (hit_id - data->id_min) + 1;
+ return true;
+ }
+ return false;
+}
+
/**
* Find the selection id closest to \a center.
* \param dist: Use to initialize the distance,
@@ -349,13 +370,8 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph,
const uint id_max,
uint *dist)
{
- /* Smart function to sample a rect spiraling outside, nice for selection ID. */
-
/* Create region around center (typically the mouse cursor).
- * This must be square and have an odd width,
- * the spiraling algorithm does not work with arbitrary rectangles. */
-
- uint index = 0;
+ * This must be square and have an odd width. */
rcti rect;
BLI_rcti_init_pt_radius(&rect, center, *dist);
@@ -364,7 +380,6 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph,
int width = BLI_rcti_size_x(&rect);
int height = width;
- BLI_assert(width == height);
/* Read from selection framebuffer. */
@@ -372,64 +387,23 @@ uint DRW_select_buffer_find_nearest_to_point(struct Depsgraph *depsgraph,
const uint *buf = DRW_select_buffer_read(depsgraph, region, v3d, &rect, &buf_len);
if (buf == NULL) {
- return index;
+ return 0;
}
- BLI_assert(width * height == buf_len);
-
- /* Spiral, starting from center of buffer. */
- int spiral_offset = height * (int)(width / 2) + (height / 2);
- int spiral_direction = 0;
-
- for (int nr = 1; nr <= height; nr++) {
- for (int a = 0; a < 2; a++) {
- for (int b = 0; b < nr; b++) {
- /* Find hit within the specified range. */
- uint hit_id = buf[spiral_offset];
-
- if (hit_id && hit_id >= id_min && hit_id < id_max) {
- /* Get x/y from spiral offset. */
- int hit_x = spiral_offset % width;
- int hit_y = spiral_offset / width;
-
- int center_x = width / 2;
- int center_y = height / 2;
+ const int shape[2] = {height, width};
+ const int center_yx[2] = {(height - 1) / 2, (width - 1) / 2};
+ struct SelectReadData data = {NULL, id_min, id_max, 0};
+ BLI_array_iter_spiral_square(buf, shape, center_yx, select_buffer_test_fn, &data);
- /* Manhattan distance in keeping with other screen-based selection. */
- *dist = (uint)(abs(hit_x - center_x) + abs(hit_y - center_y));
-
- /* Indices start at 1 here. */
- index = (hit_id - id_min) + 1;
- goto exit;
- }
-
- /* Next spiral step. */
- if (spiral_direction == 0) {
- spiral_offset += 1; /* right */
- }
- else if (spiral_direction == 1) {
- spiral_offset -= width; /* down */
- }
- else if (spiral_direction == 2) {
- spiral_offset -= 1; /* left */
- }
- else {
- spiral_offset += width; /* up */
- }
-
- /* Stop if we are outside the buffer. */
- if (spiral_offset < 0 || spiral_offset >= buf_len) {
- goto exit;
- }
- }
-
- spiral_direction = (spiral_direction + 1) % 4;
- }
+ if (data.val_ptr) {
+ size_t offset = ((size_t)data.val_ptr - (size_t)buf) / sizeof(*buf);
+ int hit_x = offset % width;
+ int hit_y = offset / width;
+ *dist = (uint)(abs(hit_y - center_yx[0]) + abs(hit_x - center_yx[1]));
}
-exit:
MEM_freeN((void *)buf);
- return index;
+ return data.r_index;
}
/** \} */