diff options
author | YimingWu <xp8110@outlook.com> | 2019-05-28 10:39:42 +0300 |
---|---|---|
committer | YimingWu <xp8110@outlook.com> | 2019-05-28 10:39:42 +0300 |
commit | f37533fc44cfb8a7eec919df0dae38998de10e2f (patch) | |
tree | 264074656a88f96bdc3a4dbf53340277d45dc86a /source/blender/editors/mesh | |
parent | a640228d92273154acc644d525b095b5318c248b (diff) | |
parent | 1008d9c73567780ec22bea6a0b27f57e60ea403d (diff) |
Merge branch 'master' into soc-2019-npr
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r-- | source/blender/editors/mesh/editface.c | 68 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_bisect.c | 6 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c | 3 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_knife.c | 5 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_path.c | 83 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 273 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_tools.c | 23 | ||||
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 9 |
8 files changed, 168 insertions, 302 deletions
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index fdbcc3449b2..d61c340f7a2 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -441,74 +441,6 @@ bool paintface_mouse_select( return true; } -bool do_paintface_box_select(ViewContext *vc, const rcti *rect, int sel_op) -{ - Object *ob = vc->obact; - Mesh *me; - - me = BKE_mesh_from_object(ob); - if ((me == NULL) || (me->totpoly == 0)) { - return false; - } - - bool changed = false; - if (SEL_OP_USE_PRE_DESELECT(sel_op)) { - changed |= paintface_deselect_all_visible(vc->C, vc->obact, SEL_DESELECT, false); - } - - if (BLI_rcti_is_empty(rect)) { - /* pass */ - } - else { - MPoly *mpoly; - uint *rt, *buf, buf_len; - int a, index; - - char *selar = MEM_callocN(me->totpoly + 1, "selar"); - - ED_view3d_select_id_validate(vc); - buf = ED_view3d_select_id_read_rect(vc, rect, &buf_len); - - rt = buf; - - a = buf_len; - while (a--) { - if (*rt) { - index = *rt; - if (index <= me->totpoly) { - selar[index] = 1; - } - } - rt++; - } - - mpoly = me->mpoly; - for (a = 1; a <= me->totpoly; a++, mpoly++) { - if ((mpoly->flag & ME_HIDE) == 0) { - const bool is_select = mpoly->flag & ME_FACE_SEL; - const bool is_inside = (selar[a] != 0); - const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside); - if (sel_op_result != -1) { - SET_FLAG_FROM_TEST(mpoly->flag, sel_op_result, ME_FACE_SEL); - changed = true; - } - } - } - - MEM_freeN(buf); - MEM_freeN(selar); - -#ifdef __APPLE__ - glReadBuffer(GL_BACK); -#endif - } - - if (changed) { - paintface_flush_flags(vc->C, vc->obact, SELECT); - } - return changed; -} - /* (similar to void paintface_flush_flags(Object *ob)) * copy the vertex flags, most importantly selection from the mesh to the final derived mesh, * use in object mode when selecting vertices (while painting) */ diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c index bc60ff9274f..1d173d8e396 100644 --- a/source/blender/editors/mesh/editmesh_bisect.c +++ b/source/blender/editors/mesh/editmesh_bisect.c @@ -148,7 +148,7 @@ static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event) BisectData *opdata; opdata = MEM_mallocN(sizeof(BisectData), "inset_operator_data"); - gesture->userdata = opdata; + gesture->user_data.data = opdata; opdata->backup_len = objects_len; opdata->backup = MEM_callocN(sizeof(*opdata->backup) * objects_len, __func__); @@ -193,7 +193,7 @@ static void edbm_bisect_exit(bContext *C, BisectData *opdata) static int mesh_bisect_modal(bContext *C, wmOperator *op, const wmEvent *event) { wmGesture *gesture = op->customdata; - BisectData *opdata = gesture->userdata; + BisectData *opdata = gesture->user_data.data; BisectData opdata_back = *opdata; /* annoyance, WM_gesture_straightline_modal, frees */ int ret; @@ -276,7 +276,7 @@ static int mesh_bisect_exec(bContext *C, wmOperator *op) } wmGesture *gesture = op->customdata; - BisectData *opdata = (gesture != NULL) ? gesture->userdata : NULL; + BisectData *opdata = (gesture != NULL) ? gesture->user_data.data : NULL; /* -------------------------------------------------------------------- */ /* Modal support */ diff --git a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c index 269ead7b23f..74700e59e99 100644 --- a/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c +++ b/source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c @@ -295,7 +295,8 @@ static void gizmo_mesh_spin_init_draw_prepare(const bContext *C, wmGizmoGroup *g static void gizmo_mesh_spin_init_invoke_prepare(const bContext *UNUSED(C), wmGizmoGroup *gzgroup, - wmGizmo *gz) + wmGizmo *gz, + const wmEvent *UNUSED(event)) { /* Set the initial ortho axis. */ GizmoGroupData_SpinInit *ggd = gzgroup->customdata; diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index e45c15b3e53..976dbe01a22 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1156,19 +1156,20 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vert, NULL, GPU_BATCH_OWNS_VBO); GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); + GPU_batch_bind(batch); /* draw any snapped verts first */ rgba_uchar_to_float(fcol, kcd->colors.point_a); GPU_batch_uniform_4fv(batch, "color", fcol); GPU_matrix_bind(batch->interface); GPU_point_size(11); - GPU_batch_draw_range_ex(batch, 0, v - 1, false); + GPU_batch_draw_advanced(batch, 0, v - 1, 0, 0); /* now draw the rest */ rgba_uchar_to_float(fcol, kcd->colors.curpoint_a); GPU_batch_uniform_4fv(batch, "color", fcol); GPU_point_size(7); - GPU_batch_draw_range_ex(batch, vs + 1, kcd->totlinehit - (vs + 1), false); + GPU_batch_draw_advanced(batch, vs + 1, kcd->totlinehit - (vs + 1), 0, 0); GPU_batch_program_use_end(batch); GPU_batch_discard(batch); diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c index f8ec4334427..6fd0ee83b6c 100644 --- a/source/blender/editors/mesh/editmesh_path.c +++ b/source/blender/editors/mesh/editmesh_path.c @@ -63,6 +63,15 @@ /** \name Path Select Struct & Properties * \{ */ +enum { + EDGE_MODE_SELECT = 0, + EDGE_MODE_TAG_SEAM = 1, + EDGE_MODE_TAG_SHARP = 2, + EDGE_MODE_TAG_CREASE = 3, + EDGE_MODE_TAG_BEVEL = 4, + EDGE_MODE_TAG_FREESTYLE = 5, +}; + struct PathSelectParams { /** ensure the active element is the last selected item (handy for picking) */ bool track_active; @@ -75,6 +84,23 @@ struct PathSelectParams { static void path_select_properties(wmOperatorType *ot) { + static const EnumPropertyItem edge_tag_items[] = { + {EDGE_MODE_SELECT, "SELECT", 0, "Select", ""}, + {EDGE_MODE_TAG_SEAM, "SEAM", 0, "Tag Seam", ""}, + {EDGE_MODE_TAG_SHARP, "SHARP", 0, "Tag Sharp", ""}, + {EDGE_MODE_TAG_CREASE, "CREASE", 0, "Tag Crease", ""}, + {EDGE_MODE_TAG_BEVEL, "BEVEL", 0, "Tag Bevel", ""}, + {EDGE_MODE_TAG_FREESTYLE, "FREESTYLE", 0, "Tag Freestyle Edge Mark", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + RNA_def_enum(ot->srna, + "edge_mode", + edge_tag_items, + EDGE_MODE_SELECT, + "Edge Tag", + "The edge flag to tag when selecting the shortest path"); + RNA_def_boolean(ot->srna, "use_face_step", false, @@ -93,9 +119,24 @@ static void path_select_properties(wmOperatorType *ot) WM_operator_properties_checker_interval(ot, true); } -static void path_select_params_from_op(wmOperator *op, struct PathSelectParams *op_params) +static void path_select_params_from_op(wmOperator *op, + ToolSettings *ts, + struct PathSelectParams *op_params) { - op_params->edge_mode = EDGE_MODE_SELECT; + { + PropertyRNA *prop = RNA_struct_find_property(op->ptr, "edge_mode"); + if (RNA_property_is_set(op->ptr, prop)) { + op_params->edge_mode = RNA_property_enum_get(op->ptr, prop); + if (op->flag & OP_IS_INVOKE) { + ts->edge_mode = op_params->edge_mode; + } + } + else { + op_params->edge_mode = ts->edge_mode; + RNA_property_enum_set(op->ptr, prop, op_params->edge_mode); + } + } + op_params->track_active = false; op_params->use_face_step = RNA_boolean_get(op->ptr, "use_face_step"); op_params->use_fill = RNA_boolean_get(op->ptr, "use_fill"); @@ -103,6 +144,21 @@ static void path_select_params_from_op(wmOperator *op, struct PathSelectParams * WM_operator_properties_checker_interval_from_op(op, &op_params->interval_params); } +static bool path_select_poll_property(const bContext *C, + wmOperator *UNUSED(op), + const PropertyRNA *prop) +{ + const char *prop_id = RNA_property_identifier(prop); + if (STREQ(prop_id, "edge_mode")) { + const Scene *scene = CTX_data_scene(C); + ToolSettings *ts = scene->toolsettings; + if ((ts->selectmode & SCE_SELECT_EDGE) == 0) { + return false; + } + } + return true; +} + struct UserData { BMesh *bm; Mesh *me; @@ -319,7 +375,7 @@ static void edgetag_ensure_cd_flag(Mesh *me, const char edge_mode) /* mesh shortest path select, uses prev-selected edge */ /* since you want to create paths with multiple selects, it doesn't have extend option */ -static void mouse_mesh_shortest_path_edge(Scene *UNUSED(scene), +static void mouse_mesh_shortest_path_edge(Scene *scene, Object *obedit, const struct PathSelectParams *op_params, BMEdge *e_act, @@ -421,6 +477,10 @@ static void mouse_mesh_shortest_path_edge(Scene *UNUSED(scene), } EDBM_update_generic(em, false, false); + + if (op_params->edge_mode == EDGE_MODE_TAG_SEAM) { + ED_uvedit_live_unwrap(scene, &obedit, 1); + } } /** \} */ @@ -649,12 +709,14 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE return OPERATOR_FINISHED; } + struct PathSelectParams op_params; + path_select_params_from_op(op, vc.scene->toolsettings, &op_params); + BMElem *ele_src, *ele_dst; if (!(ele_src = edbm_elem_active_elem_or_face_get(em->bm)) || !(ele_dst = edbm_elem_find_nearest(&vc, ele_src->head.htype))) { /* special case, toggle edge tags even when we don't have a path */ - if (((em->selectmode & SCE_SELECT_EDGE) && - (vc.scene->toolsettings->edge_mode != EDGE_MODE_SELECT)) && + if (((em->selectmode & SCE_SELECT_EDGE) && (op_params.edge_mode != EDGE_MODE_SELECT)) && /* check if we only have a destination edge */ ((ele_src == NULL) && (ele_dst = edbm_elem_find_nearest(&vc, BM_EDGE)))) { ele_src = ele_dst; @@ -665,11 +727,7 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE } } - struct PathSelectParams op_params; - - path_select_params_from_op(op, &op_params); op_params.track_active = track_active; - op_params.edge_mode = vc.scene->toolsettings->edge_mode; if (!edbm_shortest_path_pick_ex(vc.scene, vc.obedit, &op_params, ele_src, ele_dst)) { return OPERATOR_PASS_THROUGH; @@ -707,9 +765,8 @@ static int edbm_shortest_path_pick_exec(bContext *C, wmOperator *op) } struct PathSelectParams op_params; - path_select_params_from_op(op, &op_params); + path_select_params_from_op(op, scene->toolsettings, &op_params); op_params.track_active = true; - op_params.edge_mode = scene->toolsettings->edge_mode; if (!edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst)) { return OPERATOR_CANCELLED; @@ -731,6 +788,7 @@ void MESH_OT_shortest_path_pick(wmOperatorType *ot) ot->invoke = edbm_shortest_path_pick_invoke; ot->exec = edbm_shortest_path_pick_exec; ot->poll = ED_operator_editmesh_region_view3d; + ot->poll_property = path_select_poll_property; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -832,7 +890,7 @@ static int edbm_shortest_path_select_exec(bContext *C, wmOperator *op) if (ele_src && ele_dst) { struct PathSelectParams op_params; - path_select_params_from_op(op, &op_params); + path_select_params_from_op(op, scene->toolsettings, &op_params); edbm_shortest_path_pick_ex(scene, obedit, &op_params, ele_src, ele_dst); @@ -860,6 +918,7 @@ void MESH_OT_shortest_path_select(wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_shortest_path_select_exec; ot->poll = ED_operator_editmesh; + ot->poll_property = path_select_poll_property; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 485d855e18e..6a91fcb8327 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -53,6 +53,7 @@ #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" @@ -199,8 +200,19 @@ void EDBM_automerge(Scene *scene, Object *obedit, bool update, const char hflag) * \{ */ struct EDBMBaseOffset { - uint face; - uint edge; + /* For convenience only. */ + union { + uint offset; + uint face_start; + }; + union { + uint face; + uint edge_start; + }; + union { + uint edge; + uint vert_start; + }; uint vert; }; @@ -209,18 +221,21 @@ struct EDBMSelectID_Context { /** Borrow from caller (not freed). */ struct Base **bases; uint bases_len; + /** Total number of items `base_array_index_offsets[bases_len - 1].vert`. */ + uint base_array_index_len; }; static bool check_ob_drawface_dot(short select_mode, const View3D *v3d, char dt) { if (select_mode & SCE_SELECT_FACE) { - if (dt < OB_SOLID) { + if ((dt < OB_SOLID) || XRAY_FLAG_ENABLED(v3d)) { return true; } if (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) { return true; } - if (XRAY_FLAG_ENABLED(v3d)) { + if ((v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_EDGES) == 0) { + /* Since we can't deduce face selection when edges aren't visible - show dots. */ return true; } } @@ -234,7 +249,7 @@ static void edbm_select_pick_draw_bases(struct EDBMSelectID_Context *sel_id_ctx, Scene *scene_eval = (Scene *)DEG_get_evaluated_id(vc->depsgraph, &vc->scene->id); DRW_framebuffer_select_id_setup(vc->ar, true); - uint offset = 0; + uint offset = 1; for (uint base_index = 0; base_index < sel_id_ctx->bases_len; base_index++) { Object *ob_eval = DEG_get_evaluated_object(vc->depsgraph, sel_id_ctx->bases[base_index]->object); @@ -252,9 +267,12 @@ static void edbm_select_pick_draw_bases(struct EDBMSelectID_Context *sel_id_ctx, &base_ofs->edge, &base_ofs->face); + base_ofs->offset = offset; offset = base_ofs->vert; } + sel_id_ctx->base_array_index_len = offset; + DRW_framebuffer_select_id_release(vc->ar); } @@ -262,28 +280,26 @@ BMElem *EDBM_select_id_bm_elem_get(struct EDBMSelectID_Context *sel_id_ctx, const uint sel_id, uint *r_base_index) { - char elem_type; + char elem_type = 0; uint elem_id; - uint prev_offs = 0; uint base_index = 0; for (; base_index < sel_id_ctx->bases_len; base_index++) { struct EDBMBaseOffset *base_ofs = &sel_id_ctx->base_array_index_offsets[base_index]; if (base_ofs->face > sel_id) { - elem_id = sel_id - (prev_offs + 1); + elem_id = sel_id - base_ofs->face_start; elem_type = BM_FACE; break; } if (base_ofs->edge > sel_id) { - elem_id = sel_id - base_ofs->face; + elem_id = sel_id - base_ofs->edge_start; elem_type = BM_EDGE; break; } if (base_ofs->vert > sel_id) { - elem_id = sel_id - base_ofs->edge; + elem_id = sel_id - base_ofs->vert_start; elem_type = BM_VERT; break; } - prev_offs = base_ofs->vert; } if (r_base_index) { @@ -306,9 +322,32 @@ BMElem *EDBM_select_id_bm_elem_get(struct EDBMSelectID_Context *sel_id_ctx, } } +uint EDBM_select_id_context_offset_for_object_elem(const struct EDBMSelectID_Context *sel_id_ctx, + int base_index, + char htype) +{ + struct EDBMBaseOffset *base_ofs = &sel_id_ctx->base_array_index_offsets[base_index]; + if (htype == BM_VERT) { + return base_ofs->vert_start - 1; + } + if (htype == BM_EDGE) { + return base_ofs->edge_start - 1; + } + if (htype == BM_FACE) { + return base_ofs->face_start - 1; + } + BLI_assert(0); + return 0; +} + +uint EDBM_select_id_context_elem_len(const struct EDBMSelectID_Context *sel_id_ctx) +{ + return sel_id_ctx->base_array_index_len; +} + struct EDBMSelectID_Context *EDBM_select_id_context_create(ViewContext *vc, Base **bases, - uint bases_len, + const uint bases_len, short select_mode) { struct EDBMSelectID_Context *sel_id_ctx = MEM_mallocN(sizeof(*sel_id_ctx), __func__); @@ -328,192 +367,6 @@ void EDBM_select_id_context_destroy(struct EDBMSelectID_Context *sel_id_ctx) MEM_freeN(sel_id_ctx); } -/* set in view3d_draw_legacy.c ... for colorindices */ -unsigned int bm_solidoffs = 0, bm_wireoffs = 0, bm_vertoffs = 0; - -/* facilities for box select and circle select */ -static BLI_bitmap *selbuf = NULL; - -static BLI_bitmap *edbm_backbuf_alloc(const int size) -{ - return BLI_BITMAP_NEW(size, "selbuf"); -} - -/* reads rect, and builds selection array for quick lookup */ -/* returns if all is OK */ -bool EDBM_backbuf_border_init(ViewContext *vc, short xmin, short ymin, short xmax, short ymax) -{ - uint *buf, *dr, buf_len; - - if (vc->obedit == NULL || XRAY_FLAG_ENABLED(vc->v3d)) { - return false; - } - - ED_view3d_select_id_validate(vc); - buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len); - if ((buf == NULL) || (bm_vertoffs == 0)) { - return false; - } - - dr = buf; - - /* build selection lookup */ - selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); - - while (buf_len--) { - if (*dr > 0 && *dr <= bm_vertoffs) { - BLI_BITMAP_ENABLE(selbuf, *dr); - } - dr++; - } - MEM_freeN(buf); - return true; -} - -bool EDBM_backbuf_check(unsigned int index) -{ - /* 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 - * code doesn't set the depth buffer by accident, but leave for now. - Campbell */ - if (selbuf == NULL) { - return true; - } - - if (index > 0 && index <= bm_vertoffs) { - return BLI_BITMAP_TEST_BOOL(selbuf, index); - } - - return false; -} - -void EDBM_backbuf_free(void) -{ - if (selbuf) { - MEM_freeN(selbuf); - } - selbuf = NULL; -} - -struct LassoMaskData { - unsigned int *px; - int width; -}; - -static void edbm_mask_lasso_px_cb(int x, int x_end, int y, void *user_data) -{ - struct LassoMaskData *data = user_data; - unsigned int *px = &data->px[(y * data->width) + x]; - do { - *px = true; - px++; - } while (++x != x_end); -} - -/* mcords is a polygon mask - * - grab backbuffer, - * - draw with black in backbuffer, - * - grab again and compare - * returns 'OK' - */ -bool EDBM_backbuf_border_mask_init(ViewContext *vc, - const int mcords[][2], - short tot, - short xmin, - short ymin, - short xmax, - short ymax) -{ - uint *buf, *dr, *dr_mask, *dr_mask_arr, buf_len; - struct LassoMaskData lasso_mask_data; - - /* method in use for face selecting too */ - if (vc->obedit == NULL) { - if (!BKE_paint_select_elem_test(vc->obact)) { - return false; - } - } - else if (XRAY_FLAG_ENABLED(vc->v3d)) { - return false; - } - - ED_view3d_select_id_validate(vc); - buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, &buf_len); - if ((buf == NULL) || (bm_vertoffs == 0)) { - return false; - } - - dr = buf; - - dr_mask = dr_mask_arr = MEM_callocN(sizeof(*dr_mask) * buf_len, __func__); - lasso_mask_data.px = dr_mask; - lasso_mask_data.width = (xmax - xmin) + 1; - - BLI_bitmap_draw_2d_poly_v2i_n( - xmin, ymin, xmax + 1, ymax + 1, mcords, tot, edbm_mask_lasso_px_cb, &lasso_mask_data); - - /* build selection lookup */ - selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); - - while (buf_len--) { - if (*dr > 0 && *dr <= bm_vertoffs && *dr_mask == true) { - BLI_BITMAP_ENABLE(selbuf, *dr); - } - dr++; - dr_mask++; - } - MEM_freeN(buf); - MEM_freeN(dr_mask_arr); - - return true; -} - -/* circle shaped sample area */ -bool EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads) -{ - uint *buf, *dr; - short xmin, ymin, xmax, ymax, xc, yc; - int radsq; - - /* method in use for face selecting too */ - if (vc->obedit == NULL) { - if (!BKE_paint_select_elem_test(vc->obact)) { - return false; - } - } - else if (XRAY_FLAG_ENABLED(vc->v3d)) { - return false; - } - - xmin = xs - rads; - xmax = xs + rads; - ymin = ys - rads; - ymax = ys + rads; - - ED_view3d_select_id_validate(vc); - buf = ED_view3d_select_id_read(vc, xmin, ymin, xmax, ymax, NULL); - if ((buf == NULL) || (bm_vertoffs == 0)) { - return false; - } - - dr = buf; - - /* build selection lookup */ - selbuf = edbm_backbuf_alloc(bm_vertoffs + 1); - radsq = rads * rads; - for (yc = -rads; yc <= rads; yc++) { - for (xc = -rads; xc <= rads; xc++, dr++) { - if (xc * xc + yc * yc < radsq) { - if (*dr > 0 && *dr <= bm_vertoffs) { - BLI_BITMAP_ENABLE(selbuf, *dr); - } - } - } - } - - MEM_freeN(buf); - return true; -} - /** \} */ /* -------------------------------------------------------------------- */ @@ -625,7 +478,7 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc, struct EDBMSelectID_Context *sel_id_ctx = EDBM_select_id_context_create( vc, bases, bases_len, select_mode); - index = ED_view3d_select_id_read_nearest(vc, vc->mval, 1, UINT_MAX, &dist_px); + index = ED_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px); if (index) { eve = (BMVert *)EDBM_select_id_bm_elem_get(sel_id_ctx, index, &base_index); @@ -652,7 +505,7 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc, } else { struct NearestVertUserData data = {{0}}; - const struct NearestVertUserData_Hit *hit; + const struct NearestVertUserData_Hit *hit = NULL; const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT; BMesh *prev_select_bm = NULL; @@ -697,6 +550,10 @@ BMVert *EDBM_vert_find_nearest_ex(ViewContext *vc, } } + if (hit == NULL) { + return NULL; + } + prev_select.index = hit->index; prev_select.elem = hit->vert; prev_select.bm = prev_select_bm; @@ -850,7 +707,7 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc, struct EDBMSelectID_Context *sel_id_ctx = EDBM_select_id_context_create( vc, bases, bases_len, select_mode); - index = ED_view3d_select_id_read_nearest(vc, vc->mval, 1, UINT_MAX, &dist_px); + index = ED_select_buffer_find_nearest_to_point(vc->mval, 1, UINT_MAX, &dist_px); if (index) { eed = (BMEdge *)EDBM_select_id_bm_elem_get(sel_id_ctx, index, &base_index); @@ -899,7 +756,7 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc, } else { struct NearestEdgeUserData data = {{0}}; - const struct NearestEdgeUserData_Hit *hit; + const struct NearestEdgeUserData_Hit *hit = NULL; /* interpolate along the edge before doing a clipping plane test */ const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT & ~V3D_PROJ_TEST_CLIP_BB; BMesh *prev_select_bm = NULL; @@ -946,6 +803,10 @@ BMEdge *EDBM_edge_find_nearest_ex(ViewContext *vc, } } + if (hit == NULL) { + return NULL; + } + if (r_dist_center) { *r_dist_center = hit->dist_center; } @@ -1059,7 +920,7 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc, struct EDBMSelectID_Context *sel_id_ctx = EDBM_select_id_context_create( vc, bases, bases_len, select_mode); - index = ED_view3d_select_id_sample(vc, vc->mval[0], vc->mval[1]); + index = ED_select_buffer_sample_point(vc->mval); if (index) { efa = (BMFace *)EDBM_select_id_bm_elem_get(sel_id_ctx, index, &base_index); @@ -1108,7 +969,7 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc, } else { struct NearestFaceUserData data = {{0}}; - const struct NearestFaceUserData_Hit *hit; + const struct NearestFaceUserData_Hit *hit = NULL; const eV3DProjTest clip_flag = V3D_PROJ_TEST_CLIP_DEFAULT; BMesh *prev_select_bm = NULL; @@ -1153,6 +1014,10 @@ BMFace *EDBM_face_find_nearest_ex(ViewContext *vc, } } + if (hit == NULL) { + return NULL; + } + if (r_dist_center) { *r_dist_center = hit->dist; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 331be744932..60c6994eb2e 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -7688,6 +7688,7 @@ static int point_normals_init(bContext *C, wmOperator *op, const wmEvent *UNUSED BMEditMesh *em = BKE_editmesh_from_object(obedit); BMesh *bm = em->bm; + BKE_editmesh_ensure_autosmooth(em); BKE_editmesh_lnorspace_update(em); BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm); @@ -8077,7 +8078,7 @@ void MESH_OT_point_normals(struct wmOperatorType *ot) ot->exec = edbm_point_normals_exec; ot->invoke = edbm_point_normals_invoke; ot->modal = edbm_point_normals_modal; - ot->poll = ED_operator_editmesh_auto_smooth; + ot->poll = ED_operator_editmesh; ot->ui = edbm_point_normals_ui; ot->cancel = point_normals_free; @@ -8243,6 +8244,7 @@ static int normals_split_merge(bContext *C, const bool do_merge) BMEdge *e; BMIter eiter; + BKE_editmesh_ensure_autosmooth(em); BKE_editmesh_lnorspace_update(em); BMLoopNorEditDataArray *lnors_ed_arr = do_merge ? BM_loop_normal_editdata_array_init(bm) : NULL; @@ -8288,7 +8290,7 @@ void MESH_OT_merge_normals(struct wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_merge_normals_exec; - ot->poll = ED_operator_editmesh_auto_smooth; + ot->poll = ED_operator_editmesh; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -8308,7 +8310,7 @@ void MESH_OT_split_normals(struct wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_split_normals_exec; - ot->poll = ED_operator_editmesh_auto_smooth; + ot->poll = ED_operator_editmesh; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -8346,6 +8348,7 @@ static int edbm_average_normals_exec(bContext *C, wmOperator *op) BMLoop *l, *l_curr, *l_first; BMIter fiter; + BKE_editmesh_ensure_autosmooth(em); bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL; BKE_editmesh_lnorspace_update(em); @@ -8506,7 +8509,7 @@ void MESH_OT_average_normals(struct wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_average_normals_exec; - ot->poll = ED_operator_editmesh_auto_smooth; + ot->poll = ED_operator_editmesh; ot->ui = edbm_average_normals_ui; /* flags */ @@ -8569,6 +8572,7 @@ static int edbm_normals_tools_exec(bContext *C, wmOperator *op) const int mode = RNA_enum_get(op->ptr, "mode"); const bool absolute = RNA_boolean_get(op->ptr, "absolute"); + BKE_editmesh_ensure_autosmooth(em); BKE_editmesh_lnorspace_update(em); BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm); BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata; @@ -8725,7 +8729,7 @@ void MESH_OT_normals_tools(struct wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_normals_tools_exec; - ot->poll = ED_operator_editmesh_auto_smooth; + ot->poll = ED_operator_editmesh; ot->ui = edbm_normals_tools_ui; /* flags */ @@ -8765,6 +8769,7 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op) const bool keep_sharp = RNA_boolean_get(op->ptr, "keep_sharp"); + BKE_editmesh_ensure_autosmooth(em); BKE_editmesh_lnorspace_update(em); float(*vnors)[3] = MEM_callocN(sizeof(*vnors) * bm->totvert, __func__); @@ -8830,6 +8835,7 @@ static int edbm_set_normals_from_faces_exec(bContext *C, wmOperator *op) MEM_freeN(vnors); EDBM_update_generic(em, true, false); } + MEM_freeN(objects); return OPERATOR_FINISHED; } @@ -8843,7 +8849,7 @@ void MESH_OT_set_normals_from_faces(struct wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_set_normals_from_faces_exec; - ot->poll = ED_operator_editmesh_auto_smooth; + ot->poll = ED_operator_editmesh; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -8860,6 +8866,7 @@ static int edbm_smoothen_normals_exec(bContext *C, wmOperator *op) BMLoop *l; BMIter fiter, liter; + BKE_editmesh_ensure_autosmooth(em); BKE_editmesh_lnorspace_update(em); BMLoopNorEditDataArray *lnors_ed_arr = BM_loop_normal_editdata_array_init(bm); @@ -8935,7 +8942,7 @@ void MESH_OT_smoothen_normals(struct wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_smoothen_normals_exec; - ot->poll = ED_operator_editmesh_auto_smooth; + ot->poll = ED_operator_editmesh; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -9018,7 +9025,7 @@ void MESH_OT_mod_weighted_strength(struct wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_mod_weighted_strength_exec; - ot->poll = ED_operator_editmesh_auto_smooth; + ot->poll = ED_operator_editmesh; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index e29cfa6b6e0..41736fb9a14 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -61,6 +61,7 @@ #include "DEG_depsgraph_query.h" #include "ED_mesh.h" +#include "ED_select_buffer_utils.h" #include "ED_object.h" #include "ED_view3d.h" @@ -1114,11 +1115,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_view3d_select_id_read_nearest(&vc, mval, 1, me->totpoly + 1, &dist_px); + *r_index = ED_select_buffer_find_nearest_to_point(mval, 1, me->totpoly + 1, &dist_px); } else { /* sample only on the exact position */ - *r_index = ED_view3d_select_id_sample(&vc, mval[0], mval[1]); + *r_index = ED_select_buffer_sample_point(mval); } if ((*r_index) == 0 || (*r_index) > (unsigned int)me->totpoly) { @@ -1295,11 +1296,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_view3d_select_id_read_nearest(&vc, mval, 1, me->totvert + 1, &dist_px); + *r_index = ED_select_buffer_find_nearest_to_point(mval, 1, me->totvert + 1, &dist_px); } else { /* sample only on the exact position */ - *r_index = ED_view3d_select_id_sample(&vc, mval[0], mval[1]); + *r_index = ED_select_buffer_sample_point(mval); } if ((*r_index) == 0 || (*r_index) > (uint)me->totvert) { |