GPencil: fix separate points/strokes freezing with empty selection
Code would still create an object (without setting up materials), code for removing unused material slots would then freeze. Now return/cancel early in case of empty selection. This came up in T88269 [which is still not fully fixed, transforming curve edit points clear their GP_STROKE_SELECT flag which now results in the early exit, should be looked at separately] Maniphest Tasks: T88269 Differential Revision: https://developer.blender.org/D11252
This commit is contained in:
parent
d19d79c5a6
commit
c3e13d5a2b
Notes:
blender-bot
2023-02-14 06:49:57 +01:00
Referenced by issue #88269, Crash in Curve Editing.
|
@ -4520,6 +4520,9 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
|
|||
|
||||
eGP_SeparateModes mode = RNA_enum_get(op->ptr, "mode");
|
||||
|
||||
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_src);
|
||||
const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd_src);
|
||||
|
||||
/* sanity checks */
|
||||
if (ELEM(NULL, gpd_src)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
|
@ -4530,8 +4533,22 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_src);
|
||||
const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd_src);
|
||||
/* Cancel if nothing selected. */
|
||||
if (ELEM(mode, GP_SEPARATE_POINT, GP_SEPARATE_STROKE)) {
|
||||
bool has_selected = false;
|
||||
CTX_DATA_BEGIN (C, bGPDlayer *, gpl, editable_gpencil_layers) {
|
||||
if (ED_gpencil_layer_has_selected_stroke(gpl, is_multiedit)) {
|
||||
has_selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
if (!has_selected) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Nothing selected");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a new object. */
|
||||
/* Take into account user preferences for duplicating actions. */
|
||||
|
|
|
@ -542,6 +542,38 @@ bool gpencil_stroke_inside_circle(const float mval[2], int rad, int x0, int y0,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* ******************************************************** */
|
||||
/* Selection Validity Testing */
|
||||
|
||||
bool ED_gpencil_frame_has_selected_stroke(const bGPDframe *gpf)
|
||||
{
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
if (gps->flag & GP_STROKE_SELECT) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ED_gpencil_layer_has_selected_stroke(const bGPDlayer *gpl, const bool is_multiedit)
|
||||
{
|
||||
bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe;
|
||||
for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
|
||||
if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
|
||||
if (ED_gpencil_frame_has_selected_stroke(gpf)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/* If not multiedit, exit loop. */
|
||||
if (!is_multiedit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* ******************************************************** */
|
||||
/* Stroke Validity Testing */
|
||||
|
||||
|
|
|
@ -144,6 +144,8 @@ bool ED_gpencil_data_owner_is_annotation(struct PointerRNA *owner_ptr);
|
|||
bool ED_gpencil_has_keyframe_v3d(struct Scene *scene, struct Object *ob, int cfra);
|
||||
|
||||
/* ----------- Stroke Editing Utilities ---------------- */
|
||||
bool ED_gpencil_frame_has_selected_stroke(const struct bGPDframe *gpf);
|
||||
bool ED_gpencil_layer_has_selected_stroke(const struct bGPDlayer *gpl, const bool is_multiedit);
|
||||
|
||||
bool ED_gpencil_stroke_can_use_direct(const struct ScrArea *area, const struct bGPDstroke *gps);
|
||||
bool ED_gpencil_stroke_can_use(const struct bContext *C, const struct bGPDstroke *gps);
|
||||
|
|
Loading…
Reference in New Issue