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:
committed by
Campbell Barton
parent
2752b8a400
commit
04a499bc5a
@@ -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);
|
||||
|
||||
@@ -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).
|
||||
*/
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
Reference in New Issue
Block a user