diff options
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_select_buffer_utils.h | 43 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 10 | ||||
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 11 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_utils.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw_legacy.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 35 | ||||
-rw-r--r-- | source/blender/editors/util/CMakeLists.txt | 3 | ||||
-rw-r--r-- | source/blender/editors/util/select_buffer_utils.c | 345 |
9 files changed, 34 insertions, 420 deletions
diff --git a/source/blender/editors/include/ED_select_buffer_utils.h b/source/blender/editors/include/ED_select_buffer_utils.h deleted file mode 100644 index 1b55de30d96..00000000000 --- a/source/blender/editors/include/ED_select_buffer_utils.h +++ /dev/null @@ -1,43 +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. - */ - -/** \file - * \ingroup editors - */ - -#ifndef __ED_SELECT_BUFFER_UTILS_H__ -#define __ED_SELECT_BUFFER_UTILS_H__ - -struct rcti; - -/* Boolean array from selection ID's. */ -uint *ED_select_buffer_bitmap_from_rect(const struct rcti *rect, uint *r_bitmap_len); -uint *ED_select_buffer_bitmap_from_circle(const int center[2], - const int radius, - uint *r_bitmap_len); -uint *ED_select_buffer_bitmap_from_poly(const int poly[][2], - const int poly_len, - const rcti *rect, - uint *r_bitmap_len); - -/* Single result from selection ID's. */ -uint ED_select_buffer_sample_point(const int center[2]); -uint ED_select_buffer_find_nearest_to_point(const int center[2], - const uint id_min, - const uint id_max, - uint *dist); - -#endif /* __ED_SELECT_BUFFER_UTILS_H__ */ diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 844811390ea..2f4688e2de7 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -53,7 +53,6 @@ #include "ED_mesh.h" #include "ED_screen.h" #include "ED_transform.h" -#include "ED_select_buffer_utils.h" #include "ED_select_utils.h" #include "ED_view3d.h" @@ -69,6 +68,7 @@ #include "DEG_depsgraph_query.h" #include "DRW_engine.h" +#include "DRW_select_buffer.h" #include "mesh_intern.h" /* own include */ @@ -203,7 +203,7 @@ static BMElem *edbm_select_id_bm_elem_get(Base **bases, const uint sel_id, uint { uint elem_id; char elem_type = 0; - bool success = DRW_select_elem_get(sel_id, &elem_id, r_base_index, &elem_type); + bool success = DRW_select_buffer_elem_get(sel_id, &elem_id, r_base_index, &elem_type); if (success) { Object *obedit = bases[*r_base_index]->object; @@ -319,7 +319,7 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc, { DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, SCE_SELECT_VERTEX); - index = ED_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px); + index = DRW_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px); if (index) { eve = (BMVert *)edbm_select_id_bm_elem_get(bases, index, &base_index); @@ -541,7 +541,7 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc, { DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, SCE_SELECT_EDGE); - index = ED_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px); + index = DRW_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px); if (index) { eed = (BMEdge *)edbm_select_id_bm_elem_get(bases, index, &base_index); @@ -747,7 +747,7 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc, { DRW_draw_select_id(vc->depsgraph, vc->ar, vc->v3d, bases, bases_len, SCE_SELECT_FACE); - index = ED_select_buffer_sample_point(vc->mval); + index = DRW_select_buffer_sample_point(vc->mval); if (index) { efa = (BMFace *)edbm_select_id_bm_elem_get(bases, index, &base_index); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index b082af352b2..0bdc59c7185 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -60,8 +60,9 @@ #include "DEG_depsgraph_build.h" #include "DEG_depsgraph_query.h" +#include "DRW_select_buffer.h" + #include "ED_mesh.h" -#include "ED_select_buffer_utils.h" #include "ED_object.h" #include "ED_view3d.h" @@ -1115,11 +1116,11 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], uint dist_px, if (dist_px) { /* sample rect to increase chances of selecting, so that when clicking * on an edge in the backbuf, we can still select a face */ - *r_index = ED_select_buffer_find_nearest_to_point(mval, 1, me->totpoly + 1, &dist_px); + *r_index = DRW_select_buffer_find_nearest_to_point(mval, 1, me->totpoly + 1, &dist_px); } else { /* sample only on the exact position */ - *r_index = ED_select_buffer_sample_point(mval); + *r_index = DRW_select_buffer_sample_point(mval); } if ((*r_index) == 0 || (*r_index) > (unsigned int)me->totpoly) { @@ -1296,11 +1297,11 @@ bool ED_mesh_pick_vert( if (dist_px > 0) { /* sample rect to increase chances of selecting, so that when clicking * on an face in the backbuf, we can still select a vert */ - *r_index = ED_select_buffer_find_nearest_to_point(mval, 1, me->totvert + 1, &dist_px); + *r_index = DRW_select_buffer_find_nearest_to_point(mval, 1, me->totvert + 1, &dist_px); } else { /* sample only on the exact position */ - *r_index = ED_select_buffer_sample_point(mval); + *r_index = DRW_select_buffer_sample_point(mval); } if ((*r_index) == 0 || (*r_index) > (uint)me->totvert) { diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index 2a8ff9d4f78..752a5c36010 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -23,6 +23,7 @@ set(INC ../../blentranslation ../../bmesh ../../depsgraph + ../../draw ../../gpu ../../imbuf ../../makesdna diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 0f37968f599..806b7c471c6 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -71,7 +71,8 @@ #include "BLI_sys_types.h" #include "ED_mesh.h" /* for face mask functions */ -#include "ED_select_buffer_utils.h" + +#include "DRW_select_buffer.h" #include "WM_api.h" #include "WM_types.h" @@ -391,7 +392,7 @@ static int imapaint_pick_face(ViewContext *vc, /* sample only on the exact position */ ED_view3d_select_id_validate(vc); - *r_index = ED_select_buffer_sample_point(mval); + *r_index = DRW_select_buffer_sample_point(mval); if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) { return 0; diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c index 307d2a1a41b..040b257bb90 100644 --- a/source/blender/editors/space_view3d/view3d_draw_legacy.c +++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c @@ -102,6 +102,7 @@ #include "RE_engine.h" #include "DRW_engine.h" +#include "DRW_select_buffer.h" #include "view3d_intern.h" /* own include */ diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 39684cb6986..d20a854c022 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -89,7 +89,6 @@ #include "ED_mesh.h" #include "ED_object.h" #include "ED_screen.h" -#include "ED_select_buffer_utils.h" #include "ED_select_utils.h" #include "ED_sculpt.h" #include "ED_mball.h" @@ -105,6 +104,7 @@ #include "DEG_depsgraph_query.h" #include "DRW_engine.h" +#include "DRW_select_buffer.h" #include "view3d_intern.h" /* own include */ @@ -269,7 +269,8 @@ static bool edbm_backbuf_check_and_select_verts(struct EditSelectBuf_Cache *esel bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - uint index = DRW_select_context_offset_for_object_elem(ob->runtime.select_id, SCE_SELECT_VERTEX); + uint index = DRW_select_buffer_context_offset_for_object_elem(ob->runtime.select_id, + SCE_SELECT_VERTEX); BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { @@ -296,7 +297,8 @@ static bool edbm_backbuf_check_and_select_edges(struct EditSelectBuf_Cache *esel bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - uint index = DRW_select_context_offset_for_object_elem(ob->runtime.select_id, SCE_SELECT_EDGE); + uint index = DRW_select_buffer_context_offset_for_object_elem(ob->runtime.select_id, + SCE_SELECT_EDGE); BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { @@ -323,7 +325,8 @@ static bool edbm_backbuf_check_and_select_faces(struct EditSelectBuf_Cache *esel bool changed = false; const BLI_bitmap *select_bitmap = esel->select_bitmap; - uint index = DRW_select_context_offset_for_object_elem(ob->runtime.select_id, SCE_SELECT_FACE); + uint index = DRW_select_buffer_context_offset_for_object_elem(ob->runtime.select_id, + SCE_SELECT_FACE); BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { @@ -828,7 +831,7 @@ static bool do_lasso_select_mesh(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, ts->selectmode); esel = wm_userdata->data; - esel->select_bitmap = ED_select_buffer_bitmap_from_poly(mcords, moves, &rect, NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_poly(mcords, moves, &rect); } } @@ -846,7 +849,7 @@ static bool do_lasso_select_mesh(ViewContext *vc, struct LassoSelectUserData_ForMeshEdge data_for_edge = { .data = &data, .esel = use_zbuf ? esel : NULL, - .backbuf_offset = use_zbuf ? DRW_select_context_offset_for_object_elem( + .backbuf_offset = use_zbuf ? DRW_select_buffer_context_offset_for_object_elem( vc->obedit->runtime.select_id, SCE_SELECT_EDGE) : 0, }; @@ -1138,8 +1141,7 @@ static bool do_lasso_select_paintvert(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, SCE_SELECT_VERTEX); esel = wm_userdata->data; - const uint buffer_len = DRW_select_context_elem_len(); - esel->select_bitmap = ED_select_buffer_bitmap_from_poly(mcords, moves, &rect, NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_poly(mcords, moves, &rect); } } @@ -1197,8 +1199,7 @@ static bool do_lasso_select_paintface(ViewContext *vc, if (esel == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, SCE_SELECT_FACE); esel = wm_userdata->data; - const uint buffer_len = DRW_select_context_elem_len(); - esel->select_bitmap = ED_select_buffer_bitmap_from_poly(mcords, moves, &rect, NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_poly(mcords, moves, &rect); } if (esel->select_bitmap) { @@ -2553,7 +2554,7 @@ static bool do_paintvert_box_select(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, SCE_SELECT_VERTEX); esel = wm_userdata->data; - esel->select_bitmap = ED_select_buffer_bitmap_from_rect(rect, NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_rect(rect, NULL); } if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op); @@ -2607,7 +2608,7 @@ static bool do_paintface_box_select(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, SCE_SELECT_FACE); esel = wm_userdata->data; - esel->select_bitmap = ED_select_buffer_bitmap_from_rect(rect, NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_rect(rect, NULL); } if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op); @@ -2804,7 +2805,7 @@ static bool do_mesh_box_select(ViewContext *vc, if (wm_userdata->data == NULL) { editselect_buf_cache_init_with_generic_userdata(wm_userdata, vc, ts->selectmode); esel = wm_userdata->data; - esel->select_bitmap = ED_select_buffer_bitmap_from_rect(rect, NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_rect(rect, NULL); } } @@ -2822,7 +2823,7 @@ static bool do_mesh_box_select(ViewContext *vc, struct BoxSelectUserData_ForMeshEdge cb_data = { .data = &data, .esel = use_zbuf ? esel : NULL, - .backbuf_offset = use_zbuf ? DRW_select_context_offset_for_object_elem( + .backbuf_offset = use_zbuf ? DRW_select_buffer_context_offset_for_object_elem( vc->obedit->runtime.select_id, SCE_SELECT_EDGE) : 0, }; @@ -3391,7 +3392,7 @@ static bool mesh_circle_select(ViewContext *vc, struct EditSelectBuf_Cache *esel = wm_userdata->data; if (use_zbuf) { - esel->select_bitmap = ED_select_buffer_bitmap_from_circle(mval, (int)(rad + 1.0f), NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_circle(mval, (int)(rad + 1.0f), NULL); } if (ts->selectmode & SCE_SELECT_VERTEX) { @@ -3468,7 +3469,7 @@ static bool paint_facesel_circle_select(ViewContext *vc, { struct EditSelectBuf_Cache *esel = wm_userdata->data; - esel->select_bitmap = ED_select_buffer_bitmap_from_circle(mval, (int)(rad + 1.0f), NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_circle(mval, (int)(rad + 1.0f), NULL); if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_faces_obmode(me, esel, sel_op); MEM_freeN(esel->select_bitmap); @@ -3522,7 +3523,7 @@ static bool paint_vertsel_circle_select(ViewContext *vc, if (use_zbuf) { struct EditSelectBuf_Cache *esel = wm_userdata->data; - esel->select_bitmap = ED_select_buffer_bitmap_from_circle(mval, (int)(rad + 1.0f), NULL); + esel->select_bitmap = DRW_select_buffer_bitmap_from_circle(mval, (int)(rad + 1.0f), NULL); if (esel->select_bitmap != NULL) { changed |= edbm_backbuf_check_and_select_verts_obmode(me, esel, sel_op); MEM_freeN(esel->select_bitmap); diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index 23464e9985a..0564cb07897 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -22,7 +22,6 @@ set(INC ../../blentranslation ../../bmesh ../../depsgraph - ../../draw ../../gpu ../../imbuf ../../makesdna @@ -42,7 +41,6 @@ set(SRC ed_util.c gizmo_utils.c numinput.c - select_buffer_utils.c select_utils.c # general includes @@ -81,7 +79,6 @@ set(SRC ../include/ED_screen.h ../include/ED_screen_types.h ../include/ED_sculpt.h - ../include/ED_select_buffer_utils.h ../include/ED_select_utils.h ../include/ED_sequencer.h ../include/ED_sound.h 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 df5864d3dd1..00000000000 --- a/source/blender/editors/util/select_buffer_utils.c +++ /dev/null @@ -1,345 +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 "DRW_engine.h" - -#include "ED_select_buffer_utils.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 rcti *rect, uint *r_bitmap_len) -{ - const uint bitmap_len = DRW_select_context_elem_len(); - if (bitmap_len == 0) { - return NULL; - } - - rcti rect_px = *rect; - rect_px.xmax += 1; - rect_px.ymax += 1; - - uint buf_len; - const uint *buf = DRW_framebuffer_select_id_read(&rect_px, &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); - - if (r_bitmap_len) { - *r_bitmap_len = bitmap_len; - } - - 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 int center[2], - const int radius, - uint *r_bitmap_len) -{ - const uint bitmap_len = DRW_select_context_elem_len(); - if (bitmap_len == 0) { - return NULL; - } - - const rcti rect = { - .xmin = center[0] - radius, - .xmax = center[0] + radius + 1, - .ymin = center[1] - radius, - .ymax = center[1] + radius + 1, - }; - - const uint *buf = DRW_framebuffer_select_id_read(&rect, 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); - - if (r_bitmap_len) { - *r_bitmap_len = bitmap_len; - } - - 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 int poly[][2], - const int poly_len, - const rcti *rect, - uint *r_bitmap_len) - -{ - const uint bitmap_len = DRW_select_context_elem_len(); - if (bitmap_len == 0) { - return NULL; - } - - rcti rect_px = *rect; - rect_px.xmax += 1; - rect_px.ymax += 1; - - struct PolyMaskData poly_mask_data; - uint buf_len; - const uint *buf = DRW_framebuffer_select_id_read(&rect_px, &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_px.xmin, - rect_px.ymin, - rect_px.xmax, - rect_px.ymax, - 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); - - if (r_bitmap_len) { - *r_bitmap_len = bitmap_len; - } - - 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]) -{ - const rcti rect = { - .xmin = center[0], - .xmax = center[0] + 1, - .ymin = center[1], - .ymax = center[1] + 1, - }; - - uint buf_len; - uint *buf = DRW_framebuffer_select_id_read(&rect, &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 that's 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. */ - - uint index = 0; - - 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 = DRW_framebuffer_select_id_read(&rect, &buf_len); - - if (buf == NULL) { - return index; - } - - 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; - - /* 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; -} - -/** \} */ |