[Bf-blender-cvs] [d00de988c36] master: WM: avoid unnecessary undo step creation when duplicating

Pratik Borhade noreply at git.blender.org
Tue Apr 5 12:30:37 CEST 2022


Commit: d00de988c36a6bde9bccdd75cd544085df2d472c
Author: Pratik Borhade
Date:   Tue Apr 5 20:13:03 2022 +1000
Branches: master
https://developer.blender.org/rBd00de988c36a6bde9bccdd75cd544085df2d472c

WM: avoid unnecessary undo step creation when duplicating

Calling duplicate operation without selecting anything registers an undo
step. If nothing is selected (keyframe, curve, object, etc.), cancel the
operator execution to prevent undo push.

Patch improves following operators:

- ACTION_OT_duplicate
- GPENCIL_OT_duplicate
- GRAPH_OT_duplicate
- MESH_OT_duplicate
- NODE_OT_duplicate
- OBJECT_OT_duplicate

Reviewed By: campbellbarton

Ref D14511

===================================================================

M	source/blender/editors/animation/keyframes_general.c
M	source/blender/editors/gpencil/gpencil_edit.c
M	source/blender/editors/include/ED_keyframes_edit.h
M	source/blender/editors/mesh/editmesh_tools.c
M	source/blender/editors/object/object_add.cc
M	source/blender/editors/space_action/action_edit.c
M	source/blender/editors/space_graph/graph_edit.c
M	source/blender/editors/space_node/node_edit.cc

===================================================================

diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index aec2b0f769a..00e2f221117 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -118,11 +118,13 @@ void clear_fcurve_keys(FCurve *fcu)
 
 /* ---------------- */
 
-void duplicate_fcurve_keys(FCurve *fcu)
+bool duplicate_fcurve_keys(FCurve *fcu)
 {
+  bool changed = false;
+
   /* this can only work when there is an F-Curve, and also when there are some BezTriples */
   if (ELEM(NULL, fcu, fcu->bezt)) {
-    return;
+    return changed;
   }
 
   for (int i = 0; i < fcu->totvert; i++) {
@@ -135,7 +137,7 @@ void duplicate_fcurve_keys(FCurve *fcu)
       memcpy(newbezt + i + 1, fcu->bezt + i, sizeof(BezTriple));
       memcpy(newbezt + i + 2, fcu->bezt + i + 1, sizeof(BezTriple) * (fcu->totvert - (i + 1)));
       fcu->totvert++;
-
+      changed = true;
       /* reassign pointers... (free old, and add new) */
       MEM_freeN(fcu->bezt);
       fcu->bezt = newbezt;
@@ -148,6 +150,7 @@ void duplicate_fcurve_keys(FCurve *fcu)
       BEZT_SEL_ALL(&fcu->bezt[i]);
     }
   }
+  return changed;
 }
 
 /* **************************************************** */
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index a8fb344f366..3c8e6d6e5f5 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -994,9 +994,10 @@ static int gpencil_duplicate_exec(bContext *C, wmOperator *op)
     /* updates */
     DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
     WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
+    return OPERATOR_FINISHED;
   }
 
-  return OPERATOR_FINISHED;
+  return OPERATOR_CANCELLED;
 }
 
 void GPENCIL_OT_duplicate(wmOperatorType *ot)
diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h
index 3a0bb9738ae..163797d395d 100644
--- a/source/blender/editors/include/ED_keyframes_edit.h
+++ b/source/blender/editors/include/ED_keyframes_edit.h
@@ -381,7 +381,7 @@ bool keyframe_region_circle_test(const KeyframeEdit_CircleData *data_circle, con
 void delete_fcurve_key(struct FCurve *fcu, int index, bool do_recalc);
 bool delete_fcurve_keys(struct FCurve *fcu);
 void clear_fcurve_keys(struct FCurve *fcu);
-void duplicate_fcurve_keys(struct FCurve *fcu);
+bool duplicate_fcurve_keys(struct FCurve *fcu);
 float get_default_rna_value(struct FCurve *fcu, struct PropertyRNA *prop, struct PointerRNA *ptr);
 
 typedef struct FCurveSegment {
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 1499742af54..0b2944657fd 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -2014,6 +2014,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
   uint objects_len = 0;
   Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
       view_layer, CTX_wm_view3d(C), &objects_len);
+  bool changed = false;
 
   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
     Object *obedit = objects[ob_index];
@@ -2024,6 +2025,7 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
 
     BMOperator bmop;
     BMesh *bm = em->bm;
+    changed = true;
 
     EDBM_op_init(em,
                  &bmop,
@@ -2058,16 +2060,16 @@ static int edbm_duplicate_exec(bContext *C, wmOperator *op)
   }
   MEM_freeN(objects);
 
-  return OPERATOR_FINISHED;
+  return (changed) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
 }
 
 static int edbm_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
 {
   WM_cursor_wait(true);
-  edbm_duplicate_exec(C, op);
+  const int retval = edbm_duplicate_exec(C, op);
   WM_cursor_wait(false);
 
-  return OPERATOR_FINISHED;
+  return retval;
 }
 
 void MESH_OT_duplicate(wmOperatorType *ot)
