35 Commits

Author SHA1 Message Date
Sybren A. Stüvel
3171a22dfd Refactor: adjust unit tests to no longer use the legacy Action API
Adjust various unit tests so that they no longer use the legacy Action
API (which was deprecated in Blender 4.4 and will be removed in 5.0).

No functional changes.

This is part of #146586

Pull Request: https://projects.blender.org/blender/blender/pulls/147060
2025-10-02 14:42:42 +02:00
Sybren A. Stüvel
e077c189ec Refactor: Action unit tests, replace deprecated self.assertEquals() call
In the Action unit tests, replace the calls to the deprecated
`self.assertEquals()` function with `self.assertEqual()`.

No functional changes.

Pull Request: https://projects.blender.org/blender/blender/pulls/147185
2025-10-02 11:41:38 +02:00
Sybren A. Stüvel
dbcb701eb2 Anim: make it easier to convert from legacy to current Action API
The changes:

1. Add `group_name` to the `channelbag.fcurves.new()` and
   `action.fcurve_ensure_for_datablock()` RNA functions.
2. Add `anim_utils.action_ensure_channelbag_for_slot(action, slot)`.
3. Add `channelbag.fcurves.ensure()` RNA function.

This makes it possible to replace this legacy code:

```py
fcurve = action.fcurves.new("location", index=2, action_group="Name")
```

with this code:

```py
channelbag = action_ensure_channelbag_for_slot(action, action_slot)
fcurve = channelbag.fcurves.new("location", index=2, group_name="Name")
```

or replace this legacy code:

```py
fcurve = action.fcurves.find("location", index=2, action_group="Name")
if not fcurve:
    fcurve = action.fcurves.new("location", index=2, action_group="Name")
```

with this code:

```py
channelbag = action_ensure_channelbag_for_slot(action, action_slot)
fcurve = channelbag.fcurves.ensure("location", index=2, group_name="Name")
```

Note that the parameter name is different (`action_group` became
`group_name`). This clarifies that this is the name of the group, and
not a reference to the group itself.

This is part of #146586

Pull Request: https://projects.blender.org/blender/blender/pulls/146977
2025-09-30 14:43:56 +02:00
Michal Krupa
fdaaea6328 Core: Increase MAX_ID_NAME length from 66 to 258 (Blender 5.0)
Change the maximum data-block name from 64 to 256 bytes by increasing MAX_ID_NAME value.

Also increase a few related non-ID data name max size, essentially the action slots identifiers, as these are the primary key used to match an Action's slot to an ID by name.

Other sub-data (bones, modifiers, etc.) lengths are not modified here, as these can be made actual dynamic strings in the future, while keeping (a reasonable level of) forward compatibility, during the course of Blender 5 release cycles.

Implements #137608.

Co-authored-by: Bastien Montagne <bastien@blender.org>
Pull Request: https://projects.blender.org/blender/blender/pulls/137196
2025-06-19 16:39:20 +02:00
Sergey Sharybin
bbfc97ad6f Move tests/data and assets to the main repository
This change moves the tests data files and publish folder of assets
repository to the main blender.git repository as LFS files.

The goal of this change is to eliminate toil of modifying tests,
cherry-picking changes to LFS branches, adding tests as part of a
PR which brings new features or fixes.

More detailed explanation and conversation can be found in the
design task.

Ref #137215

Pull Request: https://projects.blender.org/blender/blender/pulls/137219
2025-05-05 15:10:22 +02:00
Sybren A. Stüvel
064421a02d Anim: expose Action Slot users to RNA
Add a new RNA function `ActionSlot.users()` that returns the
data-blocks that are animated by this slot.

This covers direct assignment of the action & slot, but also use in
the NLA and in Action constraints.

```python
>>> D.actions['SuzanneAction'].slots['OBSuzanne'].users()
[bpy.data.objects['Suzanne']]
```

This was implemented as a function, and not a collection property,
because Blender's bookkeeping of the slot users can be marked 'dirty'.
In that case the slot user list needs to be rebuilt, which happens for
all Actions and all their slots simultaneously. This was considered
too broad a data-changing action to 'hide' inside a getter of a
property. Also it needs a `bmain` pointer, which is not available in
getters, but is available in functions.

