Files
test/source/blender/animrig/ANIM_action_iterators.hh
Sybren A. Stüvel 3dbede128e Fix #134581: Regression: Animation breaking going from 4.3 to 4.4
Fix an issue where the versioning of Action & slot assignments did not
use RNA properties to do the slot assignment. This caused certain
on-update callbacks to be missed, which in turn meant that an Action
constraint could remain disabled even though its action slot assignment
had been corrected.

This is now resolved by actually using RNA to set the assigned slot in
the versioning code.

Unfortunately that does mean that any reporting done will be by the
generic RNA code as well, and won't be specific to versioning. This
shouldn't be much of an issue in practice, as any warning was only shown
in the rare case of mis-matched `action.idroot` properties.

Pull Request: https://projects.blender.org/blender/blender/pulls/134759
2025-02-20 11:58:01 +01:00

108 lines
4.0 KiB
C++

/* SPDX-FileCopyrightText: 2024 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup animrig
*
* \brief Functionality to iterate an Action in various ways.
*/
#pragma once
#include "BLI_function_ref.hh"
#include "DNA_action_types.h"
struct FCurve;
namespace blender::animrig {
class Action;
class Layer;
class Strip;
class Channelbag;
} // namespace blender::animrig
namespace blender::animrig {
using slot_handle_t = decltype(::ActionSlot::handle);
/**
* Iterates over all FCurves of the Action and executes the callback on it.
* Works on layered and legacy actions.
*/
void foreach_fcurve_in_action(Action &action, FunctionRef<void(FCurve &fcurve)> callback);
/**
* Iterates over all FCurves of the given slot handle in the Action and executes the callback on
* it. Works on layered and legacy actions. When the action is legacy, the slot handle will be
* ignored.
*
* \note Use lambdas to have access to specific data in the callback.
*/
void foreach_fcurve_in_action_slot(Action &action,
slot_handle_t handle,
FunctionRef<void(FCurve &fcurve)> callback);
/**
* Call the given callback for each Action + Slot that this ID uses.
*
* The following cases are visited:
* - Direct Action+Slot assignment.
* - NLA strips.
* - Action Constraints, both on Object and Pose Bone level.
*
* \param callback: The function to call for each Action+Slot used. Even when there is no slot
* assigned, this function will be called (but then with slot_handle = Slot::unassigned). The
* callback should return `true` to continue the foreach loop, or return `false` to stop it.
*
* \returns Whether the foreach loop came to a natural end. So returns `false` when the callback
* returned `false`, and `true` otherwise.
*/
bool foreach_action_slot_use(
const ID &animated_id,
FunctionRef<bool(const Action &action, slot_handle_t slot_handle)> callback);
/**
* Essentially the same as foreach_action_slot_use(), except that it provides
* the ID as well as pointers via which the callback can modify which
* Action/slot is assigned.
*
* The ID passed to the callback is always the same `animated_id` as is passed
* to this function. The actions & slots passed to the callback are *not*
* necessarily the direct action & slot of that ID: they can also be the action
* & slot of an Action Constraint or NLA Strip owned by the ID.
*
* \see blender::animrig::generic_assign_action
* \see blender::animrig::generic_assign_action_slot
* \see blender::animrig::generic_assign_action_slot_handle
*/
bool foreach_action_slot_use_with_references(
ID &animated_id,
FunctionRef<bool(ID &animated_id,
bAction *&action_ptr_ref,
slot_handle_t &slot_handle_ref,
char *last_slot_identifier)> callback);
/**
* Essentially the same as foreach_action_slot_use(), except that it provides
* the ID as well as the RNA properties via which the callback can modify which
* Action/slot is assigned.
*
* The ID passed to the callback is always the same `animated_id` as is passed
* to this function. The actions & slots passed to the callback are *not*
* necessarily the direct action & slot of that ID: they can also be the action
* & slot of an Action Constraint or NLA Strip owned by the ID.
*
* \note this function CANNOT be used to change which Action is assigned, as that makes the
* PointerRNA/PropertyRNA values invalid.
*
* \see foreach_action_slot_use_with_references
*/
bool foreach_action_slot_use_with_rna(ID &animated_id,
FunctionRef<bool(ID &animated_id,
bAction *action,
PointerRNA &action_slot_owner_ptr,
PropertyRNA &action_slot_prop,
char *last_slot_identifier)> callback);
} // namespace blender::animrig