diff options
author | Philipp Oeser <info@graphics-engineer.com> | 2022-04-28 14:51:14 +0300 |
---|---|---|
committer | Philipp Oeser <info@graphics-engineer.com> | 2022-05-03 10:46:18 +0300 |
commit | cc0c4c17f011f7f687f7719aab1568c9a5a38217 (patch) | |
tree | b3d49c86a0a32c4b4780eb2c15780a71e62083e6 /source/blender/editors/transform/transform_ops.c | |
parent | 1a6d0ec71cf3b0c2c22bc1b125135b1e9679c390 (diff) |
Fix T95752: crash 'Select Linked' after loopcut in multiobject editmode
This was reported explicitly for originally being in face selectmode,
but could also crash when in vertex selectmode (when doing multiple
cuts).
The reason here is that `MESH_OT_loopcut` switches to edge select mode
(needed for `TRANSFORM_OT_edge_slide`, done in `ringsel_finish`), but was
only doing this on the active object's editmesh, all other participating
meshes would keep their selectmode which would now be out of sync with
both the active object's editmesh and scene settings for these.
This causes problems later in 'Select Linked'. Here, a mixture of
objects are used. First the viewcontext is set up with the active
object, then all participating objects are iterated (changing the
viewcontext to another object), then `unified_findnearest` would use that
changed viewcontext which would now contain the last object iterated. To
repeat: this could now have a different selectmode than the active
object which is later **again** used to get the nearest `BMElem` from in
`EDBM_elem_from_selectmode`. So in the failing case, we could get an
edge (but no face because of edge selectmode) from `unified_findnearest`,
`EDBM_elem_from_selectmode` would return NULL though (edge provided, but
in face selectmode), leading to the crash.
To solve this I assume it is best to change selectmode on all
participating meshes in multi-object editmode loopcut if necessary so
these are always in sync for following operations.
Alternatively, `Select Linked` (and probably lots more operators) would
have to be tweaked to pay closer attention which object is really used
to get selectmode from.
Note the selectmode is actually set back from edge selectmode in certain
cases (see `USE_LOOPSLIDE_HACK`), this patch changes that as well to act
on all participating meshes.
Maniphest Tasks: T95752
Differential Revision: https://developer.blender.org/D14791
Diffstat (limited to 'source/blender/editors/transform/transform_ops.c')
-rw-r--r-- | source/blender/editors/transform/transform_ops.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index ec49cef4067..600f525b428 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -315,6 +315,8 @@ static void TRANSFORM_OT_create_orientation(struct wmOperatorType *ot) #ifdef USE_LOOPSLIDE_HACK /** * Special hack for MESH_OT_loopcut_slide so we get back to the selection mode + * Do this for all meshes in multi-object editmode so their selectmode is in sync for following + * operators */ static void transformops_loopsel_hack(bContext *C, wmOperator *op) { @@ -334,12 +336,10 @@ static void transformops_loopsel_hack(bContext *C, wmOperator *op) (mesh_select_mode[1] ? SCE_SELECT_EDGE : 0) | (mesh_select_mode[2] ? SCE_SELECT_FACE : 0)); - /* still switch if we were originally in face select mode */ + /* Still switch if we were originally in face select mode. */ if ((ts->selectmode != selectmode_orig) && (selectmode_orig != SCE_SELECT_FACE)) { - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BKE_editmesh_from_object(obedit); - em->selectmode = ts->selectmode = selectmode_orig; - EDBM_selectmode_set(em); + ts->selectmode = selectmode_orig; + EDBM_selectmode_set_multi(C, selectmode_orig); } } } |