Cleanup: Refactor animdata iterators to C++ callbacks
Pull Request: https://projects.blender.org/blender/blender/pulls/125485
This commit is contained in:
committed by
Lukas Stockner
parent
de9fc05af6
commit
1c7c1829b6
@@ -8,13 +8,15 @@
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
|
||||
#include "BLI_sys_types.h" /* for bool */
|
||||
#include "BLI_function_ref.hh"
|
||||
|
||||
struct AnimData;
|
||||
struct BlendDataReader;
|
||||
struct BlendWriter;
|
||||
struct FCurve;
|
||||
struct ID;
|
||||
struct Library;
|
||||
struct LibraryForeachIDData;
|
||||
@@ -170,3 +172,17 @@ void BKE_animdata_blend_read_data(BlendDataReader *reader, ID *id);
|
||||
* applied.
|
||||
*/
|
||||
void BKE_animdata_liboverride_post_process(ID *id);
|
||||
|
||||
/* ************************************* */
|
||||
/* Batch AnimData API */
|
||||
/* Loop over all datablocks applying callback */
|
||||
void BKE_animdata_main_cb(struct Main *bmain, blender::FunctionRef<void(ID *, AnimData *)> func);
|
||||
|
||||
/** Apply the given callback function on all F-Curves attached to data in `main` database. */
|
||||
void BKE_fcurves_main_cb(struct Main *bmain, blender::FunctionRef<void(ID *, FCurve *)> func);
|
||||
|
||||
/* Look over all f-curves of a given ID. */
|
||||
void BKE_fcurves_id_cb(struct ID *id, blender::FunctionRef<void(ID *, FCurve *)> func);
|
||||
|
||||
/* ************************************* */
|
||||
/* TODO: overrides, remapping, and path-finding API's. */
|
||||
|
||||
@@ -206,27 +206,6 @@ void BKE_animdata_transfer_by_basepath(struct Main *bmain,
|
||||
struct ID *dstID,
|
||||
struct ListBase *basepaths);
|
||||
|
||||
/* ************************************* */
|
||||
/* Batch AnimData API */
|
||||
|
||||
/* Define for callback looper used in BKE_animdata_main_cb */
|
||||
typedef void (*ID_AnimData_Edit_Callback)(struct ID *id, struct AnimData *adt, void *user_data);
|
||||
|
||||
/* Define for callback looper used in BKE_fcurves_main_cb */
|
||||
typedef void (*ID_FCurve_Edit_Callback)(struct ID *id, struct FCurve *fcu, void *user_data);
|
||||
|
||||
/* Loop over all datablocks applying callback */
|
||||
void BKE_animdata_main_cb(struct Main *bmain, ID_AnimData_Edit_Callback func, void *user_data);
|
||||
|
||||
/** Apply the given callback function on all F-Curves attached to data in `main` database. */
|
||||
void BKE_fcurves_main_cb(struct Main *bmain, ID_FCurve_Edit_Callback func, void *user_data);
|
||||
|
||||
/* Look over all f-curves of a given ID. */
|
||||
void BKE_fcurves_id_cb(struct ID *id, ID_FCurve_Edit_Callback func, void *user_data);
|
||||
|
||||
/* ************************************* */
|
||||
/* TODO: overrides, remapping, and path-finding API's. */
|
||||
|
||||
/* ------------ NLA Keyframing --------------- */
|
||||
|
||||
typedef struct NlaKeyframingContext NlaKeyframingContext;
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
|
||||
static CLG_LogRef LOG = {"bke.anim_sys"};
|
||||
|
||||
using blender::FunctionRef;
|
||||
|
||||
/* ***************************************** */
|
||||
/* AnimData API */
|
||||
|
||||
@@ -1214,80 +1216,72 @@ bool BKE_animdata_fix_paths_remove(ID *id, const char *prefix)
|
||||
|
||||
/* Apply Op to All FCurves in Database --------------------------- */
|
||||
|
||||
/* "User-Data" wrapper used by BKE_fcurves_main_cb() */
|
||||
struct AllFCurvesCbWrapper {
|
||||
ID_FCurve_Edit_Callback func; /* Operation to apply on F-Curve */
|
||||
void *user_data; /* Custom data for that operation */
|
||||
};
|
||||
|
||||
/* Helper for adt_apply_all_fcurves_cb() - Apply wrapped operator to list of F-Curves */
|
||||
static void fcurves_apply_cb(ID *id,
|
||||
ListBase *fcurves,
|
||||
ID_FCurve_Edit_Callback func,
|
||||
void *user_data)
|
||||
const FunctionRef<void(ID *, FCurve *)> func)
|
||||
{
|
||||
LISTBASE_FOREACH (FCurve *, fcu, fcurves) {
|
||||
func(id, fcu, user_data);
|
||||
func(id, fcu);
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for adt_apply_all_fcurves_cb() - Recursively go through each NLA strip */
|
||||
static void nlastrips_apply_all_curves_cb(ID *id, ListBase *strips, AllFCurvesCbWrapper *wrapper)
|
||||
static void nlastrips_apply_all_curves_cb(ID *id,
|
||||
ListBase *strips,
|
||||
const FunctionRef<void(ID *, FCurve *)> func)
|
||||
{
|
||||
LISTBASE_FOREACH (NlaStrip *, strip, strips) {
|
||||
/* fix strip's action */
|
||||
if (strip->act) {
|
||||
fcurves_apply_cb(id, &strip->act->curves, wrapper->func, wrapper->user_data);
|
||||
fcurves_apply_cb(id, &strip->act->curves, func);
|
||||
}
|
||||
|
||||
/* Check sub-strips (if meta-strips). */
|
||||
nlastrips_apply_all_curves_cb(id, &strip->strips, wrapper);
|
||||
nlastrips_apply_all_curves_cb(id, &strip->strips, func);
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper for BKE_fcurves_main_cb() - Dispatch wrapped operator to all F-Curves */
|
||||
static void adt_apply_all_fcurves_cb(ID *id, AnimData *adt, void *wrapper_data)
|
||||
static void adt_apply_all_fcurves_cb(ID *id,
|
||||
AnimData *adt,
|
||||
const FunctionRef<void(ID *, FCurve *)> func)
|
||||
{
|
||||
AllFCurvesCbWrapper *wrapper = static_cast<AllFCurvesCbWrapper *>(wrapper_data);
|
||||
|
||||
if (adt->action) {
|
||||
fcurves_apply_cb(id, &adt->action->curves, wrapper->func, wrapper->user_data);
|
||||
fcurves_apply_cb(id, &adt->action->curves, func);
|
||||
}
|
||||
|
||||
if (adt->tmpact) {
|
||||
fcurves_apply_cb(id, &adt->tmpact->curves, wrapper->func, wrapper->user_data);
|
||||
fcurves_apply_cb(id, &adt->tmpact->curves, func);
|
||||
}
|
||||
|
||||
/* free drivers - stored as a list of F-Curves */
|
||||
fcurves_apply_cb(id, &adt->drivers, wrapper->func, wrapper->user_data);
|
||||
fcurves_apply_cb(id, &adt->drivers, func);
|
||||
|
||||
/* NLA Data - Animation Data for Strips */
|
||||
LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
|
||||
nlastrips_apply_all_curves_cb(id, &nlt->strips, wrapper);
|
||||
nlastrips_apply_all_curves_cb(id, &nlt->strips, func);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_fcurves_id_cb(ID *id, ID_FCurve_Edit_Callback func, void *user_data)
|
||||
void BKE_fcurves_id_cb(ID *id, const FunctionRef<void(ID *, FCurve *)> func)
|
||||
{
|
||||
AnimData *adt = BKE_animdata_from_id(id);
|
||||
if (adt != nullptr) {
|
||||
AllFCurvesCbWrapper wrapper = {func, user_data};
|
||||
adt_apply_all_fcurves_cb(id, adt, &wrapper);
|
||||
adt_apply_all_fcurves_cb(id, adt, func);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_fcurves_main_cb(Main *bmain, ID_FCurve_Edit_Callback func, void *user_data)
|
||||
void BKE_fcurves_main_cb(Main *bmain, const FunctionRef<void(ID *, FCurve *)> func)
|
||||
{
|
||||
/* Wrap F-Curve operation stuff to pass to the general AnimData-level func */
|
||||
AllFCurvesCbWrapper wrapper = {func, user_data};
|
||||
|
||||
/* Use the AnimData-based function so that we don't have to reimplement all that stuff */
|
||||
BKE_animdata_main_cb(bmain, adt_apply_all_fcurves_cb, &wrapper);
|
||||
BKE_animdata_main_cb(bmain,
|
||||
[&](ID *id, AnimData *adt) { adt_apply_all_fcurves_cb(id, adt, func); });
|
||||
}
|
||||
|
||||
/* Whole Database Ops -------------------------------------------- */
|
||||
|
||||
void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *user_data)
|
||||
void BKE_animdata_main_cb(Main *bmain, const FunctionRef<void(ID *, AnimData *)> func)
|
||||
{
|
||||
ID *id;
|
||||
|
||||
@@ -1296,7 +1290,7 @@ void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *use
|
||||
for (id = static_cast<ID *>(first); id; id = static_cast<ID *>(id->next)) { \
|
||||
AnimData *adt = BKE_animdata_from_id(id); \
|
||||
if (adt) { \
|
||||
func(id, adt, user_data); \
|
||||
func(id, adt); \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
@@ -1309,11 +1303,11 @@ void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *use
|
||||
if (ntp->nodetree) { \
|
||||
AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
|
||||
if (adt2) { \
|
||||
func(id, adt2, user_data); \
|
||||
func(id, adt2); \
|
||||
} \
|
||||
} \
|
||||
if (adt) { \
|
||||
func(id, adt, user_data); \
|
||||
func(id, adt); \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
@@ -1412,115 +1406,10 @@ void BKE_animdata_fix_paths_rename_all_ex(Main *bmain,
|
||||
const int newSubscript,
|
||||
const bool verify_paths)
|
||||
{
|
||||
/* TODO: use BKE_animdata_main_cb for looping over all data. */
|
||||
|
||||
ID *id;
|
||||
|
||||
/* macro for less typing
|
||||
* - whether animdata exists is checked for by the main renaming callback, though taking
|
||||
* this outside of the function may make things slightly faster?
|
||||
*/
|
||||
#define RENAMEFIX_ANIM_IDS(first) \
|
||||
for (id = static_cast<ID *>(first); id; id = static_cast<ID *>(id->next)) { \
|
||||
AnimData *adt = BKE_animdata_from_id(id); \
|
||||
BKE_animdata_fix_paths_rename( \
|
||||
id, adt, ref_id, prefix, oldName, newName, oldSubscript, newSubscript, verify_paths); \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
/* Another version of this macro for node-trees. */
|
||||
#define RENAMEFIX_ANIM_NODETREE_IDS(first, NtId_Type) \
|
||||
for (id = static_cast<ID *>(first); id; id = static_cast<ID *>(id->next)) { \
|
||||
AnimData *adt = BKE_animdata_from_id(id); \
|
||||
NtId_Type *ntp = (NtId_Type *)id; \
|
||||
if (ntp->nodetree) { \
|
||||
AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
|
||||
BKE_animdata_fix_paths_rename((ID *)ntp->nodetree, \
|
||||
adt2, \
|
||||
ref_id, \
|
||||
prefix, \
|
||||
oldName, \
|
||||
newName, \
|
||||
oldSubscript, \
|
||||
newSubscript, \
|
||||
verify_paths); \
|
||||
} \
|
||||
BKE_animdata_fix_paths_rename( \
|
||||
id, adt, ref_id, prefix, oldName, newName, oldSubscript, newSubscript, verify_paths); \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
/* nodes */
|
||||
RENAMEFIX_ANIM_IDS(bmain->nodetrees.first);
|
||||
|
||||
/* textures */
|
||||
RENAMEFIX_ANIM_NODETREE_IDS(bmain->textures.first, Tex);
|
||||
|
||||
/* lights */
|
||||
RENAMEFIX_ANIM_NODETREE_IDS(bmain->lights.first, Light);
|
||||
|
||||
/* materials */
|
||||
RENAMEFIX_ANIM_NODETREE_IDS(bmain->materials.first, Material);
|
||||
|
||||
/* cameras */
|
||||
RENAMEFIX_ANIM_IDS(bmain->cameras.first);
|
||||
|
||||
/* shapekeys */
|
||||
RENAMEFIX_ANIM_IDS(bmain->shapekeys.first);
|
||||
|
||||
/* metaballs */
|
||||
RENAMEFIX_ANIM_IDS(bmain->metaballs.first);
|
||||
|
||||
/* curves */
|
||||
RENAMEFIX_ANIM_IDS(bmain->curves.first);
|
||||
|
||||
/* armatures */
|
||||
RENAMEFIX_ANIM_IDS(bmain->armatures.first);
|
||||
|
||||
/* lattices */
|
||||
RENAMEFIX_ANIM_IDS(bmain->lattices.first);
|
||||
|
||||
/* meshes */
|
||||
RENAMEFIX_ANIM_IDS(bmain->meshes.first);
|
||||
|
||||
/* particles */
|
||||
RENAMEFIX_ANIM_IDS(bmain->particles.first);
|
||||
|
||||
/* speakers */
|
||||
RENAMEFIX_ANIM_IDS(bmain->speakers.first);
|
||||
|
||||
/* movie clips */
|
||||
RENAMEFIX_ANIM_IDS(bmain->movieclips.first);
|
||||
|
||||
/* objects */
|
||||
RENAMEFIX_ANIM_IDS(bmain->objects.first);
|
||||
|
||||
/* masks */
|
||||
RENAMEFIX_ANIM_IDS(bmain->masks.first);
|
||||
|
||||
/* worlds */
|
||||
RENAMEFIX_ANIM_NODETREE_IDS(bmain->worlds.first, World);
|
||||
|
||||
/* linestyles */
|
||||
RENAMEFIX_ANIM_IDS(bmain->linestyles.first);
|
||||
|
||||
/* grease pencil */
|
||||
RENAMEFIX_ANIM_IDS(bmain->gpencils.first);
|
||||
|
||||
/* cache files */
|
||||
RENAMEFIX_ANIM_IDS(bmain->cachefiles.first);
|
||||
|
||||
/* Hair Curves. */
|
||||
RENAMEFIX_ANIM_IDS(bmain->hair_curves.first);
|
||||
|
||||
/* pointclouds */
|
||||
RENAMEFIX_ANIM_IDS(bmain->pointclouds.first);
|
||||
|
||||
/* volumes */
|
||||
RENAMEFIX_ANIM_IDS(bmain->volumes.first);
|
||||
|
||||
/* scenes */
|
||||
RENAMEFIX_ANIM_NODETREE_IDS(bmain->scenes.first, Scene);
|
||||
BKE_animdata_main_cb(bmain, [&](ID *id, AnimData *adt) {
|
||||
BKE_animdata_fix_paths_rename(
|
||||
id, adt, ref_id, prefix, oldName, newName, oldSubscript, newSubscript, verify_paths);
|
||||
});
|
||||
}
|
||||
|
||||
/* .blend file API -------------------------------------------- */
|
||||
|
||||
@@ -386,7 +386,7 @@ static char *replace_bbone_easing_rnapath(char *old_path)
|
||||
return old_path;
|
||||
}
|
||||
|
||||
static void do_version_bbone_easing_fcurve_fix(ID * /*id*/, FCurve *fcu, void * /*user_data*/)
|
||||
static void do_version_bbone_easing_fcurve_fix(ID * /*id*/, FCurve *fcu)
|
||||
{
|
||||
/* F-Curve's path (for bbone_in/out) */
|
||||
if (fcu->rna_path) {
|
||||
@@ -1626,6 +1626,6 @@ void do_versions_after_linking_270(Main *bmain)
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 279, 2)) {
|
||||
/* B-Bones (bbone_in/out -> bbone_easein/out) + Stepped FMod Frame Start/End fix */
|
||||
BKE_fcurves_main_cb(bmain, do_version_bbone_easing_fcurve_fix, nullptr);
|
||||
BKE_fcurves_main_cb(bmain, do_version_bbone_easing_fcurve_fix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
#undef DNA_GENFILE_VERSIONING_MACROS
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_anim_data.hh"
|
||||
#include "BKE_blender.hh"
|
||||
#include "BKE_collection.hh"
|
||||
#include "BKE_colortools.hh"
|
||||
@@ -579,13 +579,6 @@ static void do_version_bbone_scale_fcurve_fix(ListBase *curves, FCurve *fcu)
|
||||
}
|
||||
}
|
||||
|
||||
static void do_version_bbone_scale_animdata_cb(ID * /*id*/, AnimData *adt, void * /*wrapper_data*/)
|
||||
{
|
||||
LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &adt->drivers) {
|
||||
do_version_bbone_scale_fcurve_fix(&adt->drivers, fcu);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_version_constraints_maintain_volume_mode_uniform(ListBase *lb)
|
||||
{
|
||||
LISTBASE_FOREACH (bConstraint *, con, lb) {
|
||||
@@ -1001,16 +994,6 @@ static void do_version_curvemapping_walker(Main *bmain, void (*callback)(CurveMa
|
||||
}
|
||||
}
|
||||
|
||||
static void do_version_fcurve_hide_viewport_fix(ID * /*id*/, FCurve *fcu, void * /*user_data*/)
|
||||
{
|
||||
if (fcu->rna_path == nullptr || !STREQ(fcu->rna_path, "hide")) {
|
||||
return;
|
||||
}
|
||||
|
||||
MEM_freeN(fcu->rna_path);
|
||||
fcu->rna_path = BLI_strdupn("hide_viewport", 13);
|
||||
}
|
||||
|
||||
static void displacement_node_insert(bNodeTree *ntree)
|
||||
{
|
||||
bool need_update = false;
|
||||
@@ -1688,15 +1671,6 @@ static void update_noise_node_dimensions(bNodeTree *ntree)
|
||||
}
|
||||
}
|
||||
|
||||
/* This structure is only used to pass data to
|
||||
* update_mapping_node_fcurve_rna_path_callback.
|
||||
*/
|
||||
struct MappingNodeFCurveCallbackData {
|
||||
char *nodePath;
|
||||
bNode *minimumNode;
|
||||
bNode *maximumNode;
|
||||
};
|
||||
|
||||
/* This callback function is used by update_mapping_node_inputs_and_properties.
|
||||
* It is executed on every fcurve in the nodetree id updating its RNA paths. The
|
||||
* paths needs to be updated because the node properties became inputs.
|
||||
@@ -1711,10 +1685,12 @@ struct MappingNodeFCurveCallbackData {
|
||||
* update if the rna path starts with the rna path of the mapping node and
|
||||
* doesn't end with "default_value", that is, not the Vector input.
|
||||
*/
|
||||
static void update_mapping_node_fcurve_rna_path_callback(ID * /*id*/, FCurve *fcurve, void *_data)
|
||||
static void update_mapping_node_fcurve_rna_path_callback(FCurve *fcurve,
|
||||
const char *nodePath,
|
||||
const bNode *minimumNode,
|
||||
const bNode *maximumNode)
|
||||
{
|
||||
MappingNodeFCurveCallbackData *data = (MappingNodeFCurveCallbackData *)_data;
|
||||
if (!STRPREFIX(fcurve->rna_path, data->nodePath) ||
|
||||
if (!STRPREFIX(fcurve->rna_path, nodePath) ||
|
||||
BLI_str_endswith(fcurve->rna_path, "default_value"))
|
||||
{
|
||||
return;
|
||||
@@ -1722,22 +1698,22 @@ static void update_mapping_node_fcurve_rna_path_callback(ID * /*id*/, FCurve *fc
|
||||
char *old_fcurve_rna_path = fcurve->rna_path;
|
||||
|
||||
if (BLI_str_endswith(old_fcurve_rna_path, "translation")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", data->nodePath, "inputs[1].default_value");
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", nodePath, "inputs[1].default_value");
|
||||
}
|
||||
else if (BLI_str_endswith(old_fcurve_rna_path, "rotation")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", data->nodePath, "inputs[2].default_value");
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", nodePath, "inputs[2].default_value");
|
||||
}
|
||||
else if (BLI_str_endswith(old_fcurve_rna_path, "scale")) {
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", data->nodePath, "inputs[3].default_value");
|
||||
fcurve->rna_path = BLI_sprintfN("%s.%s", nodePath, "inputs[3].default_value");
|
||||
}
|
||||
else if (data->minimumNode && BLI_str_endswith(old_fcurve_rna_path, "max")) {
|
||||
char node_name_esc[sizeof(data->minimumNode->name) * 2];
|
||||
BLI_str_escape(node_name_esc, data->minimumNode->name, sizeof(node_name_esc));
|
||||
else if (minimumNode && BLI_str_endswith(old_fcurve_rna_path, "max")) {
|
||||
char node_name_esc[sizeof(minimumNode->name) * 2];
|
||||
BLI_str_escape(node_name_esc, minimumNode->name, sizeof(node_name_esc));
|
||||
fcurve->rna_path = BLI_sprintfN("nodes[\"%s\"].%s", node_name_esc, "inputs[1].default_value");
|
||||
}
|
||||
else if (data->maximumNode && BLI_str_endswith(old_fcurve_rna_path, "min")) {
|
||||
char node_name_esc[sizeof(data->maximumNode->name) * 2];
|
||||
BLI_str_escape(node_name_esc, data->maximumNode->name, sizeof(node_name_esc));
|
||||
else if (maximumNode && BLI_str_endswith(old_fcurve_rna_path, "min")) {
|
||||
char node_name_esc[sizeof(maximumNode->name) * 2];
|
||||
BLI_str_escape(node_name_esc, maximumNode->name, sizeof(node_name_esc));
|
||||
fcurve->rna_path = BLI_sprintfN("nodes[\"%s\"].%s", node_name_esc, "inputs[1].default_value");
|
||||
}
|
||||
|
||||
@@ -1861,8 +1837,9 @@ static void update_mapping_node_inputs_and_properties(bNodeTree *ntree)
|
||||
BLI_str_escape(node_name_esc, node->name, sizeof(node_name_esc));
|
||||
|
||||
char *nodePath = BLI_sprintfN("nodes[\"%s\"]", node_name_esc);
|
||||
MappingNodeFCurveCallbackData data = {nodePath, minimumNode, maximumNode};
|
||||
BKE_fcurves_id_cb(&ntree->id, update_mapping_node_fcurve_rna_path_callback, &data);
|
||||
BKE_fcurves_id_cb(&ntree->id, [&](ID * /*id*/, FCurve *fcu) {
|
||||
update_mapping_node_fcurve_rna_path_callback(fcu, nodePath, minimumNode, maximumNode);
|
||||
});
|
||||
MEM_freeN(nodePath);
|
||||
}
|
||||
}
|
||||
@@ -2943,7 +2920,14 @@ void do_versions_after_linking_280(FileData *fd, Main *bmain)
|
||||
/* During development of Blender 2.80 the "Object.hide" property was
|
||||
* removed, and reintroduced in 5e968a996a53 as "Object.hide_viewport". */
|
||||
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
||||
BKE_fcurves_id_cb(&ob->id, do_version_fcurve_hide_viewport_fix, nullptr);
|
||||
BKE_fcurves_id_cb(&ob->id, [&](ID * /*id*/, FCurve *fcu) {
|
||||
if (fcu->rna_path == nullptr || !STREQ(fcu->rna_path, "hide")) {
|
||||
return;
|
||||
}
|
||||
|
||||
MEM_freeN(fcu->rna_path);
|
||||
fcu->rna_path = BLI_strdupn("hide_viewport", 13);
|
||||
});
|
||||
}
|
||||
|
||||
/* Reset all grease pencil brushes. */
|
||||
@@ -5221,7 +5205,11 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
}
|
||||
}
|
||||
|
||||
BKE_animdata_main_cb(bmain, do_version_bbone_scale_animdata_cb, nullptr);
|
||||
BKE_animdata_main_cb(bmain, [](ID * /*id*/, AnimData *adt) {
|
||||
LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &adt->drivers) {
|
||||
do_version_bbone_scale_fcurve_fix(&adt->drivers, fcu);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Scene *, sce, &bmain->scenes) {
|
||||
|
||||
@@ -1459,15 +1459,6 @@ static void do_version_bbone_len_scale_fcurve_fix(FCurve *fcu)
|
||||
replace_bbone_len_scale_rnapath(&fcu->rna_path, &fcu->array_index);
|
||||
}
|
||||
|
||||
static void do_version_bbone_len_scale_animdata_cb(ID * /*id*/,
|
||||
AnimData *adt,
|
||||
void * /*wrapper_data*/)
|
||||
{
|
||||
LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &adt->drivers) {
|
||||
do_version_bbone_len_scale_fcurve_fix(fcu);
|
||||
}
|
||||
}
|
||||
|
||||
static void do_version_bones_bbone_len_scale(ListBase *lb)
|
||||
{
|
||||
LISTBASE_FOREACH (Bone *, bone, lb) {
|
||||
@@ -2369,7 +2360,7 @@ static void version_liboverride_nla_strip_frame_start_end(IDOverrideLibrary *lib
|
||||
}
|
||||
|
||||
/** Fix the `frame_start` and `frame_end` overrides on NLA strips. See #102662. */
|
||||
static void version_liboverride_nla_frame_start_end(ID *id, AnimData *adt, void * /*user_data*/)
|
||||
static void version_liboverride_nla_frame_start_end(ID *id, AnimData *adt)
|
||||
{
|
||||
IDOverrideLibrary *liboverride = id->override_library;
|
||||
if (!liboverride) {
|
||||
@@ -2511,7 +2502,11 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
}
|
||||
}
|
||||
|
||||
BKE_animdata_main_cb(bmain, do_version_bbone_len_scale_animdata_cb, nullptr);
|
||||
BKE_animdata_main_cb(bmain, [](ID * /*id*/, AnimData *adt) {
|
||||
LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &adt->drivers) {
|
||||
do_version_bbone_len_scale_fcurve_fix(fcu);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4516,7 +4511,7 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 306, 11)) {
|
||||
BKE_animdata_main_cb(bmain, version_liboverride_nla_frame_start_end, nullptr);
|
||||
BKE_animdata_main_cb(bmain, version_liboverride_nla_frame_start_end);
|
||||
|
||||
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_anim_data.hh"
|
||||
|
||||
#include "RNA_path.hh"
|
||||
|
||||
@@ -63,50 +63,33 @@ uint64_t AnimatedPropertyID::hash() const
|
||||
return uint64_t(((ptr1 >> 4) * 33) ^ (ptr2 >> 4));
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct AnimatedPropertyCallbackData {
|
||||
PointerRNA pointer_rna;
|
||||
AnimatedPropertyStorage *animated_property_storage;
|
||||
DepsgraphBuilderCache *builder_cache;
|
||||
};
|
||||
|
||||
void animated_property_cb(ID * /*id*/, FCurve *fcurve, void *data_v)
|
||||
{
|
||||
if (fcurve->rna_path == nullptr || fcurve->rna_path[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
AnimatedPropertyCallbackData *data = static_cast<AnimatedPropertyCallbackData *>(data_v);
|
||||
/* Resolve property. */
|
||||
PointerRNA pointer_rna;
|
||||
PropertyRNA *property_rna = nullptr;
|
||||
if (!RNA_path_resolve_property(
|
||||
&data->pointer_rna, fcurve->rna_path, &pointer_rna, &property_rna))
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* Get storage for the ID.
|
||||
* This is needed to deal with cases when nested datablock is animated by its parent. */
|
||||
AnimatedPropertyStorage *animated_property_storage = data->animated_property_storage;
|
||||
if (pointer_rna.owner_id != data->pointer_rna.owner_id) {
|
||||
animated_property_storage = data->builder_cache->ensureAnimatedPropertyStorage(
|
||||
pointer_rna.owner_id);
|
||||
}
|
||||
/* Set the property as animated. */
|
||||
animated_property_storage->tagPropertyAsAnimated(&pointer_rna, property_rna);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AnimatedPropertyStorage::AnimatedPropertyStorage() : is_fully_initialized(false) {}
|
||||
|
||||
void AnimatedPropertyStorage::initializeFromID(DepsgraphBuilderCache *builder_cache, const ID *id)
|
||||
{
|
||||
AnimatedPropertyCallbackData data;
|
||||
data.pointer_rna = RNA_id_pointer_create(const_cast<ID *>(id));
|
||||
data.animated_property_storage = this;
|
||||
data.builder_cache = builder_cache;
|
||||
BKE_fcurves_id_cb(const_cast<ID *>(id), animated_property_cb, &data);
|
||||
PointerRNA own_pointer_rna = RNA_id_pointer_create(const_cast<ID *>(id));
|
||||
BKE_fcurves_id_cb(const_cast<ID *>(id), [&](ID * /*id*/, FCurve *fcurve) {
|
||||
if (fcurve->rna_path == nullptr || fcurve->rna_path[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
/* Resolve property. */
|
||||
PointerRNA pointer_rna;
|
||||
PropertyRNA *property_rna = nullptr;
|
||||
if (!RNA_path_resolve_property(
|
||||
&own_pointer_rna, fcurve->rna_path, &pointer_rna, &property_rna))
|
||||
{
|
||||
return;
|
||||
}
|
||||
/* Get storage for the ID.
|
||||
* This is needed to deal with cases when nested datablock is animated by its parent. */
|
||||
AnimatedPropertyStorage *animated_property_storage = this;
|
||||
if (pointer_rna.owner_id != own_pointer_rna.owner_id) {
|
||||
animated_property_storage = builder_cache->ensureAnimatedPropertyStorage(
|
||||
pointer_rna.owner_id);
|
||||
}
|
||||
/* Set the property as animated. */
|
||||
animated_property_storage->tagPropertyAsAnimated(&pointer_rna, property_rna);
|
||||
});
|
||||
}
|
||||
|
||||
void AnimatedPropertyStorage::tagPropertyAsAnimated(const AnimatedPropertyID &property_id)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
|
||||
#include "BKE_anim_data.hh"
|
||||
#include "BKE_animsys.h"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
@@ -19,48 +20,6 @@
|
||||
|
||||
namespace blender::deg {
|
||||
|
||||
namespace {
|
||||
|
||||
struct AnimatedPropertyStoreCalbackData {
|
||||
AnimationBackup *backup;
|
||||
|
||||
/* ID which needs to be stored.
|
||||
* Is used to check possibly nested IDs which f-curves are pointing to. */
|
||||
ID *id;
|
||||
|
||||
PointerRNA id_pointer_rna;
|
||||
};
|
||||
|
||||
void animated_property_store_cb(ID *id, FCurve *fcurve, void *data_v)
|
||||
{
|
||||
AnimatedPropertyStoreCalbackData *data = reinterpret_cast<AnimatedPropertyStoreCalbackData *>(
|
||||
data_v);
|
||||
if (fcurve->rna_path == nullptr || fcurve->rna_path[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
if (id != data->id) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Resolve path to the property. */
|
||||
PathResolvedRNA resolved_rna;
|
||||
if (!BKE_animsys_rna_path_resolve(
|
||||
&data->id_pointer_rna, fcurve->rna_path, fcurve->array_index, &resolved_rna))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read property value. */
|
||||
float value;
|
||||
if (!BKE_animsys_read_from_rna_path(&resolved_rna, &value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
data->backup->values_backup.append({fcurve->rna_path, fcurve->array_index, value});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
AnimationValueBackup::AnimationValueBackup(const string &rna_path, int array_index, float value)
|
||||
: rna_path(rna_path), array_index(array_index), value(value)
|
||||
{
|
||||
@@ -84,11 +43,31 @@ void AnimationBackup::init_from_id(ID *id)
|
||||
* the current version of backup. */
|
||||
return;
|
||||
|
||||
AnimatedPropertyStoreCalbackData data;
|
||||
data.backup = this;
|
||||
data.id = id;
|
||||
data.id_pointer_rna = RNA_id_pointer_create(id);
|
||||
BKE_fcurves_id_cb(id, animated_property_store_cb, &data);
|
||||
PointerRNA id_pointer_rna = RNA_id_pointer_create(id);
|
||||
BKE_fcurves_id_cb(id, [&](ID *cb_id, FCurve *fcurve) {
|
||||
if (fcurve->rna_path == nullptr || fcurve->rna_path[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
if (id != cb_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Resolve path to the property. */
|
||||
PathResolvedRNA resolved_rna;
|
||||
if (!BKE_animsys_rna_path_resolve(
|
||||
&id_pointer_rna, fcurve->rna_path, fcurve->array_index, &resolved_rna))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read property value. */
|
||||
float value;
|
||||
if (!BKE_animsys_read_from_rna_path(&resolved_rna, &value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->values_backup.append({fcurve->rna_path, fcurve->array_index, value});
|
||||
});
|
||||
}
|
||||
|
||||
void AnimationBackup::restore_to_id(ID *id)
|
||||
|
||||
@@ -114,33 +114,23 @@ static void joined_armature_fix_links_constraints(Main *bmain,
|
||||
}
|
||||
}
|
||||
|
||||
/** User-data for #joined_armature_fix_animdata_cb(). */
|
||||
struct tJoinArmature_AdtFixData {
|
||||
Main *bmain;
|
||||
|
||||
Object *srcArm;
|
||||
Object *tarArm;
|
||||
|
||||
GHash *names_map;
|
||||
};
|
||||
|
||||
/* Callback to pass to BKE_animdata_main_cb() for fixing driver ID's to point to the new ID. */
|
||||
/* FIXME: For now, we only care about drivers here.
|
||||
* When editing rigs, it's very rare to have animation on the rigs being edited already,
|
||||
* so it should be safe to skip these.
|
||||
*/
|
||||
static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data)
|
||||
static void joined_armature_fix_animdata_cb(
|
||||
Main *bmain, ID *id, FCurve *fcu, Object *srcArm, Object *tarArm, GHash *names_map)
|
||||
{
|
||||
tJoinArmature_AdtFixData *afd = (tJoinArmature_AdtFixData *)user_data;
|
||||
ID *src_id = &afd->srcArm->id;
|
||||
ID *dst_id = &afd->tarArm->id;
|
||||
ID *src_id = &srcArm->id;
|
||||
ID *dst_id = &tarArm->id;
|
||||
|
||||
GHashIterator gh_iter;
|
||||
bool changed = false;
|
||||
|
||||
/* Fix paths - If this is the target object, it will have some "dirty" paths */
|
||||
if ((id == src_id) && strstr(fcu->rna_path, "pose.bones[")) {
|
||||
GHASH_ITER (gh_iter, afd->names_map) {
|
||||
GHASH_ITER (gh_iter, names_map) {
|
||||
const char *old_name = static_cast<const char *>(BLI_ghashIterator_getKey(&gh_iter));
|
||||
const char *new_name = static_cast<const char *>(BLI_ghashIterator_getValue(&gh_iter));
|
||||
|
||||
@@ -184,7 +174,7 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data
|
||||
* little twists so that we know that it isn't going to clobber the wrong data
|
||||
*/
|
||||
if ((dtar->rna_path && strstr(dtar->rna_path, "pose.bones[")) || (dtar->pchan_name[0])) {
|
||||
GHASH_ITER (gh_iter, afd->names_map) {
|
||||
GHASH_ITER (gh_iter, names_map) {
|
||||
const char *old_name = static_cast<const char *>(BLI_ghashIterator_getKey(&gh_iter));
|
||||
const char *new_name = static_cast<const char *>(
|
||||
BLI_ghashIterator_getValue(&gh_iter));
|
||||
@@ -212,7 +202,7 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
DEG_id_tag_update_ex(afd->bmain, id, ID_RECALC_SYNC_TO_EVAL);
|
||||
DEG_id_tag_update_ex(bmain, id, ID_RECALC_SYNC_TO_EVAL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,17 +352,13 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
|
||||
|
||||
CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
|
||||
if ((ob_iter->type == OB_ARMATURE) && (ob_iter != ob_active)) {
|
||||
tJoinArmature_AdtFixData afd = {nullptr};
|
||||
bArmature *curarm = static_cast<bArmature *>(ob_iter->data);
|
||||
|
||||
/* we assume that each armature datablock is only used in a single place */
|
||||
BLI_assert(ob_active->data != ob_iter->data);
|
||||
|
||||
/* init callback data for fixing up AnimData links later */
|
||||
afd.bmain = bmain;
|
||||
afd.srcArm = ob_iter;
|
||||
afd.tarArm = ob_active;
|
||||
afd.names_map = BLI_ghash_str_new("join_armature_adt_fix");
|
||||
GHash *names_map = BLI_ghash_str_new("join_armature_adt_fix");
|
||||
|
||||
/* Make a list of edit-bones in current armature */
|
||||
ED_armature_to_edit(curarm);
|
||||
@@ -400,7 +386,7 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* Get new name */
|
||||
ED_armature_ebone_unique_name(arm->edbo, curbone->name, nullptr);
|
||||
BLI_ghash_insert(afd.names_map, BLI_strdup(pchan->name), curbone->name);
|
||||
BLI_ghash_insert(names_map, BLI_strdup(pchan->name), curbone->name);
|
||||
|
||||
/* Transform the bone */
|
||||
{
|
||||
@@ -462,8 +448,10 @@ int ED_armature_join_objects_exec(bContext *C, wmOperator *op)
|
||||
DEG_id_tag_update_ex(bmain, &curarm->id, ID_RECALC_GEOMETRY);
|
||||
|
||||
/* Fix all the drivers (and animation data) */
|
||||
BKE_fcurves_main_cb(bmain, joined_armature_fix_animdata_cb, &afd);
|
||||
BLI_ghash_free(afd.names_map, MEM_freeN, nullptr);
|
||||
BKE_fcurves_main_cb(bmain, [&](ID *id, FCurve *fcu) {
|
||||
joined_armature_fix_animdata_cb(bmain, id, fcu, ob_iter, ob_active, names_map);
|
||||
});
|
||||
BLI_ghash_free(names_map, MEM_freeN, nullptr);
|
||||
|
||||
/* Only copy over animdata now, after all the remapping has been done,
|
||||
* so that we don't have to worry about ambiguities re which armature
|
||||
|
||||
@@ -2502,29 +2502,21 @@ void GPENCIL_OT_vertex_group_normalize_all(wmOperatorType *ot)
|
||||
|
||||
/****************************** Join ***********************************/
|
||||
|
||||
/** User-data for #gpencil_joined_fix_animdata_cb(). */
|
||||
struct tJoinGPencil_AdtFixData {
|
||||
bGPdata *src_gpd;
|
||||
bGPdata *tar_gpd;
|
||||
|
||||
GHash *names_map;
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback to pass to #BKE_fcurves_main_cb()
|
||||
* for RNA Paths attached to each F-Curve used in the #AnimData.
|
||||
*/
|
||||
static void gpencil_joined_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data)
|
||||
static void gpencil_joined_fix_animdata_cb(
|
||||
ID *id, FCurve *fcu, bGPdata *src_gpd, bGPdata *tar_gpd, GHash *names_map)
|
||||
{
|
||||
tJoinGPencil_AdtFixData *afd = (tJoinGPencil_AdtFixData *)user_data;
|
||||
ID *src_id = &afd->src_gpd->id;
|
||||
ID *dst_id = &afd->tar_gpd->id;
|
||||
ID *src_id = &src_gpd->id;
|
||||
ID *dst_id = &tar_gpd->id;
|
||||
|
||||
GHashIterator gh_iter;
|
||||
|
||||
/* Fix paths - If this is the target datablock, it will have some "dirty" paths */
|
||||
if ((id == src_id) && fcu->rna_path && strstr(fcu->rna_path, "layers[")) {
|
||||
GHASH_ITER (gh_iter, afd->names_map) {
|
||||
GHASH_ITER (gh_iter, names_map) {
|
||||
const char *old_name = static_cast<const char *>(BLI_ghashIterator_getKey(&gh_iter));
|
||||
const char *new_name = static_cast<const char *>(BLI_ghashIterator_getValue(&gh_iter));
|
||||
|
||||
@@ -2556,7 +2548,7 @@ static void gpencil_joined_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data)
|
||||
* little twists so that we know that it isn't going to clobber the wrong data
|
||||
*/
|
||||
if (dtar->rna_path && strstr(dtar->rna_path, "layers[")) {
|
||||
GHASH_ITER (gh_iter, afd->names_map) {
|
||||
GHASH_ITER (gh_iter, names_map) {
|
||||
const char *old_name = static_cast<const char *>(BLI_ghashIterator_getKey(&gh_iter));
|
||||
const char *new_name = static_cast<const char *>(
|
||||
BLI_ghashIterator_getValue(&gh_iter));
|
||||
@@ -2674,10 +2666,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
/* Duplicate #bGPDlayers. */
|
||||
tJoinGPencil_AdtFixData afd = {nullptr};
|
||||
afd.src_gpd = gpd_src;
|
||||
afd.tar_gpd = gpd_dst;
|
||||
afd.names_map = BLI_ghash_str_new("joined_gp_layers_map");
|
||||
GHash *names_map = BLI_ghash_str_new("joined_gp_layers_map");
|
||||
|
||||
float imat[3][3], bmat[3][3];
|
||||
float offset_global[3];
|
||||
@@ -2727,15 +2716,17 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
|
||||
'.',
|
||||
offsetof(bGPDlayer, info),
|
||||
sizeof(gpl_new->info));
|
||||
BLI_ghash_insert(afd.names_map, BLI_strdup(gpl_src->info), gpl_new->info);
|
||||
BLI_ghash_insert(names_map, BLI_strdup(gpl_src->info), gpl_new->info);
|
||||
|
||||
/* add to destination datablock */
|
||||
BLI_addtail(&gpd_dst->layers, gpl_new);
|
||||
}
|
||||
|
||||
/* Fix all the animation data */
|
||||
BKE_fcurves_main_cb(bmain, gpencil_joined_fix_animdata_cb, &afd);
|
||||
BLI_ghash_free(afd.names_map, MEM_freeN, nullptr);
|
||||
BKE_fcurves_main_cb(bmain, [&](ID *id, FCurve *fcu) {
|
||||
gpencil_joined_fix_animdata_cb(id, fcu, gpd_src, gpd_dst, names_map);
|
||||
});
|
||||
BLI_ghash_free(names_map, MEM_freeN, nullptr);
|
||||
|
||||
/* Only copy over animdata now, after all the remapping has been done,
|
||||
* so that we don't have to worry about ambiguities re which datablock
|
||||
|
||||
Reference in New Issue
Block a user