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.
This commit is contained in:
parent
65965a892f
commit
211d7ff3cf
Notes:
blender-bot
2023-02-14 06:17:14 +01:00
Referenced by issue #89367, Running select_linked_pick with a negative index crashes Blender with an access violation Referenced by issue #81288, 'Delimit' in 'Select Linked' works unexpectedly when editing multiple objects Referenced by issue #77348, Blender LTS: Maintenance Task 2.83
|
@ -3572,13 +3572,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);
|
||||
|
@ -3589,18 +3593,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;
|
||||
|
||||
index = RNA_int_get(op->ptr, "index");
|
||||
if (index < 0 || index >= (bm->totvert + bm->totedge + bm->totface)) {
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -3645,6 +3653,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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
@ -1557,6 +1558,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;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue