94 lines
2.3 KiB
C++
94 lines
2.3 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup animrig
|
|
*/
|
|
|
|
#include "ANIM_animdata.hh"
|
|
#include "BKE_action.h"
|
|
#include "BKE_fcurve.h"
|
|
#include "BKE_lib_id.h"
|
|
#include "BLI_listbase.h"
|
|
#include "DNA_anim_types.h"
|
|
#include "ED_anim_api.hh"
|
|
|
|
namespace blender::animrig {
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
/** \name Public F-Curves API
|
|
* \{ */
|
|
|
|
void animdata_fcurve_delete(bAnimContext *ac, AnimData *adt, FCurve *fcu)
|
|
{
|
|
/* - If no AnimData, we've got nowhere to remove the F-Curve from
|
|
* (this doesn't guarantee that the F-Curve is in there, but at least we tried
|
|
* - If no F-Curve, there is nothing to remove
|
|
*/
|
|
if (ELEM(nullptr, adt, fcu)) {
|
|
return;
|
|
}
|
|
|
|
/* Remove from whatever list it came from
|
|
* - Action Group
|
|
* - Action
|
|
* - Drivers
|
|
* - TODO... some others?
|
|
*/
|
|
if ((ac) && (ac->datatype == ANIMCONT_DRIVERS)) {
|
|
BLI_remlink(&adt->drivers, fcu);
|
|
}
|
|
else if (adt->action) {
|
|
bAction *act = adt->action;
|
|
|
|
/* Remove from group or action, whichever one "owns" the F-Curve. */
|
|
if (fcu->grp) {
|
|
bActionGroup *agrp = fcu->grp;
|
|
|
|
/* Remove F-Curve from group+action. */
|
|
action_groups_remove_channel(act, fcu);
|
|
|
|
/* If group has no more channels, remove it too,
|
|
* otherwise can have many dangling groups #33541.
|
|
*/
|
|
if (BLI_listbase_is_empty(&agrp->channels)) {
|
|
BLI_freelinkN(&act->groups, agrp);
|
|
}
|
|
}
|
|
else {
|
|
BLI_remlink(&act->curves, fcu);
|
|
}
|
|
|
|
/* If action has no more F-Curves as a result of this, unlink it from
|
|
* AnimData if it did not come from a NLA Strip being tweaked.
|
|
*
|
|
* This is done so that we don't have dangling Object+Action entries in
|
|
* channel list that are empty, and linger around long after the data they
|
|
* are for has disappeared (and probably won't come back).
|
|
*/
|
|
animdata_remove_empty_action(adt);
|
|
}
|
|
|
|
BKE_fcurve_free(fcu);
|
|
}
|
|
|
|
bool animdata_remove_empty_action(AnimData *adt)
|
|
{
|
|
if (adt->action != nullptr) {
|
|
bAction *act = adt->action;
|
|
|
|
if (BLI_listbase_is_empty(&act->curves) && (adt->flag & ADT_NLA_EDIT_ON) == 0) {
|
|
id_us_min(&act->id);
|
|
adt->action = nullptr;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/** \} */
|
|
|
|
} // namespace blender::animrig
|