Files
test2/source/blender/animrig/ANIM_animdata.hh
Christoph Lendenfeld 34a18c7608 Anim: Merge Animation operator
This adds the "Merge Animation" (`ANIM_OT_merge_animation`) operator to the 3D viewport.
It merges the animation of all selected objects into the animation of the active object.

On a technical level this moves the `ChannelBag` of the source action into a new slot
on the target action. The Slot name is copied but might differ due to name clashes.
Due to this, the operator is named "Merge Animation" and not "Merge Actions" since
it might not merge the complete actions but only the slots actually used by the selection
in the 3D viewport

This operator will find all related IDs to the selection, i.e. object data, shape keys etc. and merge those as well.
That means this operator can also be used to JUST merge the actions of the active object and its data.

### Caveats
Because there may be more than 1 slot user this might reassign an object that isn't actually selected.
The other option is that when there is more than 1 slot user, the `ChannelBag` is copied instead of moved.
That means moving objects that share a slot one by one would result in a loss of slot sharing and
data duplication. I think it's better to respect the artist decision of "these things use the same animation"
in this case. (open to opinions though)

Design task: #126937

Pull Request: https://projects.blender.org/blender/blender/pulls/127414
2024-09-20 15:08:16 +02:00

86 lines
2.6 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup animrig
*
* \brief Functions to work with AnimData.
*/
#pragma once
#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
struct ID;
struct Main;
struct bAnimContext;
struct AnimData;
struct FCurve;
struct bAction;
namespace blender::animrig {
class Action;
/**
* Get (or add relevant data to be able to do so) the Active Action for the given
* Animation Data block, given an ID block where the Animation Data should reside.
*/
bAction *id_action_ensure(Main *bmain, ID *id);
/**
* Delete the F-Curve from the given AnimData block (if possible),
* as appropriate according to animation context.
*/
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.
*
* If the action has no F-Curves, unlink it from AnimData if it did not
* come from a NLA Strip being tweaked.
*/
bool animdata_remove_empty_action(AnimData *adt);
/**
* Build a Vector of IDs that are related to the given ID. Related things are e.g. Object<->Data,
* Mesh<->Material and so on. The exact relationships are defined per ID type. Only relationships
* of 1:1 are traced. The case of multiple users for 1 ID is treated as not related.
* The returned Vector always contains the passed ID as the first index as such will never be
* emtpy.
*/
Vector<ID *> find_related_ids(Main &bmain, ID &id);
/**
* Compatibility helper function for `BKE_animadata_fcurve_find_by_rna_path()`.
*
* Searches each layer (top to bottom) to find an FCurve that matches the given
* RNA path & index.
*
* \see BKE_animadata_fcurve_find_by_rna_path
*
* \note The returned FCurve should NOT be used for keyframe manipulation. Its
* existence is an indicator for "this property is animated".
*
* \note This function assumes that `adt->action` actually points to a layered
* Action. It is a bug to call this with a legacy Action, or without one.
*
* This function should probably be limited to the active layer (for the given
* property, once pinning to layers is there), so that the "this is keyed" color
* is more accurate.
*
* Again, this is just to hook up the layered Action to the old Blender UI code.
*/
const FCurve *fcurve_find_by_rna_path(const AnimData &adt,
StringRefNull rna_path,
int array_index);
} // namespace blender::animrig