From f0f70729b10ecb633a0005bc9f70b62a595a43d7 Mon Sep 17 00:00:00 2001 From: Cian Jinks Date: Tue, 28 Sep 2021 23:06:58 +0100 Subject: Fix: Knife undo with no cut segments left Now if a user presses the knife tool undo key when there are no more cut segments to undo, the operator exits. Previously, it did nothing. --- source/blender/editors/mesh/editmesh_knife.c | 104 ++++++++++++++------------- 1 file changed, 54 insertions(+), 50 deletions(-) (limited to 'source/blender/editors/mesh/editmesh_knife.c') diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 4fa8df0b672..64c008acf8e 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -3899,71 +3899,69 @@ static void knifetool_undo(KnifeTool_OpData *kcd) KnifeUndoFrame *undo; BLI_mempool_iter iterkfe; - if (!BLI_stack_is_empty(kcd->undostack)) { - undo = BLI_stack_peek(kcd->undostack); + undo = BLI_stack_peek(kcd->undostack); - /* Undo edge splitting. */ - for (int i = 0; i < undo->splits; i++) { - BLI_stack_pop(kcd->splitstack, &newkfe); - BLI_stack_pop(kcd->splitstack, &kfe); - knife_join_edge(newkfe, kfe); - } + /* Undo edge splitting. */ + for (int i = 0; i < undo->splits; i++) { + BLI_stack_pop(kcd->splitstack, &newkfe); + BLI_stack_pop(kcd->splitstack, &kfe); + knife_join_edge(newkfe, kfe); + } - for (int i = 0; i < undo->cuts; i++) { + for (int i = 0; i < undo->cuts; i++) { - BLI_mempool_iternew(kcd->kedges, &iterkfe); - for (kfe = BLI_mempool_iterstep(&iterkfe); kfe; kfe = BLI_mempool_iterstep(&iterkfe)) { - if (!kfe->is_cut || kfe->is_invalid || kfe->splits) { - continue; - } - lastkfe = kfe; + BLI_mempool_iternew(kcd->kedges, &iterkfe); + for (kfe = BLI_mempool_iterstep(&iterkfe); kfe; kfe = BLI_mempool_iterstep(&iterkfe)) { + if (!kfe->is_cut || kfe->is_invalid || kfe->splits) { + continue; } + lastkfe = kfe; + } - if (lastkfe) { - lastkfe->is_invalid = true; - - /* TODO: Are they always guaranteed to be in this order? */ - v1 = lastkfe->v1; - v2 = lastkfe->v2; - - /* Only remove first vertex if it is the start segment of the cut. */ - if (!v1->is_invalid && !v1->is_splitting) { - v1->is_invalid = true; - /* If the first vertex is touching any other cut edges don't remove it. */ - for (ref = v1->edges.first; ref; ref = ref->next) { - kfe = ref->ref; - if (kfe->is_cut && !kfe->is_invalid) { - v1->is_invalid = false; - break; - } + if (lastkfe) { + lastkfe->is_invalid = true; + + /* TODO: Are they always guaranteed to be in this order? */ + v1 = lastkfe->v1; + v2 = lastkfe->v2; + + /* Only remove first vertex if it is the start segment of the cut. */ + if (!v1->is_invalid && !v1->is_splitting) { + v1->is_invalid = true; + /* If the first vertex is touching any other cut edges don't remove it. */ + for (ref = v1->edges.first; ref; ref = ref->next) { + kfe = ref->ref; + if (kfe->is_cut && !kfe->is_invalid) { + v1->is_invalid = false; + break; } } + } - /* Only remove second vertex if it is the end segment of the cut. */ - if (!v2->is_invalid && !v2->is_splitting) { - v2->is_invalid = true; - /* If the second vertex is touching any other cut edges don't remove it. */ - for (ref = v2->edges.first; ref; ref = ref->next) { - kfe = ref->ref; - if (kfe->is_cut && !kfe->is_invalid) { - v2->is_invalid = false; - break; - } + /* Only remove second vertex if it is the end segment of the cut. */ + if (!v2->is_invalid && !v2->is_splitting) { + v2->is_invalid = true; + /* If the second vertex is touching any other cut edges don't remove it. */ + for (ref = v2->edges.first; ref; ref = ref->next) { + kfe = ref->ref; + if (kfe->is_cut && !kfe->is_invalid) { + v2->is_invalid = false; + break; } } } } + } - if (kcd->mode == MODE_DRAGGING) { - /* Restore kcd->prev. */ - kcd->prev = undo->pos; - } + if (kcd->mode == MODE_DRAGGING) { + /* Restore kcd->prev. */ + kcd->prev = undo->pos; + } - /* Restore data for distance and angle measurements. */ - kcd->mdata = undo->mdata; + /* Restore data for distance and angle measurements. */ + kcd->mdata = undo->mdata; - BLI_stack_discard(kcd->undostack); - } + BLI_stack_discard(kcd->undostack); } /** \} */ @@ -4406,6 +4404,12 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_FINISHED; case KNF_MODAL_UNDO: + if (BLI_stack_is_empty(kcd->undostack)) { + ED_region_tag_redraw(kcd->region); + knifetool_exit(op); + ED_workspace_status_text(C, NULL); + return OPERATOR_CANCELLED; + } knifetool_undo(kcd); knife_update_active(C, kcd); ED_region_tag_redraw(kcd->region); -- cgit v1.2.3