Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/mesh/editmesh_select.c
| Show First 20 Lines • Show All 207 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* reads rect, and builds selection array for quick lookup */ | /* reads rect, and builds selection array for quick lookup */ | ||||
| /* returns if all is OK */ | /* returns if all is OK */ | ||||
| bool EDBM_backbuf_border_init( | bool EDBM_backbuf_border_init( | ||||
| ViewContext *vc, short xmin, | ViewContext *vc, short xmin, | ||||
| short ymin, short xmax, short ymax) | short ymin, short xmax, short ymax) | ||||
| { | { | ||||
| struct ImBuf *buf; | uint *buf, *dr, buf_len; | ||||
| unsigned int *dr; | |||||
| int a; | |||||
| if (vc->obedit == NULL || !V3D_IS_ZBUF(vc->v3d)) { | if (vc->obedit == NULL || !V3D_IS_ZBUF(vc->v3d)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| buf = ED_view3d_backbuf_read(vc, xmin, ymin, xmax, ymax); | buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len); | ||||
| if ((buf == NULL) || (bm_vertoffs == 0)) { | if ((buf == NULL) || (bm_vertoffs == 0)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| dr = buf->rect; | dr = buf; | ||||
| /* build selection lookup */ | /* build selection lookup */ | ||||
| selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); | selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); | ||||
| a = (xmax - xmin + 1) * (ymax - ymin + 1); | while (buf_len--) { | ||||
| while (a--) { | |||||
| if (*dr > 0 && *dr <= bm_vertoffs) { | if (*dr > 0 && *dr <= bm_vertoffs) { | ||||
| BLI_BITMAP_ENABLE(selbuf, *dr); | BLI_BITMAP_ENABLE(selbuf, *dr); | ||||
| } | } | ||||
| dr++; | dr++; | ||||
| } | } | ||||
| IMB_freeImBuf(buf); | MEM_freeN(buf); | ||||
| return true; | return true; | ||||
| } | } | ||||
| bool EDBM_backbuf_check(unsigned int index) | bool EDBM_backbuf_check(unsigned int index) | ||||
| { | { | ||||
| /* odd logic, if selbuf is NULL we assume no zbuf-selection is enabled | /* odd logic, if selbuf is NULL we assume no zbuf-selection is enabled | ||||
| * and just ignore the depth buffer, this is error prone since its possible | * and just ignore the depth buffer, this is error prone since its possible | ||||
| * code doesn't set the depth buffer by accident, but leave for now. - Campbell */ | * code doesn't set the depth buffer by accident, but leave for now. - Campbell */ | ||||
| Show All 31 Lines | |||||
| /* mcords is a polygon mask | /* mcords is a polygon mask | ||||
| * - grab backbuffer, | * - grab backbuffer, | ||||
| * - draw with black in backbuffer, | * - draw with black in backbuffer, | ||||
| * - grab again and compare | * - grab again and compare | ||||
| * returns 'OK' | * returns 'OK' | ||||
| */ | */ | ||||
| bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) | bool EDBM_backbuf_border_mask_init(ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax) | ||||
| { | { | ||||
| unsigned int *dr, *dr_mask, *dr_mask_arr; | uint *buf, *dr, *dr_mask, *dr_mask_arr, buf_len; | ||||
| struct ImBuf *buf; | |||||
| int a; | |||||
| struct LassoMaskData lasso_mask_data; | struct LassoMaskData lasso_mask_data; | ||||
| /* method in use for face selecting too */ | /* method in use for face selecting too */ | ||||
| if (vc->obedit == NULL) { | if (vc->obedit == NULL) { | ||||
| if (!BKE_paint_select_elem_test(vc->obact)) { | if (!BKE_paint_select_elem_test(vc->obact)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| else if (!V3D_IS_ZBUF(vc->v3d)) { | else if (!V3D_IS_ZBUF(vc->v3d)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| buf = ED_view3d_backbuf_read(vc, xmin, ymin, xmax, ymax); | buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len); | ||||
| if ((buf == NULL) || (bm_vertoffs == 0)) { | if ((buf == NULL) || (bm_vertoffs == 0)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| dr = buf->rect; | dr = buf; | ||||
| dr_mask = dr_mask_arr = MEM_callocN(sizeof(*dr_mask) * buf->x * buf->y, __func__); | dr_mask = dr_mask_arr = MEM_callocN(sizeof(*dr_mask) * buf_len, __func__); | ||||
| lasso_mask_data.px = dr_mask; | lasso_mask_data.px = dr_mask; | ||||
| lasso_mask_data.width = (xmax - xmin) + 1; | lasso_mask_data.width = (xmax - xmin) + 1; | ||||
| BLI_bitmap_draw_2d_poly_v2i_n( | BLI_bitmap_draw_2d_poly_v2i_n( | ||||
| xmin, ymin, xmax + 1, ymax + 1, | xmin, ymin, xmax + 1, ymax + 1, | ||||
| mcords, tot, | mcords, tot, | ||||
| edbm_mask_lasso_px_cb, &lasso_mask_data); | edbm_mask_lasso_px_cb, &lasso_mask_data); | ||||
| /* build selection lookup */ | /* build selection lookup */ | ||||
| selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); | selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); | ||||
| a = (xmax - xmin + 1) * (ymax - ymin + 1); | while (buf_len--) { | ||||
| while (a--) { | |||||
| if (*dr > 0 && *dr <= bm_vertoffs && *dr_mask == true) { | if (*dr > 0 && *dr <= bm_vertoffs && *dr_mask == true) { | ||||
| BLI_BITMAP_ENABLE(selbuf, *dr); | BLI_BITMAP_ENABLE(selbuf, *dr); | ||||
| } | } | ||||
| dr++; dr_mask++; | dr++; dr_mask++; | ||||
| } | } | ||||
| IMB_freeImBuf(buf); | MEM_freeN(buf); | ||||
| MEM_freeN(dr_mask_arr); | MEM_freeN(dr_mask_arr); | ||||
| return true; | return true; | ||||
| } | } | ||||
| /* circle shaped sample area */ | /* circle shaped sample area */ | ||||
| bool EDBM_backbuf_circle_init( | bool EDBM_backbuf_circle_init( | ||||
| ViewContext *vc, | ViewContext *vc, | ||||
| short xs, short ys, short rads) | short xs, short ys, short rads) | ||||
| { | { | ||||
| struct ImBuf *buf; | uint *buf, *dr; | ||||
| unsigned int *dr; | |||||
| short xmin, ymin, xmax, ymax, xc, yc; | short xmin, ymin, xmax, ymax, xc, yc; | ||||
| int radsq; | int radsq; | ||||
| /* method in use for face selecting too */ | /* method in use for face selecting too */ | ||||
| if (vc->obedit == NULL) { | if (vc->obedit == NULL) { | ||||
| if (!BKE_paint_select_elem_test(vc->obact)) { | if (!BKE_paint_select_elem_test(vc->obact)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| else if (!V3D_IS_ZBUF(vc->v3d)) { | else if (!V3D_IS_ZBUF(vc->v3d)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| xmin = xs - rads; xmax = xs + rads; | xmin = xs - rads; xmax = xs + rads; | ||||
| ymin = ys - rads; ymax = ys + rads; | ymin = ys - rads; ymax = ys + rads; | ||||
| buf = ED_view3d_backbuf_read(vc, xmin, ymin, xmax, ymax); | buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, NULL); | ||||
| if ((buf == NULL) || (bm_vertoffs == 0)) { | if ((buf == NULL) || (bm_vertoffs == 0)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| dr = buf->rect; | dr = buf; | ||||
| /* build selection lookup */ | /* build selection lookup */ | ||||
| selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); | selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); | ||||
| radsq = rads * rads; | radsq = rads * rads; | ||||
| for (yc = -rads; yc <= rads; yc++) { | for (yc = -rads; yc <= rads; yc++) { | ||||
| for (xc = -rads; xc <= rads; xc++, dr++) { | for (xc = -rads; xc <= rads; xc++, dr++) { | ||||
| if (xc * xc + yc * yc < radsq) { | if (xc * xc + yc * yc < radsq) { | ||||
| if (*dr > 0 && *dr <= bm_vertoffs) { | if (*dr > 0 && *dr <= bm_vertoffs) { | ||||
| BLI_BITMAP_ENABLE(selbuf, *dr); | BLI_BITMAP_ENABLE(selbuf, *dr); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| IMB_freeImBuf(buf); | MEM_freeN(buf); | ||||
| return true; | return true; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name Find Nearest Vert/Edge/Face | /** \name Find Nearest Vert/Edge/Face | ||||
| ▲ Show 20 Lines • Show All 80 Lines • ▼ Show 20 Lines | |||||
| */ | */ | ||||
| BMVert *EDBM_vert_find_nearest_ex( | BMVert *EDBM_vert_find_nearest_ex( | ||||
| ViewContext *vc, float *r_dist, | ViewContext *vc, float *r_dist, | ||||
| const bool use_select_bias, bool use_cycle) | const bool use_select_bias, bool use_cycle) | ||||
| { | { | ||||
| BMesh *bm = vc->em->bm; | BMesh *bm = vc->em->bm; | ||||
| if (V3D_IS_ZBUF(vc->v3d)) { | if (V3D_IS_ZBUF(vc->v3d)) { | ||||
| const int dist_px = ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist); | uint dist_px = (uint)ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist); | ||||
| float dist_test; | |||||
| unsigned int index; | unsigned int index; | ||||
| BMVert *eve; | BMVert *eve; | ||||
| /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */ | /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */ | ||||
| { | { | ||||
| FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_VERTEX); | FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_VERTEX); | ||||
| ED_view3d_backbuf_validate_with_select_mode(vc, select_mode); | ED_view3d_select_id_validate_with_select_mode(vc, select_mode); | ||||
| index = ED_view3d_backbuf_sample_rect( | index = ED_view3d_select_id_read_nearest(vc, vc->mval, bm_wireoffs, 0xFFFFFF, &dist_px); | ||||
| vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test); | |||||
| eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL; | eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL; | ||||
| FAKE_SELECT_MODE_END(vc, fake_select_mode); | FAKE_SELECT_MODE_END(vc, fake_select_mode); | ||||
| } | } | ||||
| if (eve) { | if (eve) { | ||||
| if (dist_test < *r_dist) { | if (dist_px < *r_dist) { | ||||
| *r_dist = dist_test; | *r_dist = dist_px; | ||||
| return eve; | return eve; | ||||
| } | } | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| else { | else { | ||||
| struct NearestVertUserData data = {{0}}; | struct NearestVertUserData data = {{0}}; | ||||
| const struct NearestVertUserData_Hit *hit; | const struct NearestVertUserData_Hit *hit; | ||||
| ▲ Show 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | BMEdge *EDBM_edge_find_nearest_ex( | ||||
| ViewContext *vc, float *r_dist, | ViewContext *vc, float *r_dist, | ||||
| float *r_dist_center, | float *r_dist_center, | ||||
| const bool use_select_bias, const bool use_cycle, | const bool use_select_bias, const bool use_cycle, | ||||
| BMEdge **r_eed_zbuf) | BMEdge **r_eed_zbuf) | ||||
| { | { | ||||
| BMesh *bm = vc->em->bm; | BMesh *bm = vc->em->bm; | ||||
| if (V3D_IS_ZBUF(vc->v3d)) { | if (V3D_IS_ZBUF(vc->v3d)) { | ||||
| const int dist_px = ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist); | uint dist_px = (uint)ED_view3d_backbuf_sample_size_clamp(vc->ar, *r_dist); | ||||
| float dist_test = 0.0f; | |||||
| unsigned int index; | unsigned int index; | ||||
| BMEdge *eed; | BMEdge *eed; | ||||
| /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */ | /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */ | ||||
| { | { | ||||
| FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_EDGE); | FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_EDGE); | ||||
| ED_view3d_backbuf_validate_with_select_mode(vc, select_mode); | ED_view3d_select_id_validate_with_select_mode(vc, select_mode); | ||||
| index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test); | index = ED_view3d_select_id_read_nearest(vc, vc->mval, bm_solidoffs, bm_wireoffs, &dist_px); | ||||
| eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL; | eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL; | ||||
| FAKE_SELECT_MODE_END(vc, fake_select_mode); | FAKE_SELECT_MODE_END(vc, fake_select_mode); | ||||
| } | } | ||||
| if (r_eed_zbuf) { | if (r_eed_zbuf) { | ||||
| *r_eed_zbuf = eed; | *r_eed_zbuf = eed; | ||||
| } | } | ||||
| Show All 11 Lines | if (r_dist_center && eed) { | ||||
| mesh_foreachScreenEdge(vc, find_nearest_edge_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT); | mesh_foreachScreenEdge(vc, find_nearest_edge_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT); | ||||
| *r_dist_center = data.dist; | *r_dist_center = data.dist; | ||||
| } | } | ||||
| /* end exception */ | /* end exception */ | ||||
| if (eed) { | if (eed) { | ||||
| if (dist_test < *r_dist) { | if (dist_px < *r_dist) { | ||||
| *r_dist = dist_test; | *r_dist = dist_px; | ||||
| return eed; | return eed; | ||||
| } | } | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| else { | else { | ||||
| struct NearestEdgeUserData data = {{0}}; | struct NearestEdgeUserData data = {{0}}; | ||||
| const struct NearestEdgeUserData_Hit *hit; | const struct NearestEdgeUserData_Hit *hit; | ||||
| ▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | BMFace *EDBM_face_find_nearest_ex( | ||||
| if (V3D_IS_ZBUF(vc->v3d)) { | if (V3D_IS_ZBUF(vc->v3d)) { | ||||
| float dist_test = 0.0f; | float dist_test = 0.0f; | ||||
| unsigned int index; | unsigned int index; | ||||
| BMFace *efa; | BMFace *efa; | ||||
| { | { | ||||
| FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_FACE); | FAKE_SELECT_MODE_BEGIN(vc, fake_select_mode, select_mode, SCE_SELECT_FACE); | ||||
| ED_view3d_backbuf_validate_with_select_mode(vc, select_mode); | ED_view3d_select_id_validate_with_select_mode(vc, select_mode); | ||||
| index = ED_view3d_backbuf_sample(vc, vc->mval[0], vc->mval[1]); | index = ED_view3d_select_id_sample(vc, vc->mval[0], vc->mval[1]); | ||||
| efa = index ? BM_face_at_index_find_or_table(bm, index - 1) : NULL; | efa = index ? BM_face_at_index_find_or_table(bm, index - 1) : NULL; | ||||
| FAKE_SELECT_MODE_END(vc, fake_select_mode); | FAKE_SELECT_MODE_END(vc, fake_select_mode); | ||||
| } | } | ||||
| if (r_efa_zbuf) { | if (r_efa_zbuf) { | ||||
| *r_efa_zbuf = efa; | *r_efa_zbuf = efa; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | if ((dist > 0.0f) && em->selectmode & SCE_SELECT_FACE) { | ||||
| float dist_center = 0.0f; | float dist_center = 0.0f; | ||||
| float *dist_center_p = (em->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_VERTEX)) ? &dist_center : NULL; | float *dist_center_p = (em->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_VERTEX)) ? &dist_center : NULL; | ||||
| for (uint base_index = 0; base_index < bases_len; base_index++) { | for (uint base_index = 0; base_index < bases_len; base_index++) { | ||||
| Base *base_iter = bases[base_index]; | Base *base_iter = bases[base_index]; | ||||
| Object *obedit = base_iter->object; | Object *obedit = base_iter->object; | ||||
| ED_view3d_viewcontext_init_object(vc, obedit); | ED_view3d_viewcontext_init_object(vc, obedit); | ||||
| BLI_assert(vc->em->selectmode == em->selectmode); | BLI_assert(vc->em->selectmode == em->selectmode); | ||||
| ED_view3d_backbuf_validate(vc); | |||||
| BMFace *efa_zbuf = NULL; | BMFace *efa_zbuf = NULL; | ||||
| BMFace *efa_test = EDBM_face_find_nearest_ex(vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf); | BMFace *efa_test = EDBM_face_find_nearest_ex(vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf); | ||||
| if (efa_test && dist_center_p) { | if (efa_test && dist_center_p) { | ||||
| dist = min_ff(dist_margin, dist_center); | dist = min_ff(dist_margin, dist_center); | ||||
| } | } | ||||
| if (efa_test) { | if (efa_test) { | ||||
| hit.f.base_index = base_index; | hit.f.base_index = base_index; | ||||
| hit.f.ele = efa_test; | hit.f.ele = efa_test; | ||||
| } | } | ||||
| if (efa_zbuf) { | if (efa_zbuf) { | ||||
| hit.f_zbuf.base_index = base_index; | hit.f_zbuf.base_index = base_index; | ||||
| hit.f_zbuf.ele = efa_zbuf; | hit.f_zbuf.ele = efa_zbuf; | ||||
| } | } | ||||
| } /* bases */ | } /* bases */ | ||||
| } | } | ||||
| if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_EDGE)) { | if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_EDGE)) { | ||||
| float dist_center = 0.0f; | float dist_center = 0.0f; | ||||
| float *dist_center_p = (em->selectmode & SCE_SELECT_VERTEX) ? &dist_center : NULL; | float *dist_center_p = (em->selectmode & SCE_SELECT_VERTEX) ? &dist_center : NULL; | ||||
| for (uint base_index = 0; base_index < bases_len; base_index++) { | for (uint base_index = 0; base_index < bases_len; base_index++) { | ||||
| Base *base_iter = bases[base_index]; | Base *base_iter = bases[base_index]; | ||||
| Object *obedit = base_iter->object; | Object *obedit = base_iter->object; | ||||
| ED_view3d_viewcontext_init_object(vc, obedit); | ED_view3d_viewcontext_init_object(vc, obedit); | ||||
| ED_view3d_backbuf_validate(vc); | |||||
| BMEdge *eed_zbuf = NULL; | BMEdge *eed_zbuf = NULL; | ||||
| BMEdge *eed_test = EDBM_edge_find_nearest_ex(vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf); | BMEdge *eed_test = EDBM_edge_find_nearest_ex(vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf); | ||||
| if (eed_test && dist_center_p) { | if (eed_test && dist_center_p) { | ||||
| dist = min_ff(dist_margin, dist_center); | dist = min_ff(dist_margin, dist_center); | ||||
| } | } | ||||
| if (eed_test) { | if (eed_test) { | ||||
| hit.e.base_index = base_index; | hit.e.base_index = base_index; | ||||
| hit.e.ele = eed_test; | hit.e.ele = eed_test; | ||||
| } | } | ||||
| if (eed_zbuf) { | if (eed_zbuf) { | ||||
| hit.e_zbuf.base_index = base_index; | hit.e_zbuf.base_index = base_index; | ||||
| hit.e_zbuf.ele = eed_zbuf; | hit.e_zbuf.ele = eed_zbuf; | ||||
| } | } | ||||
| } /* bases */ | } /* bases */ | ||||
| } | } | ||||
| if ((dist > 0.0f) && em->selectmode & SCE_SELECT_VERTEX) { | if ((dist > 0.0f) && em->selectmode & SCE_SELECT_VERTEX) { | ||||
| for (uint base_index = 0; base_index < bases_len; base_index++) { | for (uint base_index = 0; base_index < bases_len; base_index++) { | ||||
| Base *base_iter = bases[base_index]; | Base *base_iter = bases[base_index]; | ||||
| Object *obedit = base_iter->object; | Object *obedit = base_iter->object; | ||||
| ED_view3d_viewcontext_init_object(vc, obedit); | ED_view3d_viewcontext_init_object(vc, obedit); | ||||
| ED_view3d_backbuf_validate(vc); | |||||
| BMVert *eve_test = EDBM_vert_find_nearest_ex(vc, &dist, true, use_cycle); | BMVert *eve_test = EDBM_vert_find_nearest_ex(vc, &dist, true, use_cycle); | ||||
| if (eve_test) { | if (eve_test) { | ||||
| hit.v.base_index = base_index; | hit.v.base_index = base_index; | ||||
| hit.v.ele = eve_test; | hit.v.ele = eve_test; | ||||
| } | } | ||||
| } /* bases */ | } /* bases */ | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 3,714 Lines • Show Last 20 Lines | |||||