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:
authorCampbell Barton <ideasman42@gmail.com>2020-10-13 08:51:20 +0300
committerJeroen Bakker <jeroen@blender.org>2020-10-28 11:34:41 +0300
commitd5555115e121eac0960f2de981b8dcdd175bcf49 (patch)
treef08a2d03e1d879bd7c4e78e15a628f3f3cd9c9a7
parent0845dc0eece716947148ecc11a2276b0f5634f65 (diff)
Fix T81288:Select Linked fails with multi-object edit mode
Changing options after using select-linked didn't work when the object being selected wasn't the active object.
-rw-r--r--source/blender/editors/mesh/editmesh_select.c40
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c43
-rw-r--r--source/blender/editors/mesh/mesh_intern.h9
3 files changed, 77 insertions, 15 deletions
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index fe83d9f00ea..02fc123cdf2 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -3588,13 +3588,17 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
edbm_select_linked_pick_ex(em, ele, sel, delimit);
- /* to support redo */
- BM_mesh_elem_index_ensure(bm, ele->head.htype);
- index = EDBM_elem_to_index_any(em, ele);
-
- /* TODO(MULTI_EDIT), index doesn't know which object,
- * index selections isn't very common. */
- RNA_int_set(op->ptr, "index", index);
+ /* To support redo. */
+ {
+ /* Note that the `base_index` can't be used as the index depends on the view-port
+ * which might not be available on redo. */
+ BM_mesh_elem_index_ensure(bm, ele->head.htype);
+ int object_index;
+ index = EDBM_elem_to_index_any_multi(vc.view_layer, em, ele, &object_index);
+ BLI_assert(object_index >= 0);
+ RNA_int_set(op->ptr, "object_index", object_index);
+ RNA_int_set(op->ptr, "index", index);
+ }
DEG_id_tag_update(basact->object->data, ID_RECALC_SELECT);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, basact->object->data);
@@ -3605,18 +3609,22 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
static int edbm_select_linked_pick_exec(bContext *C, wmOperator *op)
{
- Object *obedit = CTX_data_edit_object(C);
- BMEditMesh *em = BKE_editmesh_from_object(obedit);
- BMesh *bm = em->bm;
- int index;
- const bool sel = !RNA_boolean_get(op->ptr, "deselect");
+ Object *obedit = NULL;
+ BMElem *ele;
+
+ {
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ const int object_index = RNA_int_get(op->ptr, "object_index");
+ const int index = RNA_int_get(op->ptr, "index");
+ ele = EDBM_elem_from_index_any_multi(view_layer, object_index, index, &obedit);
+ }
- index = RNA_int_get(op->ptr, "index");
- if (index < 0 || index >= (bm->totvert + bm->totedge + bm->totface)) {
+ if (ele == NULL) {
return OPERATOR_CANCELLED;
}
- BMElem *ele = EDBM_elem_from_index_any(em, index);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ const bool sel = !RNA_boolean_get(op->ptr, "deselect");
#ifdef USE_LINKED_SELECT_DEFAULT_HACK
int delimit = select_linked_delimit_default_from_op(op, em->selectmode);
@@ -3661,6 +3669,8 @@ void MESH_OT_select_linked_pick(wmOperatorType *ot)
#endif
/* use for redo */
+ prop = RNA_def_int(ot->srna, "object_index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
+ RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
prop = RNA_def_int(ot->srna, "index", -1, -1, INT_MAX, "", "", 0, INT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
}
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index a26003d78ed..68e51762cd2 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -38,6 +38,7 @@
#include "BKE_editmesh.h"
#include "BKE_editmesh_bvh.h"
#include "BKE_global.h"
+#include "BKE_layer.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
@@ -1549,6 +1550,48 @@ BMElem *EDBM_elem_from_index_any(BMEditMesh *em, int index)
return NULL;
}
+int EDBM_elem_to_index_any_multi(ViewLayer *view_layer,
+ BMEditMesh *em,
+ BMElem *ele,
+ int *r_object_index)
+{
+ uint bases_len;
+ int elem_index = -1;
+ *r_object_index = -1;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(view_layer, NULL, &bases_len);
+ for (uint base_index = 0; base_index < bases_len; base_index++) {
+ Base *base_iter = bases[base_index];
+ if (BKE_editmesh_from_object(base_iter->object) == em) {
+ *r_object_index = base_index;
+ elem_index = EDBM_elem_to_index_any(em, ele);
+ break;
+ }
+ }
+ MEM_freeN(bases);
+ return elem_index;
+}
+
+BMElem *EDBM_elem_from_index_any_multi(ViewLayer *view_layer,
+ int object_index,
+ int elem_index,
+ Object **r_obedit)
+{
+ uint bases_len;
+ Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(view_layer, NULL, &bases_len);
+ *r_obedit = NULL;
+ Object *obedit = ((uint)object_index < bases_len) ? bases[object_index]->object : NULL;
+ MEM_freeN(bases);
+ if (obedit != NULL) {
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMElem *ele = EDBM_elem_from_index_any(em, elem_index);
+ if (ele != NULL) {
+ *r_obedit = obedit;
+ return ele;
+ }
+ }
+ return NULL;
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 5e70069456b..ee957b69002 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -79,6 +79,15 @@ struct BMElem *EDBM_elem_from_selectmode(struct BMEditMesh *em,
int EDBM_elem_to_index_any(struct BMEditMesh *em, struct BMElem *ele);
struct BMElem *EDBM_elem_from_index_any(struct BMEditMesh *em, int index);
+int EDBM_elem_to_index_any_multi(struct ViewLayer *view_layer,
+ struct BMEditMesh *em,
+ struct BMElem *ele,
+ int *r_object_index);
+struct BMElem *EDBM_elem_from_index_any_multi(struct ViewLayer *view_layer,
+ int object_index,
+ int elem_index,
+ struct Object **r_obedit);
+
bool edbm_extrude_edges_indiv(struct BMEditMesh *em,
struct wmOperator *op,
const char hflag,