Using clang-tidy "cppcoreguidelines-pro-type-cstyle-cast" to find them.
This PR touches `bf_animrig` & `bf_editor_animation` & `bf_editor_armature`
NOTE: Also some case where untouched (not straightforward) same as
expanded macros (e.g. `LISTBASE` or `GS`)
NOTE: a couple of cases of "inconsistent-declaration-parameter" as well
Pull Request: https://projects.blender.org/blender/blender/pulls/136044
Fix an issue with library overrides that was caused by Action
assignments getting versioned too late in the versioning process. Now
the versioning of Action assignments (which assigns the
created-by-versioning action slots) happens in the 'after linking'
stage, as well as in the 'after setup' stage. The latter is still
necessary for the conversion of pre-2.5x animation data.
It is likely that the versioning code can now be simplified, as the
tagging for "this needs upgrading" may no longer be necessary. We're now
too close to the 4.4 release to comfortably make such bigger refactors,
though, so I'd rather keep the overall code structure as-is.
Pull Request: https://projects.blender.org/blender/blender/pulls/135988
Check existence of layer and slot before handling Channelbags.
The existing asserts dont catch this (they are skipping the "empty
layers" case) and rightfully so, think there might be usecases for
moving **empty** slots as well.
Pull Request: https://projects.blender.org/blender/blender/pulls/135963
The issue was that the `FCURVE_DISABLED` flag is set when an
RNA path cannot be resolved, and that skips evaluation.
However in the specific case, that is actually something expected as
the property only exists on one ID and not the other.
Pull Request: https://projects.blender.org/blender/blender/pulls/135782
Add an explanation to the keyframe insertion function
`animrig::insert_keyframes()` as to why it does not use
`ID_RECALC_ANIMATION`:
Animation flushing would be quite annoying in the following case:
- Key Cube's loc/rot/scale.
- Go to another frame.
- Translate, rotate, and scale the cube.
- Hover over the loc/rot/scale properties and one by one press 'I' to
insert a key there.
If `ID_RECALC_ANIMATION` were used, keying the location would immediately
cause a flush of the animation data, popping the rotation and scale back
to their animated values.
No functional changes.
The main issue of 'type-less' standard C allocations is that there is no check on
allocated type possible.
This is a serious source of annoyance (and crashes) when making some
low-level structs non-trivial, as tracking down all usages of these
structs in higher-level other structs and their allocation is... really
painful.
`MEM_[cm]allocN<T>` templates on the other hand do check that the
given type is trivial, at build time (static assert), which makes such issue...
trivial to catch.
NOTE: New code should strive to use `MEM_new` (i.e. allocation and
construction) as much as possible, even for trivial PoD types.
Pull Request: https://projects.blender.org/blender/blender/pulls/134452
When inserting keys in the viewport by pressing `I`,
certain custom properties would not get keyed if their name
was identical to existing properties (for example `scale`).
That was because we use the name of the property to resolve
an rna path and check if the path resolved. This was of course
true in the described case and the square brackets would never be added.
The solution is to check for `RNA_property_is_runtime` which is false
for properties defined inside Blender.
Pull Request: https://projects.blender.org/blender/blender/pulls/135304
The general idea is to keep the 'old', C-style MEM_callocN signature, and slowly
replace most of its usages with the new, C++-style type-safer template version.
* `MEM_cnew<T>` allocation version is renamed to `MEM_callocN<T>`.
* `MEM_cnew_array<T>` allocation version is renamed to `MEM_calloc_arrayN<T>`.
* `MEM_cnew<T>` duplicate version is renamed to `MEM_dupallocN<T>`.
Similar templates type-safe version of `MEM_mallocN` will be added soon
as well.
Following discussions in !134452.
NOTE: For now static type checking in `MEM_callocN` and related are slightly
different for Windows MSVC. This compiler seems to consider structs using the
`DNA_DEFINE_CXX_METHODS` macro as non-trivial (likely because their default
copy constructors are deleted). So using checks on trivially
constructible/destructible instead on this compiler/system.
Pull Request: https://projects.blender.org/blender/blender/pulls/134771
Make `action_channelbag_ensure()` and `action_fcurve_ensure()` return a
reference. Earlier it returned pointer that should never be `nullptr`,
but in certain cases (which would indicate a bug, as the function's
preconditions aren't met) could technically still be a `nullptr`.
Instead, the preconditions are checked with `BLI_assert()`, and a
release build will simply assume that they are met. This simplifies the
code of the functions themselves, as well as the callers.
For reference: this was discussed in !134866.
No functional changes.
Pull Request: https://projects.blender.org/blender/blender/pulls/134918
Over time the `FCurveDescriptor` class has grown, and some concern was
raised (!134866) about the performance impact of passing it by value.
It's now passed by const reference instead.
No functional changes. I did find some non-`const` uses that are now
also `const`.
Pull Request: https://projects.blender.org/blender/blender/pulls/134913
Split the majority of `animrig::action_fcurve_ensure()` into a new
function `action_channelbag_ensure()`. This ensures that the Action has
a layer, keyframe strip, action slot, and channelbag for the given ID.
`animrig::action_fcurve_ensure()` now just calls into that function, and
then ensures that there is an F-Curve in that channelbag.
No functional changes.
Pull Request: https://projects.blender.org/blender/blender/pulls/134864
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
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
Move `Library.runtime` to be a pointer, move the related
`LibraryRuntime` struct to `BKE_library.hh`. Similar to e.g.
Mesh.runtime, that pointer is expected to always be valid, and is
allocated at readtime or when creating a new Library ID.
Related smaller changes:
* Write code now uses standard ID writing codepath for Library IDs too.
* Runtime pointer is reset to nullptr before writing.
* Looking up a library by its absolute path is now handled through a
dedicated utils, `search_filepath_abs`, instead of using
`BLI_findstring`.
Pull Request: https://projects.blender.org/blender/blender/pulls/134188
The previous name was confusingly similar to the new method
`identifier_prefix()` that was introduced in #133983. This new name
better distinguishes them while also reflecting its actual functionality
better and being shorter.
Pull Request: https://projects.blender.org/blender/blender/pulls/134046
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
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
Similar to how brush assets are created and managed this
PR allows to export pose assets into a different library.
Because of this there is a limitation to this where each
asset is stored in a separate blend file.
This may be lifted in the future as there are planned changes in
the design phase: #122061
### Create Asset
Now available in the 3D viewport in the "Pose" menu: "Create Pose Asset".
The button in the Dope Sheet will now call this new operator as well.
Clicking either of those will open a popup in which you can:
* Choose the name of the asset, which library and catalog it goes into.
* Clicking "Create" will create a pose asset on disk in the given library.
It is possible to create files into an outside library or add it in the current file.
The latter option does a lot less since it basically just creates the
action and tags it as an asset.
If no Asset Shelf **AND** no Asset Browser is visible anywhere in Blender,
the Asset Shelf will be shown on the 3D viewport from which
the operator was called.
### Adjust Pose Asset
Right clicking a pose asset that has been created in the way described
before will have options to overwrite it.
Only the active object will be considered for updating a pose asset
Available Options (the latter 3 under the "Modify Pose Asset" submenu):
* Adjust Pose Asset: From the selected bones, update ONLY channels that
are also present in the asset. This is the default.
* Replace: Will completely replace the data in the Pose Asset from
the current selection
* Add: Adds the current selection to the Pose Asset. Any already existing
channels have their values updated
* Remove: Remove selected bones from the pose asset
Currently this refreshes the thumbnail. In the case of custom
thumbnails it might not be something want
### Deleting an existing Pose Asset
Right click on a Pose Asset and hit "Delete Pose Asset". Works in the shelf
and in the asset library. Doing so will pop up a confirmation dialog,
if confirming, the asset is gone forever. Deleting a local asset is basically the
same as clearing the asset. This is a bit confusing because you get
two options that basically do the same thing sometimes,
but "Delete" works in other cases as well.
I currently don't see a way around that.
Part of design #131840
Pull Request: https://projects.blender.org/blender/blender/pulls/132747
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
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
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
When writing an Action to a blend file, for forward compatability
reasons the animation data in the first slot is also written to the old
Animato Action storage locations. That way, loading the Action in an
older version of Blender will still at least have that animation data.
However, we overlooked `Action.idroot`, which indicates which ID
type the Action is for, and therefore all Actions have an unspecified
`idroot` when loaded in pre-layered-action versions of Blender.
This PR fixes that by also setting the `idroot` to match the target ID
type of the first slot when writing to disk.
Pull Request: https://projects.blender.org/blender/blender/pulls/133819
Refactor the keyframe copy-paste code to prepare for supporting action slots.
This is a non-functional change, as the slots are stored but otherwise completely ignored. This way the refactor to the new data structure can be reviewed & tested before actually changing the behaviour.
Related: #129690
Pull Request: https://projects.blender.org/blender/blender/pulls/133497
There were three methods with succinct but slightly unclear names:
- Action::slot_move()
- Channelbag::channel_group_move()
- Channelbag::fcurve_move()
The ambiguity is due to other functions with similar names that e.g.
move fcurves *between* Channelbags, etc. Whereas these methods only move
items to other positions within the array they're already in.
To make this clearer, this PR adds `_to_index` to the end of these
array-oriented methods.
Pull Request: https://projects.blender.org/blender/blender/pulls/133730
This updates the Move Channels operator in the Action Editor channel list to
also work with Slots, allowing Slots to be reordered within an Action.
Note that the Move Channels operator already had interesting behavior when
channels are selected in multiple levels of the channel hierarchy (e.g. when
both channel groups and f-curve channels are selected). For Slots, I've chosen
a simpler behavior: if any Slot is moved, all non-Slot channels (i.e. those
lower in the hierarchy) are left alone.
In the future we may want to change channel group rearrangement to work the same
way with respect to f-curve channels, but I've left that alone for now.
Pull Request: https://projects.blender.org/blender/blender/pulls/133328
When assigning an Action to an ID, a slot can be automatically
assigned as well. This behaviour is now extended by making untyped
slot identifiers (like `XXSlot`) act as wildcards.
If the last-used slot identifier was 'untyped' (like `XXSlot`), and a
slot with the same name that is specific to the animated ID's type
exists, that slot will be chosen.
Similarly, if the last-used slot identifier was 'typed' (like
`OBSlot`), a slot `OBSlot` does NOT exist, but an untyped slot with
the same name exists (like `XXSlot`), that one will be chosen.
If there is any ambiguity in the matter, the more specific slot is
chosen. In other words, in this case:
- last_slot_identifier = `XXSlot`
- both `XXSlot` and `OBSlot` exist on the Action (where `OB`
represents the ID type of `animated_id`).
the `OBSlot` should be chosen. This means that `XXSlot` NOT being
auto-assigned if there is an alternative. Since untyped slots are
bound on assignment, this design keeps the Action as-is, which means
that the `XXSlot` remains untyped and thus the user is free to assign
this to another ID type if desired.
Pull Request: https://projects.blender.org/blender/blender/pulls/133653
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
Deduplicate `assign_action_ensure_slot_for_keying()` and
`generic_slot_for_autoassign()`.
Some of the functionality of the latter function was copied into the
former. This has now been replaced by actually calling the function in
the appropriate spot.
No functional changes.
Pull Request: https://projects.blender.org/blender/blender/pulls/133652
An Action slot usually has a specific ID type (`ActionSlot::idtype`).
When this is set to 0, it is not specifc to any particular ID type. The
latter case was called "unbound", and is now called "untyped".
Note that untyped slots are given an ID type as soon as they are
actually assigned to any ID.
No functional changes.
Pull Request: https://projects.blender.org/blender/blender/pulls/133651