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:
authorYimingWu <xp8110@outlook.com>2019-05-28 10:39:42 +0300
committerYimingWu <xp8110@outlook.com>2019-05-28 10:39:42 +0300
commitf37533fc44cfb8a7eec919df0dae38998de10e2f (patch)
tree264074656a88f96bdc3a4dbf53340277d45dc86a /source/blender/editors/mesh
parenta640228d92273154acc644d525b095b5318c248b (diff)
parent1008d9c73567780ec22bea6a0b27f57e60ea403d (diff)
Merge branch 'master' into soc-2019-npr
Diffstat (limited to 'source/blender/editors/mesh')
-rw-r--r--source/blender/editors/mesh/editface.c68
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c6
-rw-r--r--source/blender/editors/mesh/editmesh_extrude_spin_gizmo.c3
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c5
-rw-r--r--source/blender/editors/mesh/editmesh_path.c83
-rw-r--r--source/blender/editors/mesh/editmesh_select.c273
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c23
-rw-r--r--source/blender/editors/mesh/meshtools.c9
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) {