diff options
Diffstat (limited to 'source/blender/editors/util/select_buffer_utils.c')
-rw-r--r-- | source/blender/editors/util/select_buffer_utils.c | 303 |
1 files changed, 0 insertions, 303 deletions
diff --git a/source/blender/editors/util/select_buffer_utils.c b/source/blender/editors/util/select_buffer_utils.c deleted file mode 100644 index 79f0f48830e..00000000000 --- a/source/blender/editors/util/select_buffer_utils.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - */ - -/** \file - * \ingroup edutil - * - * Generic utilities for handling buffer selection where selection ID's are drawn onto - * an off screen buffer. - * - * All coordinates are relative to the current region. - */ - -#include "MEM_guardedalloc.h" - -#include "BLI_bitmap.h" -#include "BLI_bitmap_draw_2d.h" -#include "BLI_rect.h" -#include "BLI_utildefines.h" - -#include "ED_select_buffer_utils.h" - -/* Only for #ED_view3d_select_id_read, - * note that this file shouldn't have 3D view specific logic in it, we could have a more general - * way to read from selection buffers that doesn't depend on the view3d API. */ -#include "ED_view3d.h" - -/* -------------------------------------------------------------------- */ -/** \name Select Bitmap from ID's - * - * Given a buffer of select ID's, fill in a booleans (true/false) per index. - * #BLI_bitmap is used for memory efficiency. - * - * \{ */ - -/** - * \param bitmap_len: Number of indices in the selection id buffer. - * \param rect: The rectangle to sample indices from (min/max inclusive). - * \returns a #BLI_bitmap the length of \a bitmap_len or NULL on failure. - */ -uint *ED_select_buffer_bitmap_from_rect(const uint bitmap_len, const rcti *rect) -{ - uint buf_len; - const uint *buf = ED_view3d_select_id_read( - rect->xmin, rect->ymin, rect->xmax, rect->ymax, &buf_len); - if (buf == NULL) { - return NULL; - } - - const uint *buf_iter = buf; - - BLI_bitmap *bitmap_buf = BLI_BITMAP_NEW(bitmap_len, __func__); - - while (buf_len--) { - const uint index = *buf_iter - 1; - if (index < bitmap_len) { - BLI_BITMAP_ENABLE(bitmap_buf, index); - } - buf_iter++; - } - MEM_freeN((void *)buf); - return bitmap_buf; -} - -/** - * \param bitmap_len: Number of indices in the selection id buffer. - * \param center: Circle center. - * \param radius: Circle radius. - * \returns a #BLI_bitmap the length of \a bitmap_len or NULL on failure. - */ -uint *ED_select_buffer_bitmap_from_circle(const uint bitmap_len, - const int center[2], - const int radius) -{ - if (bitmap_len == 0) { - return NULL; - } - - const int xmin = center[0] - radius; - const int xmax = center[0] + radius; - const int ymin = center[1] - radius; - const int ymax = center[1] + radius; - - const uint *buf = ED_view3d_select_id_read(xmin, ymin, xmax, ymax, NULL); - if (buf == NULL) { - return NULL; - } - - const uint *buf_iter = buf; - - BLI_bitmap *bitmap_buf = BLI_BITMAP_NEW(bitmap_len, __func__); - const int radius_sq = radius * radius; - for (int yc = -radius; yc <= radius; yc++) { - for (int xc = -radius; xc <= radius; xc++, buf_iter++) { - if (xc * xc + yc * yc < radius_sq) { - /* Intentionally wrap to max value if this is zero. */ - const uint index = *buf_iter - 1; - if (index < bitmap_len) { - BLI_BITMAP_ENABLE(bitmap_buf, index); - } - } - } - } - MEM_freeN((void *)buf); - return bitmap_buf; -} - -struct PolyMaskData { - BLI_bitmap *px; - int width; -}; - -static void ed_select_buffer_mask_px_cb(int x, int x_end, int y, void *user_data) -{ - struct PolyMaskData *data = user_data; - BLI_bitmap *px = data->px; - int i = (y * data->width) + x; - do { - BLI_BITMAP_ENABLE(px, i); - i++; - } while (++x != x_end); -} - -/** - * \param bitmap_len: Number of indices in the selection id buffer. - * \param center: Circle center. - * \param radius: Circle radius. - * \returns a #BLI_bitmap the length of \a bitmap_len or NULL on failure. - */ -uint *ED_select_buffer_bitmap_from_poly(const uint bitmap_len, - const int poly[][2], - const int poly_len, - const rcti *rect) - -{ - if (bitmap_len == 0) { - return NULL; - } - - struct PolyMaskData poly_mask_data; - uint buf_len; - const uint *buf = ED_view3d_select_id_read( - rect->xmin, rect->ymin, rect->xmax, rect->ymax, &buf_len); - if (buf == NULL) { - return NULL; - } - - BLI_bitmap *buf_mask = BLI_BITMAP_NEW(buf_len, __func__); - poly_mask_data.px = buf_mask; - poly_mask_data.width = (rect->xmax - rect->xmin) + 1; - - BLI_bitmap_draw_2d_poly_v2i_n(rect->xmin, - rect->ymin, - rect->xmax + 1, - rect->ymax + 1, - poly, - poly_len, - ed_select_buffer_mask_px_cb, - &poly_mask_data); - - /* Build selection lookup. */ - const uint *buf_iter = buf; - BLI_bitmap *bitmap_buf = BLI_BITMAP_NEW(bitmap_len, __func__); - int i = 0; - while (buf_len--) { - const uint index = *buf_iter - 1; - if (index < bitmap_len && BLI_BITMAP_TEST(buf_mask, i)) { - BLI_BITMAP_ENABLE(bitmap_buf, index); - } - buf_iter++; - i++; - } - MEM_freeN((void *)buf); - MEM_freeN(buf_mask); - - return bitmap_buf; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Find Single Select ID's - * - * Given a buffer of select ID's, find the a single select id. - * - * \{ */ - -/** - * Samples a single pixel. - */ -uint ED_select_buffer_sample_point(const int center[2]) -{ - uint buf_len; - uint *buf = ED_view3d_select_id_read(center[0], center[1], center[0], center[1], &buf_len); - BLI_assert(0 != buf_len); - uint ret = buf[0]; - MEM_freeN(buf); - return ret; -} - -/** - * Find the selection id closest to \a center. - * \param dist[in,out]: Use to initialize the distance, - * when found, this value is set to the distance of the selection thats returned. - */ -uint ED_select_buffer_find_nearest_to_point(const int center[2], - const uint id_min, - 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. */ - rcti rect; - BLI_rcti_init_pt_radius(&rect, center, *dist); - rect.xmax += 1; - rect.ymax += 1; - - int width = BLI_rcti_size_x(&rect); - int height = width; - BLI_assert(width == height); - - /* Read from selection framebuffer. */ - - uint buf_len; - const uint *buf = ED_view3d_select_id_read_rect(&rect, &buf_len); - 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; - - uint index = 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; - - /* Manhatten 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; - } - } - -exit: - MEM_freeN((void *)buf); - return index; -} - -/** \} */ |