Merge branch 'master' into blender2.8
authorSybren A. Stüvel <sybren@stuvel.eu>
Wed, 17 Jan 2018 11:21:05 +0000 (12:21 +0100)
committerSybren A. Stüvel <sybren@stuvel.eu>
Wed, 17 Jan 2018 11:21:05 +0000 (12:21 +0100)
release/scripts/startup/bl_ui/space_graph.py
source/blender/editors/space_graph/graph_edit.c
source/blender/editors/space_graph/graph_intern.h
source/blender/editors/space_graph/graph_ops.c

index 4938512070e3beeb13cfbb684f6d0781f195f78b..e2407f1f2b27a918ab5b767d2fcda2ed824e8f7f 100644 (file)
@@ -201,6 +201,8 @@ class GRAPH_MT_channel(Menu):
         layout.operator_context = 'INVOKE_REGION_CHANNELS'
 
         layout.operator("anim.channels_delete")
+        if context.space_data.mode == 'DRIVERS':
+            layout.operator("graph.driver_delete_invalid")
 
         layout.separator()
         layout.operator("anim.channels_group")
index 2876fccaa51a0f34acbdc606f9e88521818b8833..0a8e49fc671fbbe9d6f7bd31a85647fbae4e0ebf 100644 (file)
@@ -2747,3 +2747,92 @@ void GRAPH_OT_driver_variables_paste(wmOperatorType *ot)
 }
 
 /* ************************************************************************** */
+typedef struct InvalidDriverInfo {
+       struct InvalidDriverInfo *next, *prev;
+       ID *id;
+       FCurve *fcu;
+} InvalidDriverInfo;
+
+static int graph_driver_delete_invalid_exec(bContext *C, wmOperator *op)
+{
+       bAnimContext ac;
+       ListBase anim_data = {NULL, NULL};
+       ListBase to_delete = {NULL, NULL};
+       bAnimListElem *ale;
+       InvalidDriverInfo *idi;
+       int filter;
+       bool ok = false;
+       unsigned int deleted = 0;
+
+       /* get editor data */
+       if (ANIM_animdata_get_context(C, &ac) == 0)
+               return OPERATOR_CANCELLED;
+
+       /* NOTE: we might need a scene update to evaluate the driver flags */
+
+       /* filter data */
+       filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE);
+       ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+       /* find invalid drivers */
+       for (ale = anim_data.first; ale; ale = ale->next) {
+               FCurve *fcu = (FCurve *)ale->data;
+               if (ELEM(NULL, fcu, fcu->driver)) {
+                       continue;
+               }
+               if (!(fcu->driver->flag & DRIVER_FLAG_INVALID)) {
+                       continue;
+               }
+
+               /* remember in a separate list so we don't iterate over the same collection we modify */
+               idi = MEM_callocN(sizeof(InvalidDriverInfo), "invalid driver info");
+               BLI_assert(idi != NULL);
+               idi->id = ale->id;
+               idi->fcu = fcu;
+               BLI_addtail(&to_delete, idi);
+       }
+
+       /* delete invalid drivers */
+       for (idi = to_delete.first; idi; idi = idi->next) {
+               ok |= ANIM_remove_driver(op->reports, idi->id, idi->fcu->rna_path, idi->fcu->array_index, 0);
+               if (!ok) {
+                       break;
+               }
+               deleted += 1;
+       }
+
+       /* cleanup */
+       BLI_freelistN(&to_delete);
+       ANIM_animdata_freelist(&anim_data);
+
+       if (deleted > 0) {
+               /* notify the world of any changes */
+               DEG_relations_tag_update(CTX_data_main(C));
+               WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
+               WM_reportf(RPT_INFO, "Deleted %u drivers", deleted);
+       } else {
+               WM_report(RPT_INFO, "No drivers deleted");
+       }
+
+       /* successful or not? */
+       if (!ok) {
+               return OPERATOR_CANCELLED;
+       }
+
+       return OPERATOR_FINISHED;
+}
+
+void GRAPH_OT_driver_delete_invalid(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Delete Invalid Drivers";
+       ot->idname = "GRAPH_OT_driver_delete_invalid";
+       ot->description = "Deletes all visible drivers considered invalid";
+
+       /* api callbacks */
+       ot->exec = graph_driver_delete_invalid_exec;
+       ot->poll = graphop_visible_keyframes_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
index 534b712fd5e6c9cd7b0c9cc693b48b781b0380ef..6c375b233523b851556e7813f4ef07ef16906959 100644 (file)
@@ -152,6 +152,7 @@ void GRAPH_OT_fmodifier_paste(struct wmOperatorType *ot);
 
 void GRAPH_OT_driver_variables_copy(struct wmOperatorType *ot);
 void GRAPH_OT_driver_variables_paste(struct wmOperatorType *ot);
+void GRAPH_OT_driver_delete_invalid(struct wmOperatorType *ot);
 
 /* ----------- */
 
index 62275abcd02a8cec7afe58d18699bbb6fc978893..57d8f45905d7a4672613494e3270cf675ed7c3d1 100644 (file)
@@ -468,6 +468,7 @@ void graphedit_operatortypes(void)
        /* Drivers */
        WM_operatortype_append(GRAPH_OT_driver_variables_copy);
        WM_operatortype_append(GRAPH_OT_driver_variables_paste);
+       WM_operatortype_append(GRAPH_OT_driver_delete_invalid);
 }
 
 void ED_operatormacros_graph(void)