Pull Request: https://projects.blender.org/blender/blender/pulls/135734
2025-03-11 10:36:59 +01:00
Sybren A. Stüvel
2393d498cb Anim: add RNA function Action.fcurve_ensure_for_datablock(...)
Expose the convenience function `blender::animrig::action_fcurve_ensure()`
to RNA as `Action.fcurve_ensure_for_datablock(...)`.

The function requires that the Action is already assigned to the
data-block. It then takes care of slot assignment / creation, as well as
the creation of a layer and a keyframe strip.

This function call:

```python
fcurve = action.fcurve_ensure_for_datablock(ob_cube, "location", index=2)
```

effectively performs this logic:

```python
# Ensure the slot exists and is assigned:
slot = ob_cube.animation_data.slot
if not slot:
    slot = find_slot_for_keying(action)
if not slot:
    slot = action.slots.new(ob_cube.name)
ob_cube.animation_data.slot = slot

# Ensure a layer exists:
if action.layers:
    layer = action.layers[0]
else:
    layer = action.layers.new("Layer")

# Ensure a keyframe strip exists:
if layer.strips:
    strip = layer.strips[0]
else:
    strip = layer.strips.new('KEYFRAME')

# Ensure the channelbag exists:
channelbag = strip.channelbag(slot, ensure=True)

# Ensure the F-Curve exists:
fcurve = channelbag.fcurves.find("location", index=1)
if not fcurve:
    fcurve = channelbag.fcurves.new("location", index=1)
```

Here `find_slot_for_keying()` represents the logic that's also used when
creating keys via the user interface or the `bpy_struct.keyframe_insert()`
function.

Pull Request: https://projects.blender.org/blender/blender/pulls/134686
2025-02-18 16:04:00 +01:00
Nathan Vegdahl
33b9d54abb Anim: add RNA Channelbag.slot property
This allows Python scripts to easily determine what Slot a Channelbag is
for. This is particularly important because we're trying to discourage
the use of Slot handles in the Python APIs, and before this the only
way to identify which Slot a Channelbag was for was via the Channelbag's
`slot_handle` property.

Pull Request: https://projects.blender.org/blender/blender/pulls/134053
2025-02-04 17:39:03 +01:00
Nathan Vegdahl
f84197f0b9 Anim: ensure correct type prefix when setting Slot.identifier
Previously it was possible to make the type prefix of a Slot's identifier get
out-of-sync with its actual target ID type, by setting the identifier via
Python.

This PR changes `Slot.identifier` assignment to ensure that the type prefix is
set to match `target_id_type`. This now makes it impossible for the identifier
prefix and `target_id_type` to get out of sync, since this API previously was
the only way to accomplish that.

When the prefix that the user attempts to set doesn't match the `target_id_type`
of the Slot, a warning is issued telling the user about the mismatch and that
the identifier has been set with the correct prefix instead.

Pull Request: https://projects.blender.org/blender/blender/pulls/133983
2025-02-04 15:46:22 +01:00
Nathan Vegdahl
eda2f11f7a Anim: change RNA Action.id_root to have backwards-compatible behavior
Most of the old Animato properties on an Action (e.g. FCurve list, Channel
Groups) already act as proxies for the data for the first slot in the first
strip of the first layer. (Say that three times fast!) However, this was not yet
the case for `Action.id_root`.

This PR changes `Action.id_root` to act as a proxy for the first Slot's
`target_id_type` property, both for reading and writing.

If the Action has no Slots, then reading always returns 'UNSPECIFIED', and
writing will create a Slot and set its `target_id_type`.

Note that the ability to write to the first Slot's `target_id_type` via
`Action.id_root` conflicts with `target_id_type` supposedly only being writable
when it's still 'UNSPECIFIED' (#133883). Although that's certainly a little
weird, practically speaking this doesn't break anything for now, and is a
temporary kludge to keep `id_root` working until we can remove it in Blender
5.0. `id_root` will be removed entirely in 5.0, resolving this inconsistency.

