When duplicating a bone (has to be done in edit mode)
the pose bone colors were not copied.
This adds the code to do just that
This also fixes it for symmetrising because that uses the
same code path
Pull Request: https://projects.blender.org/blender/blender/pulls/129007
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
# Fix 128078, Part I: Fix missing reverse endian switch of Action's `idroot`.
ID type code stored as ints (or shorts) need their endian switch to be
reverted (in case there is endianess conversion) on file read.
Interestingly, this was done for the deprecated IPO data (among others), but
not for the Action one!
NOTE: There is no versioning fix for this mistake, i.e. old files that
were saved from a BE system, then opened and re-saved from a LE system,
will still have totally invalid ID code values. This is not considered
as necessary currently, given that this `idroot` value is only
'informational' and not relied on by any part of the code.
# Fix 128078, Part II: GPv3 conversion code missing animation of Layers' location.
Also add code to the AnimDataConverter to ensure that actions get the
`idroot` matching their new ID owner type in GP data case.
Pull Request: https://projects.blender.org/blender/blender/pulls/128129
`ActionSlot::idtype` needs some extra care when reading from a blend
file. Blender's generic endian switching needs to be un-done, as the
ID type values are not numerically the same between little and big
endian machines. Due to the way they are defined, they are always in
the same byte order, regardless of hardware/platform endianness.
This is the same for Action Slots as #128129 does for Actions, except
that Action Slots use a `int16_t` instead of `short` and thus don't
need a cast.
Pull Request: https://projects.blender.org/blender/blender/pulls/128438
Refactor `ED_curve_updateAnimPaths()` and the static functions it calls,
separating out:
- the manipulation of the F-Curves themselves, and
- the manipulation of whatever container holds those F-Curves.
This will make it considerably easier to convert the code to deal with a
`Span<FCurve *>` later instead of `ListBase`, which in turn is necessary
to handle layered Actions.
The old code used to move F-Curves from one `ListBase` to another, to
avoid visiting the same F-Curve twice. This is now done by tracking
those F-Curves in a `Set<FCurve *>`, so that it doesn't require
manipulation of the storage itself.
No functional changes.
In `BKE_action.hh`, update the Action Group related functions, so that
either they are legacy-only or can handle layered Actions as well.
Legacy-only functions not only are documented as such, but also assert
that the given Action is a legacy one.
No functional changes for legacy Actions.
Ref: #123424
Pull Request: https://projects.blender.org/blender/blender/pulls/128088
Add slotted/layered Action support to `get_active_actiongroup()` and
`set_active_action_group()`.
Note that there is still a bunch of code around that directly manipulates
the action group flags, instead of using these functions. That's for
another commit to address.
This commit also introduces the functions `action_treat_as_legacy()` and
`channel_groups_all(action)` utility functions in the `animrig::legacy`
namespace.
Ref: #123424
Pull Request: https://projects.blender.org/blender/blender/pulls/128084
Also return a pointer from `Layer::duplicate_with_shallow_strip_copies()`
rather than a reference, since it doesn't maintain ownership of the
returned item.
This updates the layered action data model to store strip data differently. Specifically:
- `Strip` is now just a single, POD type that only stores the data common to all
strips, such as start/end frames.
- The data that might be of a completely different nature between strips (e.g.
keyframe data vs modifier data) is now stored in arrays on the action itself.
- `Strip`s indicate their type with an enum, and specify their data with an
index into the array on the action that stores data for that type.
This approach requires a little more data juggling, but has the advantage of
making `Strip`s themselves super simple POD types, and also opening the door to
trivial strip instancing later on: instances are just strips that point at the
same data.
The intention is that the RNA API remains the same: from RNA's perspective there
is no data storage separate from the strips, and a strip's data is presented as
fields and methods directly on the strip itself. Different strip types will be
presented as different subtypes of `ActionStrip`, each with their own fields and
methods specific to their underlying data's type. However, this PR doesn't
implement that sub-typing, leaving it for a future PR. It does, however, put the
fields and methods of the one strip type we have so far directly on the strip,
which avoids changing the APIs we have so far.
This PR implements the bulk of this new approach, and everything should be
functional and working correctly. However, there are two TODO items left over
that will be implemented in forthcoming PRs:
- Type refinement in the RNA api. This PR actually removes the existing type
refinement code that was implemented in terms of the inheritance tree of the
actual C++ types, and this will need to be reimplemented in terms of the new
data model. The RNA API still works without the type refinement since there
are only keyframe strips right now, but it will be needed in preparation for
more strip types down the road.
- Strip data deletion. This PR only deletes data from the strip data arrays when
the whole action is deleted, and otherwise just accumulates strip data as more
and more strips are added, never removing the data when the corresponding
strips get removed. That's fine in the short term, especially since we only
support single strips right now. But it does need to be implemented in
preparation for proper layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126559
Move the following BKE functions to the `animrig::Action` class. Some of
those will be extended to support slots in a future commit; for now they
still operate on all F-Curves in the Action.
| Old | New |
|---------------------------------|-------------------------------------|
| `BKE_action_frame_range_calc()` | `Action::get_frame_range_of_keys()` |
| `BKE_action_frame_range_get()` | `Action::get_frame_range()` |
| `BKE_action_has_motion()` | `Action::has_keyframes()` |
| `BKE_action_has_single_frame()` | `Action::has_single_frame()` |
| `BKE_action_is_cyclic()` | `Action::is_cyclic()` |
Implementations have been copied from the BKE functions. The frame range
functions now return `float2` instead of requiring two `float *r_…`
return parameters.
The `has_motion` function is now renamed to `has_keyframes`, as that is
what the implementation was actually testing for.
The functions now no longer are null-safe. The BKE functions handled a
null action pointer, but IMO that doesn't make sense, and in none of the
call sites I could find where this would actually be valid.
No functional changes.
Ref: #127489
Pull Request: https://projects.blender.org/blender/blender/pulls/127512
Add support for slotted Actions to the NLA evaluation code.
This also affects the pose library code and the Action Constraint. These
both share some Action evaluation logic with the NLA. They now
explicitly looks at only the first Action slot. The Action Constraint will
have to be updated to have an explicit slot selector, but that's for another
commit.
Pull Request: https://projects.blender.org/blender/blender/pulls/127425
For an NLA strip to use a slotted Action, it needs to specify which slot
to use in that action. This is now handled by two new properties on the
strip in DNA & RNA: `action_slot_handle` and `action_slot_name`.
These serve the same purpose as their counterparts on the `AnimData`
struct.
Note that this commit does NOT add NLA evaluation support for slotted
Actions. It merely allows assigning them. Evaluation, tweak mode
support, etc. will be implemented in future commits.
Pull Request: https://projects.blender.org/blender/blender/pulls/127359
Fix a crash that happens when drawing Action groups in the dope sheet, when
Blender is built without experimental features (hence without Action
slots) and it has loaded a blend file with slotted Actions.
Basically a pointer needs to be set to `nullptr` when reading such a file,
as it ensures that the rest of the code treats the group as "from a legacy
Action".
Pull Request: https://projects.blender.org/blender/blender/pulls/127339
Resovle regression in [0].
Pointers in `action.chanbase` were used without first loading the
list-base. In this case the intention was to skip loading legacy
data, so clear the list instead.
[0]: c7bf1a697e
The issue was that the forward compatibility writing code for channel groups in
layered actions was building a temporary legacy listbase, but was not clearing
it properly afterwards. This was then getting caught by an assert that ensured
that layered-action groups didn't have legacy data in them.
The reason the listbase wasn't getting cleared properly is because the
prev/next listbase pointers were getting cleared using a `LISTBASE_FOREACH`
loop, and thus the loop never progressed past the first item.
Additionally, this mistake wasn't just in the channel groups writing code, but
also the forward compatibility writing code for fcurves.
This fixes the issue in both places by switching the loops to
use`LISTBASE_FOREACH_MUTABLE`.
Based on discussion with @dr.sybren, this also removes the assert that caught
the issue. The situation it guards against is actually completely benign, and
the existence of the assert is contrary to the comments in the forward-compat
writing code explaining why its approach is okay.
Pull Request: https://projects.blender.org/blender/blender/pulls/126970
The issue was that the forward compatibility saving code was setting the
group's `channels` listbase to point at the forward-compatible fcurve
listbase, but the `channels` listbase wasn't later getting cleared when
loading the groups as part of a layered action. In fact, the listbase
pointers were being completely ignored in that case because they aren't
relevant to groups on layered actions, and therefore weren't getting
remapped to the new correct memory addresses of the fcurves.
The end result was that after loading, the group's `channels` listbase
would be non-null and pointing to invalid memory, and there are some
code paths that then try to use that listbase, resulting in a segfault.
This commit fixes the issue by ensuring that the groups' `channels`
listbases are cleared when loading them as part of a layered action.
Additionally, we now also clear them after they're set during
forward-compatibly saving, the lack of which wasn't immediately
causing problems but was nevertheless incorrect.
Pull Request: https://projects.blender.org/blender/blender/pulls/126834
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
No functional changes expected.
The function `BKE_action_get_item_transform_flags` was only ever used in a single place.
As such it could be a static function within the given file.
This reduction in scope will help with future refactors.
This is in service of fixing #126125 since the function in its current form
does not support layered actions.
Pull Request: https://projects.blender.org/blender/blender/pulls/126287
When writing a layered Action to disk, take the F-Curves from the
first keyframe strip and write that as `action.curves` as well. This
will make older Blender versions see those curves and load them
properly.
Only the curves for the first slot are written this way. This means
that any legacy Action that was converted to a layered Action will be
loaded again properly by older Blender versions. Of course this is
limited to a single layer, single strip, and single slot -- once the
newer features are used, older versions of Blender will not be able to
see this extra data.
When an Action contains multiple slots, so with animation for multiple
distinct objects, the forward compatibility becomes a bit iffy. Older
versions of Blender will just see a legacy Action, with its legacy
semantics, and thus all objects that use that Action will receive the
exact same animation data. I don't think there's a way around this.
(_Unless we start breaking up Actions into an Action per slot, alter
the assignments, and then store metadata so that modern Blenders can
reassemble them. I do not think this is a good idea._)
Ref: #124714
Pull Request: https://projects.blender.org/blender/blender/pulls/125065
Rename leftover references to action 'bindings' to 'slot':
- Two comments, and
- bunch of `bind_` variable prefixes, renamed to `slot_`.
No functional changes.
Add `#ifdef WITH_ANIM_BAKLAVA` to the blend file reading/writing code,
so that the Action layers & slots are ignored when Blender is built
without experimental features.
This ensures that any loaded Action is just treated as 'legacy' (which
is the only kind of Action non-experimental Blender should have to deal
with), which will also properly deal with the forward compatible data
written by !125065.
This fix was committed on the `blender-v4.2-release` branch as
1b7485f20892523942752f81239807b2eab0f00b.
Pull Request: https://projects.blender.org/blender/blender/pulls/125068
All the arrays in the new Action DNA are named singularly (`layer_array`,
`fcurve_array` etc). `channelbags_array` was the only plural one. For
consistency, this is now also singular.
Note that this is a backward-incompatible change, and will effectively
erase all animation from layered Actions. No effort is taken to handle this
rename as the feature is still in its experimental phase.
Action and slot assignments are not affected by this change.
Apart from the lack of backward compatibility, no functional changes are
expected.
Pull Request: https://projects.blender.org/blender/blender/pulls/124768
This commit moves generated `RNA_blender.h`, `RNA_prototype.h` and
`RNA_blender_cpp.h` headers to become C++ header files.
It also removes the now useless `RNA_EXTERN_C` defines, and just
directly use the `extern` keyword. We do not need anymore `extern "C"`
declarations here.
Pull Request: https://projects.blender.org/blender/blender/pulls/124469
Instead of hard-coding `IDType_ID_AC.dependencies_id_types =
FILTER_ID_ALL`, which is overly broad, determine its value dynamically
in `id_type_init()` so that it's purely based on which `IDType`s
identify as 'animatable'.
This should make things like ID remapping a bit more efficient, as the
remapping code knows that an Action will only reference animatable
data-blocks.
Note that the initial value for the filter is still `FILTER_ID_ALL`,
so that in cases where (by accident) the call to `BKE_idtype_init()`
is omitted, semantically the situation is still correct. Not calling
this function is an easy to make oversight when writing unit tests.
Pull Request: https://projects.blender.org/blender/blender/pulls/124357
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
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
Avoid looping over all F-Curves in `bke::action_foreach_id()`. This was
only necessary to support the possible ID* in custom properties on the
Python F-Curve modifier, but that modifier has been removed in the
preceeding commit.
Even though `BKE_fcurve_foreach_id()` exists, it is only relevant for
drivers, but the F-Curves stored in an Action are always just animation
data, not drivers.
No functional changes intended.
Pull Request: https://projects.blender.org/blender/blender/pulls/123906
Keep track of which IDs are animated by which Action Binding. This will
be necessary for display in the Action editor, where animation data that
is unrelated to the active object can be shown (when "show all bindings"
is on).
Note: animation evaluation will not be using this cache, at least not in
the near future. Potentially when we introduce animation-level
constraints this will change, but that's for the future.
The user cache isn't actually used in this commit. It will be used soon
in !122672.
Pull Request: https://projects.blender.org/blender/blender/pulls/123187
Pull Request: https://projects.blender.org/blender/blender/pulls/123187
Add layered Action support to `BKE_action_frame_range_calc()`, by
looping over all F-Curves of all Bindings in the Action.
Introduce `animrig::fcurves_all(action)`, which returns a vector of all
F-Curves in the Action, both for legacy and layered Actions.
No functional changes for legacy Actions.
The setting adds the "Custom Shape Wire Width"
option to the "Viewport Display/Custom Shape" section of a pose bone.
As the setting says, this controls how thick the wire is drawn in the viewport.
This is done by adding a geometry shader that makes two triangles out of a line.
The Anti-Aliasing is controlled by the setting
Viewport->Quality->Smooth Wires->Overlay in the user preferences.
## Artifacts
When increasing the line width, the lines start to separate at their vertices.
This comes from extruding each edge along the normal of its direction.
This could be solved by adding round caps in a later PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/120176
The new/experimental, layered `Animation` data-block is merged with the
existing `bAction` data-block.
The `Animation` data-block is considerably newer than `bAction`, so the
supporting code that was written for it is also more modern. When moving
that code into `bAction`, I chose to keep the modernity where possible,
and thus some of the old code has been updated as well. Things like
preferring references over pointers.
The `Animation` data-block is now gone from DNA, the main database, etc.
As this was still an experimental feature, there is no versioning code
to convert any of that to Actions.
The DNA struct `bAction` now has a C++ wrapper `animrig::Action`, that
can be obtained via `some_action->wrap()`.
`animrig::Action` has functions `is_empty()`, `is_action_legacy()`, and
`is_action_layered()`. They **all** return `true` when the Action is
empty, as in that case none of the data that makes an action either
'legacy' or 'layered' is there.
The 'animation filtering' code (for showing things in the dope sheet,
graph editor, etc) that I wrote for `Animation` is intentionally kept
around. These types now target 'layered actions' and the
already-existing ones 'legacy actions'. A future PR may merge these two
together, but given how much work it was to add something new there, I'd
rather wait until the dust has settled on this commit.
There are plenty of variables (and some comments) named `anim` or
`animation` that now are of type `animrig::Action`. I haven't renamed
them all, to keep the noise level low in this commit (it's already big
enough). This can be done in a followup, non-functional PR.
Related task: #121355
Pull Request: https://projects.blender.org/blender/blender/pulls/121357
This allows node groups to have a description that is shown in the add menu
or when hovering over the node header.
This new description is stored in `bNodeTree.description`. Unfortunately, it
conflicts a bit with `ID.asset_data.description`. The difference is that the latter
only exists for assets. However, it makes sense for node groups to have
descriptions even if they are not assets (just like `static` functions in C++ should
also be able to have comments). In some cases, node groups are also generated
by addons for a specific purpose. Those should still have a description without
being reusable to make it easier to understand for users.
The solution here is to use the asset description if the node group is an asset,
and to use `bNodeTree.description` otherwise. The description is synced
automatically when marking or clearing assets.
A side benefit of this solution is that appended node group assets can keep their
description, which is currently always lost.
Pull Request: https://projects.blender.org/blender/blender/pulls/121334
This makes the read and write API functions match more closely, and adds
asserts to check that the data size is as expected.
There are still a few places remaining that use BLO_read_data_address
and similar generic functions, these should eventually be replaced as well.
Pull Request: https://projects.blender.org/blender/blender/pulls/120994
There are still a few places that are more complicated where the replacement
to `IDP_New` isn't obvious, but this commit replaces most uses of the ugly
`IDPropertyTemplate` usage.