diff --git a/source/blender/animrig/ANIM_animdata.hh b/source/blender/animrig/ANIM_animdata.hh index fe9eb4e3da1..ccc3ab69e23 100644 --- a/source/blender/animrig/ANIM_animdata.hh +++ b/source/blender/animrig/ANIM_animdata.hh @@ -30,6 +30,10 @@ bAction *id_action_ensure(Main *bmain, ID *id); */ void animdata_fcurve_delete(bAnimContext *ac, AnimData *adt, FCurve *fcu); +/** Iterate the FCurves of the given bAnimContext and validate the RNA path. Sets the flag + * FCURVE_DISABLED if the path can't be resolved. */ +void reevaluate_fcurve_errors(bAnimContext *ac); + /** * Unlink the action from animdata if it's empty. * diff --git a/source/blender/animrig/intern/animdata.cc b/source/blender/animrig/intern/animdata.cc index 327d1431473..e7e014412a7 100644 --- a/source/blender/animrig/intern/animdata.cc +++ b/source/blender/animrig/intern/animdata.cc @@ -17,6 +17,8 @@ #include "DEG_depsgraph_build.hh" #include "DNA_anim_types.h" #include "ED_anim_api.hh" +#include "RNA_access.hh" +#include "RNA_path.hh" namespace blender::animrig { @@ -135,4 +137,35 @@ bool animdata_remove_empty_action(AnimData *adt) /** \} */ +void reevaluate_fcurve_errors(bAnimContext *ac) +{ + /* Need to take off the flag before filtering, else the filter code would skip the FCurves, which + * have not yet been validated. */ + const bool filtering_enabled = ac->ads->filterflag & ADS_FILTER_ONLY_ERRORS; + if (filtering_enabled) { + ac->ads->filterflag &= ~ADS_FILTER_ONLY_ERRORS; + } + ListBase anim_data = {nullptr, nullptr}; + const eAnimFilter_Flags filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FCURVESONLY; + ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype)); + + LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { + FCurve *fcu = (FCurve *)ale->key_data; + PointerRNA ptr; + PropertyRNA *prop; + PointerRNA id_ptr = RNA_id_pointer_create(ale->id); + if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) { + fcu->flag &= ~FCURVE_DISABLED; + } + else { + fcu->flag |= FCURVE_DISABLED; + } + } + + ANIM_animdata_freelist(&anim_data); + if (filtering_enabled) { + ac->ads->filterflag |= ADS_FILTER_ONLY_ERRORS; + } +} + } // namespace blender::animrig diff --git a/source/blender/makesrna/intern/rna_action.cc b/source/blender/makesrna/intern/rna_action.cc index 9c9cb6a9a5e..93803e36d00 100644 --- a/source/blender/makesrna/intern/rna_action.cc +++ b/source/blender/makesrna/intern/rna_action.cc @@ -23,7 +23,6 @@ #include "RNA_access.hh" #include "RNA_define.hh" #include "RNA_enum_types.hh" -#include "RNA_path.hh" #include "rna_internal.h" @@ -38,6 +37,7 @@ # include "DEG_depsgraph.hh" # include "ANIM_action.hh" +# include "ANIM_animdata.hh" # include "ED_anim_api.hh" # include "WM_api.hh" @@ -364,28 +364,7 @@ static void rna_Action_show_errors_update(bContext *C, PointerRNA * /*ptr*/) return; } - /* Need to take off the flag before filtering, else the filter code would skip the FCurves, which - * have not yet been validated. */ - ac.ads->filterflag &= ~ADS_FILTER_ONLY_ERRORS; - ListBase anim_data = {nullptr, nullptr}; - const eAnimFilter_Flags filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FCURVESONLY; - ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, eAnimCont_Types(ac.datatype)); - - LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) { - FCurve *fcu = (FCurve *)ale->key_data; - PointerRNA ptr; - PropertyRNA *prop; - PointerRNA id_ptr = RNA_id_pointer_create(ale->id); - if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) { - fcu->flag &= ~FCURVE_DISABLED; - } - else { - fcu->flag |= FCURVE_DISABLED; - } - } - - ANIM_animdata_freelist(&anim_data); - ac.ads->filterflag |= ADS_FILTER_ONLY_ERRORS; + blender::animrig::reevaluate_fcurve_errors(&ac); } static char *rna_DopeSheet_path(const PointerRNA * /*ptr*/)