Fix #147150: Crash when trying to merge vertex and edge

The operator passed edges into BM_edge_exists, which asserts both
inputs must be vertices. Mixed selections are now rejected with an
error message, preventing the assert and crash.

Ref !147239
This commit is contained in:
tariqsulley
2025-10-02 19:56:57 +00:00
committed by Campbell Barton
parent 2752b8a400
commit 04a499bc5a
3 changed files with 33 additions and 1 deletions

View File

@@ -1116,6 +1116,19 @@ void BM_select_history_validate(BMesh *bm)
}
}
char BM_select_history_htype_all(const BMesh *bm)
{
char htype_selected = 0;
LISTBASE_FOREACH (const BMEditSelection *, ese, &bm->selected) {
htype_selected |= ese->htype;
/* Early exit if all types found. */
if (htype_selected == (BM_VERT | BM_EDGE | BM_FACE)) {
break;
}
}
return htype_selected;
}
bool BM_select_history_active_get(BMesh *bm, BMEditSelection *ese)
{
BMEditSelection *ese_last = static_cast<BMEditSelection *>(bm->selected.last);

View File

@@ -171,6 +171,10 @@ void _bm_select_history_store_after_notest(BMesh *bm, BMEditSelection *ese_ref,
void BM_select_history_validate(BMesh *bm);
void BM_select_history_clear(BMesh *bm);
/**
* Get all element types present in a selection history.
*/
[[nodiscard]] char BM_select_history_htype_all(const BMesh *bm);
/**
* Get the active mesh element (with active-face fallback).
*/

View File

@@ -25,6 +25,7 @@
#include "BLI_linklist.h"
#include "BLI_linklist_stack.h"
#include "BLI_listbase.h"
#include "BLI_math_bits.h"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
#include "BLI_math_rotation.h"
@@ -1542,6 +1543,7 @@ static wmOperatorStatus edbm_vert_connect_path_exec(bContext *C, wmOperator *op)
ViewLayer *view_layer = CTX_data_view_layer(C);
uint failed_selection_order_len = 0;
uint failed_connect_len = 0;
bool has_select_history_mixed = false;
const Vector<Object *> objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
scene, view_layer, CTX_wm_view3d(C));
@@ -1563,6 +1565,14 @@ static wmOperatorStatus edbm_vert_connect_path_exec(bContext *C, wmOperator *op)
continue;
}
/* Skip mixed selections since path handling only supports uniform types, see #147150. */
const char htype_selected = BM_select_history_htype_all(bm);
if (count_bits_i(htype_selected) > 1) {
has_select_history_mixed = true;
failed_selection_order_len++;
continue;
}
if (bm->selected.first) {
BMEditSelection *ese = static_cast<BMEditSelection *>(bm->selected.first);
if (ese->htype == BM_EDGE) {
@@ -1596,7 +1606,12 @@ static wmOperatorStatus edbm_vert_connect_path_exec(bContext *C, wmOperator *op)
}
if (failed_selection_order_len == objects.size()) {
BKE_report(op->reports, RPT_ERROR, "Invalid selection order");
if (has_select_history_mixed) {
BKE_report(op->reports, RPT_ERROR, "Could not connect mixed selection types");
}
else {
BKE_report(op->reports, RPT_ERROR, "Invalid selection order");
}
return OPERATOR_CANCELLED;
}
if (failed_connect_len == objects.size()) {