diff --git a/source/blender/editors/object/object_add.cc b/source/blender/editors/object/object_add.cc
index 6a7920d4d75..ba11483722e 100644
--- a/source/blender/editors/object/object_add.cc
+++ b/source/blender/editors/object/object_add.cc
@@ -3564,6 +3564,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
   ViewLayer *view_layer = CTX_data_view_layer(C);
   const bool linked = RNA_boolean_get(op->ptr, "linked");
   const eDupli_ID_Flags dupflag = (linked) ? (eDupli_ID_Flags)0 : (eDupli_ID_Flags)U.dupflag;
+  bool changed = false;
 
   /* We need to handle that here ourselves, because we may duplicate several objects, in which case
    * we also want to remap pointers between those... */
@@ -3582,6 +3583,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
      * the list is made in advance */
     ED_object_base_select(base, BA_DESELECT);
     ED_object_base_select(basen, BA_SELECT);
+    changed = true;
 
     if (basen == nullptr) {
       continue;
@@ -3598,6 +3600,10 @@ static int duplicate_exec(bContext *C, wmOperator *op)
   }
   CTX_DATA_END;
 
+  if (!changed) {
+    return OPERATOR_CANCELLED;
+  }
+
   /* Note that this will also clear newid pointers and tags. */
   copy_object_set_idnew(C);
 
diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index d33cf70e117..87a271543d1 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -878,11 +878,12 @@ void ACTION_OT_keyframe_insert(wmOperatorType *ot)
 
 /* ******************** Duplicate Keyframes Operator ************************* */
 
-static void duplicate_action_keys(bAnimContext *ac)
+static bool duplicate_action_keys(bAnimContext *ac)
 {
   ListBase anim_data = {NULL, NULL};
   bAnimListElem *ale;
   int filter;
+  bool changed = false;
 
   /* filter data */
   if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
@@ -898,10 +899,11 @@ static void duplicate_action_keys(bAnimContext *ac)
   /* loop through filtered data and delete selected keys */
   for (ale = anim_data.first; ale; ale = ale->next) {
     if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
-      duplicate_fcurve_keys((FCurve *)ale->key_data);
+      changed |= duplicate_fcurve_keys((FCurve *)ale->key_data);
     }
     else if (ale->type == ANIMTYPE_GPLAYER) {
       ED_gpencil_layer_frames_duplicate((bGPDlayer *)ale->data);
+      changed |= ED_gpencil_layer_frame_select_check((bGPDlayer *)ale->data);
     }
     else if (ale->type == ANIMTYPE_MASKLAYER) {
       ED_masklayer_frames_duplicate((MaskLayer *)ale->data);
@@ -915,6 +917,8 @@ static void duplicate_action_keys(bAnimContext *ac)
 
   ANIM_animdata_update(ac, &anim_data);
   ANIM_animdata_freelist(&anim_data);
+
+  return changed;
 }
 
 /* ------------------- */
@@ -929,7 +933,9 @@ static int actkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
   }
 
   /* duplicate keyframes */
-  duplicate_action_keys(&ac);
+  if (!duplicate_action_keys(&ac)) {
+    return OPERATOR_CANCELLED;
+  }
 
   /* set notifier that keyframes have changed */
   WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index bc82e7e20c2..2083a26f638 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -623,11 +623,12 @@ void GRAPH_OT_paste(wmOperatorType *ot)
 /** \name Duplicate Keyframes Operator
  * \{ */
 
-static void duplicate_graph_keys(bAnimContext *ac)
+static bool duplicate_graph_keys(bAnimContext *ac)
 {
   ListBase anim_data = {NULL, NULL};
   bAnimListElem *ale;
   int filter;
+  bool changed = false;
 
   /* Filter data. */
   filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_FOREDIT |
@@ -636,13 +637,15 @@ static void duplicate_graph_keys(bAnimContext *ac)
 
   /* Loop through filtered data and delete selected keys. */
   for (ale = anim_data.first; ale; ale = ale->next) {
-    duplicate_fcurve_keys((FCurve *)ale->key_data);
+    changed |= duplicate_fcurve_keys((FCurve *)ale->key_data);
 
     ale->update |= ANIM_UPDATE_DEFAULT;
   }
 
   ANIM_animdata_update(ac, &anim_data);
   ANIM_animdata_freelist(&anim_data);
+
+  return changed;
 }
 
 /* ------------------- */
@@ -657,7 +660,9 @@ static int graphkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
   }
 
   /* Duplicate keyframes. */
-  duplicate_graph_keys(&ac);
+  if (!duplicate_graph_keys(&ac)) {
+    return OPERATOR_CANCELLED;
+  }
 
   /* Set notifier that keyframes have changed. */
   WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc
index 956bb581ee6..9d83f977fe0 100644
--- a/source/blender/editors/space_node/node_edit.cc
+++ b/source/blender/editors/space_node/node_edit.cc
@@ -1268,6 +1268,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
   SpaceNode *snode = CTX_wm_space_node(C);
   bNodeTree *ntree = snode->edittree;
   const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
+  bool changed = false;
 
   ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
 
@@ -1280,6 +1281,7 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
       bNode *new_node = blender::bke::node_copy_with_mapping(
           ntree, *node, LIB_ID_COPY_DEFAULT, true, socket_map);
       node_map.add_new(node, new_node);
+      changed = true;
     }
 
     /* make sure we don't copy new nodes again! */
@@ -1288,6 +1290,10 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
     }
   }
 
+  if (!changed) {
+    return OPERATOR_CANCELLED;
+  }
+
   /* Copy links between selected nodes. */
   bNodeLink *lastlink = (bNodeLink *)ntree->links.last;
   LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {



More information about the Bf-blender-cvs mailing list