Pull Request: https://projects.blender.org/blender/blender/pulls/133823
2025-02-04 13:39:50 +01:00
Sybren A. Stüvel
226486aa91 Refactor: Anim, rename and adjust ActionKeyframeStrip.channels()
Rename `ActionKeyframeStrip.channels()` to `.channelbag()`, and change
its first parameter from `slot_handle` to `slot`.

This is to be consistent with `ActionKeyframeStrip.channelbags`, which is
the array of channelbags in the keyframe strip. Having a function that's
singluar makes sense for finding a single element in the array.

The change from using the slot handle to using the slot is to be consistent
with `.channelbags.new(slot)`. Furthermore, the Python API should be using
slot handles as little as possible (they're basically meaningless numbers).
Using the slots directly is preferred. If that's not possible, it is
recommended to use the slot identifier (`slot.identifier`) instead, as that
can be used to look up the slot (`action.slots[slot_identifier]`).

This breaks the glTF add-on, which will be fixed in !133915.

Pull Request: https://projects.blender.org/blender/blender/pulls/133868
2025-02-03 20:19:00 +01:00
Nathan Vegdahl
978011fe43 Anim: use legacy names for data created via legacy APIs
Previously, when use of the legacy Action APIs (specifically the `fcurves` and
`groups` properties) caused a new Slot to be created, it would be named "Slot".

This PR changes things so that Slots created that way are named "Legacy Slot",
just like Slots from upgraded legacy Actions.

The rationale is that Slots created in this way are expected (by the code that
created them) to be used as if the Action were still a legacy Action, and it's
good to reflect that in the name of the data. This also makes it clearer to
users when e.g. scripts and addons they're using may not yet have been updated
to fully work with Slotted Actions.

For consistency, this PR also names Layers created in the same way "Legacy
Layer", the same as Layers from upgraded legacy Actions.

Pull Request: https://projects.blender.org/blender/blender/pulls/133888
2025-02-03 14:48:39 +01:00
Nathan Vegdahl
b5005cd99c Anim: make RNA Slot.target_id_type writable when not yet specified
When loading old blend files, versioned Actions can end up having a slot with an
'UNSPECIFIED' `target_id_type`. Assigning the slot to an ID will then set the
slot's `target_id_type` to match the type of the ID, but there was previously no
way to directly set it via Python if needed.

This PR changes the writability of `target_id_type` to match the extent of its
mutability when assigning a slot to an IDs. Which is to say, it can be set if
it's 'UNSPECIFIED', but not otherwise.

RNA doesn't have a good way to represent this, so we accomplish this with a
custom set function that simply ignores the write if the slot's `target_id_type`
isn't 'UNSPECIFIED'. This isn't ideal, but is the least-bad solution at the
moment.

Pull Request: https://projects.blender.org/blender/blender/pulls/133883
2025-02-03 13:01:47 +01:00
Sybren A. Stüvel
f97c54ff76 Anim: emit liboverride on slot handle when action is changed
Emit a 'diff' for the `animdata.slot_handle` property whenever the
`.action` property is changed through a library override.

The slot handle is only meaningful within the context of the assigned
action. So when a liboverride changes the assigned action, the slot
handle should also get an override.

This is necessary even when the numerical value of the slot handle
happens to be the same in both actions, as the newly chosen slot is
different from the slot that was chosen in the library file.

This applies to direct Action assignment, NLA strips, and Action
constraints.

Pull Request: https://projects.blender.org/blender/blender/pulls/133727
2025-01-31 15:43:34 +01:00
Sybren A. Stüvel
815337a7da Anim: add ensure parameter to KeyframeStrip.channels(...) RNA function
Add `ensure` boolean parameter to the `ActionKeyframeStrip.channels()` RNA
function. Passing `ensure=True` will ensure the channelbag for the given
action slot handle exists. This makes it more straight-forward to create
F-Curves for a slot regardless of whether there already was a channelbag
for those F-Cuves:

```python
strip = action.layers[0].strips[0]
slot = action.slots[0]

# Old:
channelbag = strip.channels(slot.handle)
if not channelbag:
    channelbag = strip.channelbags.new(action_slot)
ob_loc_x = channelbag.fcurves.new('location', index=0)

# New:
channelbag = strip.channels(slot.handle, ensure=True)
ob_loc_x = channelbag.fcurves.new('location', index=0)
```

Pull Request: https://projects.blender.org/blender/blender/pulls/133678
2025-01-31 15:16:10 +01:00
Sybren A. Stüvel
dd67b355ee Anim: do not set slot ID type when Action is linked
When an action slot does not have an ID type, and it is assigned to some
ID, the slot is bound to that ID's type. This now no longer happens when
the Action is linked, because linked data should not be modified.

Pull Request: https://projects.blender.org/blender/blender/pulls/133670
2025-01-27 17:51:23 +01:00
Nathan Vegdahl
9f2ab9cba0 Anim: rename RNA Slot.id_root to Slot.target_id_type
The name `id_root` was not descriptive, and was just a hold-over from the
equivalent (now deprecated) property on the Action itself.  `target_id_type`
is more clear, reflecting that this is the type of ID the Slot is intended
to animate.

This PR also renames the corresponding `id_root_icon` to
`target_id_type_icon`.

Note that this PR updates the GLTF import/export core addon to adhere to
these name changes as well.

Pull Request: https://projects.blender.org/blender/blender/pulls/133164
2025-01-20 15:24:08 +01:00
Sybren A. Stüvel
63adbb19fb Anim: Always name the slot "Legacy Slot" when versioning legacy Actions
When creating Action Slots for legacy Actions, always name those slots
"Legacy Slot". Before this commit, the slot was named after the ID that
is animated by the Action; this matches what Blender will do when
animating that ID from scratch.

The old versioning behaviour caused issues when dealing with legacy
Actions: if there are multiple Actions in a file (for example multiple
run cycle animations) and only one of those was assigned to the
character (the rest has a fake user), Blender would only name that one
action slot after the character. The "fake user" Actions would just be
get a slot named "Slot".

This causes issues when toggling between the different Actions, as
Blender will not automatically assign a slot when switching from the
character- named one to the "Slot" one.

Ref: #129563, #130261

Pull Request: https://projects.blender.org/blender/blender/pulls/131425
2025-01-07 15:34:53 +01:00
Sybren A. Stüvel
c6d6efaaa2 Fix #132606: ActionSlots can be created with too long names
The max length of the RNA property `ActionSlot.identifier` was set
incorrectly. The setter code did manage the length properly, but the
getter was checking agains that incorrect max length, and rightfully
complained.

Pull Request: https://projects.blender.org/blender/blender/pulls/132691
2025-01-06 13:55:07 +01:00
Nathan Vegdahl
089c3cd85c Refactor: rename ChannelBag and channel_bag
We've had a bunch of inconsistency between `channel_bag` and `channelbag` in the
code base.  After discussion with @dr.sybren, we decided to standardize on
`channelbag` and also rename the camelcase `ChannelBag` to `Channelbag` to be
consistent with that.

This PR implements those changes.

Note that the reason we standardized on `channelbag` rather than `channel_bag`
is because it makes things clearer when stringing multiple terms together in
type and function names.  For example, in `channelbag_fcurves_move()` it makes
it clear that `channelbag` describes one thing, rather than `channel` and `bag`
being two separate things.

No functional changes intended.

Pull Request: https://projects.blender.org/blender/blender/pulls/130988
2024-12-02 17:55:59 +01:00
Nathan Vegdahl
aa83738d44 Anim: change parameters of slots.new() RNA function
`Action.slots.new()` in the Python API previously took either an ID or nothing
as a parameter. In the former case it would create a slot with the appropriate
`id_root` and name for that ID. In the latter case it would create a default
slot with an unspecified `id_root` and default name.

This had several issues:

1. You couldn't create a slot with a specific `id_root` without already having
   an ID of that type. In theory this isn't a problem, but in practice in larger
   scripts/addons you don't necessarily have such an ID on hand at the call
   site.
2. You couldn't directly create a slot with a desired name without an existing
   ID with that name. This isn't so important, since you can always just set the
   name afterwards. But it's a bit annoying.
3. Most other `new()` APIs in Blender *require* you to specify the name of the
   item being created. So calling this with no parameters was violating that
   norm.
4. Ideally, we want to eliminate unspecified `id_root`s, since they cause other
   weirdness in the API such as slot identifiers changing upon slot assignment.

To resolve these issues, and just generally to make the API more
straightforward, this PR changes `slots.new()` to take two required parameters:
an ID type and a name. For example:

`slots.new(id_type='CAMERA', name="My Camera Data Slot")`.

This fully specifies everything needed for the slot identifier upon creation,
and doesn't require any outside data items to create a slot with the desired
type and name.

In the future if we decide we still want a `for_id`-style slot creation API, we
can reintroduce it as a separate function.

Ref: #130892
Pull Request: https://projects.blender.org/blender/blender/pulls/130970
2024-12-02 17:04:37 +01:00
Nathan Vegdahl
409697a962 Anim: rename action_slot_name to last_slot_identifier
`AnimData`, NLA strips, and action constraints all have an `action_slot_name`
field in RNA. The purpose of this field is to store the identifier of the most
recently assigned slot, so that it can be used for auto-assignment when later
assigning different actions.

However, this field name is misleading in two ways:

1. In accordance with #130740, it's actually the slot *identifier*, not name.
2. It could be mistaken as a way to rename the currently assigned slot, which it
   is not.

To resolve both of those issues, we're renaming the field to
`last_slot_identifier`, which better communicates its actual nature.

As a bonus, this also ends up decluttering Python autocomplete when looking
for things related to action_slot.

Ref: #130892
Pull Request: https://projects.blender.org/blender/blender/pulls/130911
2024-11-26 16:05:40 +01:00
Nathan Vegdahl
c0fd193abf Anim: rename slot name to slot identifier
This PR renames `ActionSlot::name` to `ActionSlot::identifier` for both DNA and
RNA, and also renames related methods, functions, constants, and comments.

The purpose of this rename is to help make it clear that this is not a "name"
in the traditional sense, but rather is a composite of the slot name + id type
for lookup purposes.

Ref: #130892
Pull Request: https://projects.blender.org/blender/blender/pulls/130740
2024-11-26 12:11:06 +01:00
Sybren A. Stüvel
43d7558e5b Anim: Remove 'Slotted Actions' experimental flag
This commit takes the 'Slotted Actions' out of the experimental phase.
As a result:

- All newly created Actions will be slotted Actions.
- Legacy Actions loaded from disk will be versioned to slotted Actions.
- The new Python API for slots, layers, strips, and channel bags is
  available.
- The legacy Python API for accessing F-Curves and Action Groups is
  still available, and will operate on the F-Curves/Groups for the first
  slot only.
- Creating an Action by keying (via the UI, operators, or the
  `rna_struct.keyframe_insert` function) will try and share Actions
  between related data-blocks. See !126655 for more info about this.
- Assigning an Action to a data-block will auto-assign a suitable Action
  Slot. The logic for this is described below. However, There are cases
  where this does _not_ automatically assign a slot, and thus the Action
  will effectively _not_ animate the data-block. Effort has been spent
  to make Action selection work both reliably for Blender users as well
  as keep the behaviour the same for Python scripts. Where these two
  goals did not converge, reliability and understandability for users
  was prioritised.

Auto-selection of the Action Slot upon assigning the Action works as
follows. The first rule to find a slot wins.

1. The data-block remembers the slot name that was last assigned. If the
    newly assigned Action has a slot with that name, it is chosen.
2. If the Action has a slot with the same name as the data-block, it is
    chosen.
3. If the Action has only one slot, and it has never been assigned to
    anything, it is chosen.
4. If the Action is assigned to an NLA strip or an Action constraint,
    and the Action has a single slot, and that slot has a suitable ID
    type, it is chosen.

This last step is what I was referring to with "Where these two goals
did not converge, reliability and understandability for users was
prioritised." For regular Action assignments (like via the Action
selectors in the Properties editor) this rule doesn't apply, even though
with legacy Actions the final state ("it is animated by this Action")
differs from the final state with slotted Actions ("it has no slot so is
not animated"). This is done to support the following workflow:

- Create an Action by animating Cube.
- In order to animate Suzanne with that same Action, assign the Action
  to Suzanne.
- Start keying Suzanne. This auto-creates and auto-assigns a new slot
  for Suzanne.

If rule 4. above would apply in this case, the 2nd step would
automatically select the Cube slot for Suzanne as well, which would
immediately overwrite Suzanne's properties with the Cube animation.

Technically, this commit:
- removes the `WITH_ANIM_BAKLAVA` build flag,
- removes the `use_animation_baklava` experimental flag in preferences,
- updates the code to properly deal with the fact that empty Actions are
  now always considered slotted/layered Actions (instead of that relying
  on the user preference).

Note that 'slotted Actions' and 'layered Actions' are the exact same
thing, just focusing on different aspects (slot & layers) of the new
data model.

The "Baklava phase 1" assumptions are still asserted. This means that:
- an Action can have zero or one layer,
- that layer can have zero or one strip,
- that strip must be of type 'keyframe' and be infinite with zero
  offset.

The code to handle legacy Actions is NOT removed in this commit. It will
be removed later. For now it's likely better to keep it around as
reference to the old behaviour in order to aid in some inevitable
bugfixing.

Ref: #120406
2024-10-15 16:29:53 +02:00
Christoph Lendenfeld
bcd0d14943 Versioning for layered actions
This implements versioning code to go from legacy to layered action.
The versioning is only triggered when the experimental flag for
Multi-Slot actions is enabled.

All the actions are converted in place, which should be fine because
of backwards and forwards compatibility with layered actions.

Pull Request: https://projects.blender.org/blender/blender/pulls/127842
2024-09-26 15:45:53 +02:00
Sybren A. Stüvel
e897b184e4 Anim: Add backward-compatible RNA API for Action.groups
The `Action.groups` RNA functions now work with layered Actions as well.
They just expose / operate on the groups of the channelbag that belongs
to the first slot of the Action.

Pull Request: https://projects.blender.org/blender/blender/pulls/127241
2024-09-06 14:33:58 +02:00
Nathan Vegdahl
df02e7a5e5 Anim: add channel groups to layered actions
This PR adds channel groups (also known as fcurve groups or action groups) to
layered actions.  For layered actions, these groups belong to the `ChannelBag`s
and can vary by bag.

From a user perspective, the goal is for these to function just like channel
groups from legacy actions.  However, internally they are implemented a little
differently: legacy actions store both channel groups and fcurves in a listbase,
and groups indicate what fcurves are in them with a listbase that points
directly into the larger fcurve listbase.  Layered actions, on the other hand,
store both fcurves and channel groups in an array, and groups indicate what
fcurves are in them by indexing into the fcurve array.

Despite taking this different approach, we still reuse the `bActionGroup` struct
for the new channel groups, just adding the necessary fields for index-based
fcurve membership as described above.

This PR does not implement all of the functionality needed to reach feature
parity with legacy action channel groups, but implements the main core and gets
them basically working.

It's easier to list the things that *haven't* been implemented yet:

- Operators for letting the user manually create/remove/move channel groups.
- Keyframe selection in the action/dopesheet editor on channel group rows
  themselves are not yet working correctly.
- Handling channel groups in legacy/layered action conversion operators.
- Making the legacy `action.groups` property work on single-layer-single-strip
  layered actions.

Those are left for future PRs.  Other than that, in theory everything should be
working now.

Pull Request: https://projects.blender.org/blender/blender/pulls/125774
2024-08-22 17:13:12 +02:00
Sybren A. Stüvel
a8ee0b9a05 Anim: add Action Slot selector to Action editor
Add an Action Slot selector to the Action editor's header, next to the
Action selector. The selector shows all slots in the action that are
suitable for animating objects (as the Action editor itself is limited
to showing the Action of the active object).

This also considerably simplifies the 'Animation Debug' panel, as some
debugging code has been removed, as well as the display of any animation
layers. The latter can be reintroduced (if necessary) when multi-layer
animation support is added. Most importantly, it removes the
WindowManager property that was used as a hack to assign layered Actions
to objects.

API change: the RNA property `AnimData.slot` is now a pointer property
that reflects the actual slot (it used to be an enum property).

Some small changes to the UI code were necessary to make the selector
show the slot's display name (and not their internal name).

Pull Request: https://projects.blender.org/blender/blender/pulls/125416
2024-07-25 17:20:27 +02:00
Sybren A. Stüvel
d4984216de Anim: Backward compatibility API for Action.fcurves
These functions can now be called on layered Actions:

- `action.fcurves.new(data_path, array_index)`
- `action.fcurves.find(data_path, array_index)`
- `action.fcurves.remove(fcurve)`
- `action.fcurves.clear()`

These will operate on the first keyframe strip (searching layers bottom
to top), and then its channelbag for the first slot.

If necessary, `fcurves.new()` will create the layer, keyframe strip,
channelbag, and slot.

This backward compatibility layer only kicks in if either of these is
true:

- The Action is empty AND the experimental flag is enabled, or
- The Action already has a layer or a slot (i.e. is already considered
  'layered').

If none of these conditions hold, `action.fcurves` just gives access to
the legacy data.

Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/124996
2024-07-25 12:06:23 +02:00
Sybren A. Stüvel
efbdc4e1fa Anim: ChannelBag F-Curve management functions (C++/RNA)
Add F-Curve management functions on ChannelBags
(`channelbag.fcurves.xxx`) that are very similar to the legacy Action
functions `Action.fcurves.xxx`.

```python
channelbag = strip.channelbags.new(slot)
fcurve = channelbag.fcurves.new("rotation_quaternion", index=1)
assert channelbag.fcurves[0] == fcurve
channelbag.fcurves.remove(fcurve)
channelbag.fcurves.clear()
```

Pull Request: https://projects.blender.org/blender/blender/pulls/124987
2024-07-18 17:06:12 +02:00
Sybren A. Stüvel
7360ce4bcc Anim: add RNA code for ChannelBags
RNA API for creating & removing channelbags, as well as a path function
to construct RNA paths for channelbags.

```python
action = bpy.data.actions.new('TestAction')

slot = action.slots.new()
slot.name = 'OBTest'

layer = action.layers.new(name="Layer")
strip = layer.strips.new(type='KEYFRAME')

# New in this commit:
channelbag = strip.channelbags.new(slot)
strip.channelbags.remove(channelbag)
```

Pull Request: https://projects.blender.org/blender/blender/pulls/124793
2024-07-18 11:14:15 +02:00
Sybren A. Stüvel
0aa75ab57b Refactor: rename "Animation data-block" to "Action"
Rename "Animation data-block" to "Action" or "Layered Action", where
appropriate. Some uses of the term actually refer to the `AnimData`
struct, in which case they were left as-is.

No real functional changes, just changing some messages & descriptions.

Pull Request: https://projects.blender.org/blender/blender/pulls/124170
2024-07-05 17:52:55 +02:00
Sybren A. Stüvel
c0364efec0 Refactor: rename 'Action Binding' to 'Action Slot'
Rename 'Binding' to 'Slot'. The old term was causing all kind of
confusion, and 'slot' was considered to be a better term for the
intended functionality.

This commit breaks existing blend files that were using the new layered
Action for their animation. The animation data will be lost due to the
rename, as there is no versioning code or DNA renaming logic. At this
time the new system is still marked as experimental, so shouldn't be
used for anything serious anyway.

Pull Request: https://projects.blender.org/blender/blender/pulls/124170
2024-07-05 17:52:55 +02:00
Sybren A. Stüvel
3f555ee027 Anim: add RNA guards to prevent mixing legacy/layered action operations
Add guards to the RNA code to prevent the creation of legacy data on a
layered Action, and vice versa.

On a legacy Action, it is now impossible to create new layers or bindings.

On a layered Action, it's now impossible to create legacy F-Curves or
groups.

Refactor: Anim: rename bl_animation_id.py to bl_animation_action.py

The `Animation` datablock is no more, and this file tests `Action`.

No functional changes.

Pull Request: https://projects.blender.org/blender/blender/pulls/122483
2024-05-30 13:19:21 +02:00
Sybren A. Stüvel
ef6dd90a6e Refactor: Anim: rename bl_animation_id.py to bl_animation_action.py
The `Animation` datablock is no more, and this file tests `Action`.

No functional changes.
2024-05-30 13:19:21 +02:00