[Bf-blender-cvs] [d5555115e12] blender-v2.83-release: Fix T81288:Select Linked fails with multi-object edit mode

Campbell Barton noreply at git.blender.org
Wed Oct 28 09:55:52 CET 2020


Commit: d5555115e121eac0960f2de981b8dcdd175bcf49
Author: Campbell Barton
Date:   Tue Oct 13 16:51:20 2020 +1100
Branches: blender-v2.83-release
https://developer.blender.org/rBd5555115e121eac0960f2de981b8dcdd175bcf49

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.

===================================================================

M	source/blender/editors/mesh/editmesh_select.c
M	source/blender/editors/mesh/editmesh_utils.c
M	source/blender/editors/mesh/mesh_intern.h

===================================================================

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,



More information about the Bf-blender-cvs mailing list