Blender  V2.93
anim_data.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung
17  * All rights reserved.
18  */
19 
23 #include "MEM_guardedalloc.h"
24 
25 #include <string.h>
26 
27 #include "BKE_action.h"
28 #include "BKE_anim_data.h"
29 #include "BKE_animsys.h"
30 #include "BKE_context.h"
31 #include "BKE_fcurve.h"
32 #include "BKE_fcurve_driver.h"
33 #include "BKE_global.h"
34 #include "BKE_idtype.h"
35 #include "BKE_lib_id.h"
36 #include "BKE_lib_query.h"
37 #include "BKE_main.h"
38 #include "BKE_nla.h"
39 #include "BKE_node.h"
40 #include "BKE_report.h"
41 
42 #include "DNA_ID.h"
43 #include "DNA_anim_types.h"
44 #include "DNA_light_types.h"
45 #include "DNA_material_types.h"
46 #include "DNA_node_types.h"
47 #include "DNA_space_types.h"
49 #include "DNA_world_types.h"
50 
51 #include "BLI_alloca.h"
52 #include "BLI_dynstr.h"
53 #include "BLI_listbase.h"
54 #include "BLI_string.h"
55 #include "BLI_utildefines.h"
56 
57 #include "DEG_depsgraph.h"
58 
59 #include "BLO_read_write.h"
60 
61 #include "RNA_access.h"
62 
63 #include "CLG_log.h"
64 
65 static CLG_LogRef LOG = {"bke.anim_sys"};
66 
67 /* ***************************************** */
68 /* AnimData API */
69 
70 /* Getter/Setter -------------------------------------------- */
71 
72 /* Check if ID can have AnimData */
73 bool id_type_can_have_animdata(const short id_type)
74 {
75  const IDTypeInfo *typeinfo = BKE_idtype_get_info_from_idcode(id_type);
76  if (typeinfo != NULL) {
77  return (typeinfo->flags & IDTYPE_FLAGS_NO_ANIMDATA) == 0;
78  }
79  return false;
80 }
81 
82 bool id_can_have_animdata(const ID *id)
83 {
84  /* sanity check */
85  if (id == NULL) {
86  return false;
87  }
88 
90 }
91 
92 /* Get AnimData from the given ID-block. In order for this to work, we assume that
93  * the AnimData pointer is stored immediately after the given ID-block in the struct,
94  * as per IdAdtTemplate.
95  */
97 {
98  /* only some ID-blocks have this info for now, so we cast the
99  * types that do to be of type IdAdtTemplate, and extract the
100  * AnimData that way
101  */
102  if (id_can_have_animdata(id)) {
103  IdAdtTemplate *iat = (IdAdtTemplate *)id;
104  return iat->adt;
105  }
106  return NULL;
107 }
108 
109 /* Add AnimData to the given ID-block. In order for this to work, we assume that
110  * the AnimData pointer is stored immediately after the given ID-block in the struct,
111  * as per IdAdtTemplate. Also note that
112  */
114 {
115  /* Only some ID-blocks have this info for now, so we cast the
116  * types that do to be of type IdAdtTemplate, and add the AnimData
117  * to it using the template
118  */
119  if (id_can_have_animdata(id)) {
120  IdAdtTemplate *iat = (IdAdtTemplate *)id;
121 
122  /* check if there's already AnimData, in which case, don't add */
123  if (iat->adt == NULL) {
124  AnimData *adt;
125 
126  /* add animdata */
127  adt = iat->adt = MEM_callocN(sizeof(AnimData), "AnimData");
128 
129  /* set default settings */
130  adt->act_influence = 1.0f;
131  }
132 
133  return iat->adt;
134  }
135  return NULL;
136 }
137 
138 /* Action Setter --------------------------------------- */
139 
150 bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
151 {
152  AnimData *adt = BKE_animdata_from_id(id);
153 
154  /* Animdata validity check. */
155  if (adt == NULL) {
156  BKE_report(reports, RPT_WARNING, "No AnimData to set action on");
157  return false;
158  }
159 
160  if (adt->action == act) {
161  /* Don't bother reducing and increasing the user count when there is nothing changing. */
162  return true;
163  }
164 
165  if (!BKE_animdata_action_editable(adt)) {
166  /* Cannot remove, otherwise things turn to custard. */
167  BKE_report(reports, RPT_ERROR, "Cannot change action, as it is still being edited in NLA");
168  return false;
169  }
170 
171  /* Reduce usercount for current action. */
172  if (adt->action) {
173  id_us_min((ID *)adt->action);
174  }
175 
176  if (act == NULL) {
177  /* Just clearing the action. */
178  adt->action = NULL;
179  return true;
180  }
181 
182  /* Action must have same type as owner. */
183  if (!BKE_animdata_action_ensure_idroot(id, act)) {
184  /* Cannot set to this type. */
185  BKE_reportf(
186  reports,
187  RPT_ERROR,
188  "Could not set action '%s' onto ID '%s', as it does not have suitably rooted paths "
189  "for this purpose",
190  act->id.name + 2,
191  id->name);
192  return false;
193  }
194 
195  adt->action = act;
196  id_us_plus((ID *)adt->action);
197 
198  return true;
199 }
200 
202 {
203  /* Active action is only editable when it is not a tweaking strip. */
204  const bool is_tweaking_strip = (adt->flag & ADT_NLA_EDIT_ON) || adt->actstrip != NULL ||
205  adt->tmpact != NULL;
206  return !is_tweaking_strip;
207 }
208 
209 bool BKE_animdata_action_ensure_idroot(const ID *owner, bAction *action)
210 {
211  const int idcode = GS(owner->name);
212 
213  if (action == NULL) {
214  /* A NULL action is usable by any ID type. */
215  return true;
216  }
217 
218  if (action->idroot == 0) {
219  /* First time this Action is assigned, lock it to this ID type. */
220  action->idroot = idcode;
221  return true;
222  }
223 
224  return (action->idroot == idcode);
225 }
226 
227 /* Freeing -------------------------------------------- */
228 
229 /* Free AnimData used by the nominated ID-block, and clear ID-block's AnimData pointer */
230 void BKE_animdata_free(ID *id, const bool do_id_user)
231 {
232  /* Only some ID-blocks have this info for now, so we cast the
233  * types that do to be of type IdAdtTemplate
234  */
235  if (id_can_have_animdata(id)) {
236  IdAdtTemplate *iat = (IdAdtTemplate *)id;
237  AnimData *adt = iat->adt;
238 
239  /* check if there's any AnimData to start with */
240  if (adt) {
241  if (do_id_user) {
242  /* unlink action (don't free, as it's in its own list) */
243  if (adt->action) {
244  id_us_min(&adt->action->id);
245  }
246  /* same goes for the temporarily displaced action */
247  if (adt->tmpact) {
248  id_us_min(&adt->tmpact->id);
249  }
250  }
251 
252  /* free nla data */
253  BKE_nla_tracks_free(&adt->nla_tracks, do_id_user);
254 
255  /* free drivers - stored as a list of F-Curves */
256  BKE_fcurves_free(&adt->drivers);
257 
258  /* free driver array cache */
260 
261  /* free overrides */
262  /* TODO... */
263 
264  /* free animdata now */
265  MEM_freeN(adt);
266  iat->adt = NULL;
267  }
268  }
269 }
270 
271 bool BKE_animdata_id_is_animated(const struct ID *id)
272 {
273  if (id == NULL) {
274  return false;
275  }
276 
277  const AnimData *adt = BKE_animdata_from_id((ID *)id);
278  if (adt == NULL) {
279  return false;
280  }
281 
282  if (adt->action != NULL && !BLI_listbase_is_empty(&adt->action->curves)) {
283  return true;
284  }
285 
288 }
289 
295 {
296  LISTBASE_FOREACH (FCurve *, fcu, &adt->drivers) {
298  }
299 
302 
303  LISTBASE_FOREACH (NlaTrack *, nla_track, &adt->nla_tracks) {
304  LISTBASE_FOREACH (NlaStrip *, nla_strip, &nla_track->strips) {
305  BKE_nla_strip_foreach_id(nla_strip, data);
306  }
307  }
308 }
309 
310 /* Copying -------------------------------------------- */
311 
318 AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag)
319 {
320  AnimData *dadt;
321 
322  const bool do_action = (flag & LIB_ID_COPY_ACTIONS) != 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0;
323  const bool do_id_user = (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0;
324 
325  /* sanity check before duplicating struct */
326  if (adt == NULL) {
327  return NULL;
328  }
329  dadt = MEM_dupallocN(adt);
330 
331  /* make a copy of action - at worst, user has to delete copies... */
332  if (do_action) {
333  /* Recursive copy of 'real' IDs is a bit hairy. Even if do not want to deal with usercount
334  * when copying ID's data itself, we still need to do so with sub-IDs, since those will not be
335  * handled by later 'update usercounts of used IDs' code as used e.g. at end of
336  * BKE_id_copy_ex().
337  * So in case we do copy the ID and its sub-IDs in bmain, silence the 'no usercount' flag for
338  * the sub-IDs copying.
339  * Note: This is a bit weak, as usually when it comes to recursive ID copy. Should work for
340  * now, but we may have to revisit this at some point and add a proper extra flag to deal with
341  * that situation. Or refactor completely the way we handle such recursion, by flattening it
342  * e.g. */
343  const int id_copy_flag = (flag & LIB_ID_CREATE_NO_MAIN) == 0 ?
345  flag;
346  BLI_assert(bmain != NULL);
347  BLI_assert(dadt->action == NULL || dadt->action != dadt->tmpact);
348  dadt->action = (bAction *)BKE_id_copy_ex(bmain, (ID *)dadt->action, NULL, id_copy_flag);
349  dadt->tmpact = (bAction *)BKE_id_copy_ex(bmain, (ID *)dadt->tmpact, NULL, id_copy_flag);
350  }
351  else if (do_id_user) {
352  id_us_plus((ID *)dadt->action);
353  id_us_plus((ID *)dadt->tmpact);
354  }
355 
356  /* duplicate NLA data */
357  BKE_nla_tracks_copy(bmain, &dadt->nla_tracks, &adt->nla_tracks, flag);
358 
359  /* duplicate drivers (F-Curves) */
360  BKE_fcurves_copy(&dadt->drivers, &adt->drivers);
361  dadt->driver_array = NULL;
362 
363  /* don't copy overrides */
365 
366  /* return */
367  return dadt;
368 }
369 
375 bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const int flag)
376 {
377  AnimData *adt;
378 
379  if ((id_to && id_from) && (GS(id_to->name) != GS(id_from->name))) {
380  return false;
381  }
382 
384 
385  adt = BKE_animdata_from_id(id_from);
386  if (adt) {
387  IdAdtTemplate *iat = (IdAdtTemplate *)id_to;
388  iat->adt = BKE_animdata_copy(bmain, adt, flag);
389  }
390 
391  return true;
392 }
393 
394 static void animdata_copy_id_action(Main *bmain,
395  ID *id,
396  const bool set_newid,
397  const bool do_linked_id)
398 {
399  AnimData *adt = BKE_animdata_from_id(id);
400  if (adt) {
401  if (adt->action && (do_linked_id || !ID_IS_LINKED(adt->action))) {
402  id_us_min((ID *)adt->action);
403  adt->action = set_newid ? ID_NEW_SET(adt->action, BKE_id_copy(bmain, &adt->action->id)) :
404  BKE_id_copy(bmain, &adt->action->id);
405  }
406  if (adt->tmpact && (do_linked_id || !ID_IS_LINKED(adt->tmpact))) {
407  id_us_min((ID *)adt->tmpact);
408  adt->tmpact = set_newid ? ID_NEW_SET(adt->tmpact, BKE_id_copy(bmain, &adt->tmpact->id)) :
409  BKE_id_copy(bmain, &adt->tmpact->id);
410  }
411  }
412  bNodeTree *ntree = ntreeFromID(id);
413  if (ntree) {
414  animdata_copy_id_action(bmain, &ntree->id, set_newid, do_linked_id);
415  }
416  /* Note that collections are not animatable currently, so no need to handle scenes' master
417  * collection here. */
418 }
419 
421 {
422  const bool is_id_liboverride = ID_IS_OVERRIDE_LIBRARY(id);
423  animdata_copy_id_action(bmain, id, false, !is_id_liboverride);
424 }
425 
427  struct ID *id,
428  const eDupli_ID_Flags duplicate_flags)
429 {
430  if (duplicate_flags & USER_DUP_ACT) {
431  animdata_copy_id_action(bmain, id, true, (duplicate_flags & USER_DUP_LINKED_ID) != 0);
432  }
433 }
434 
435 /* Merge copies of the data from the src AnimData into the destination AnimData */
437  Main *bmain, ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
438 {
439  AnimData *src = BKE_animdata_from_id(src_id);
440  AnimData *dst = BKE_animdata_from_id(dst_id);
441 
442  /* sanity checks */
443  if (ELEM(NULL, dst, src)) {
444  return;
445  }
446 
447  // TODO: we must unset all "tweakmode" flags
448  if ((src->flag & ADT_NLA_EDIT_ON) || (dst->flag & ADT_NLA_EDIT_ON)) {
449  CLOG_ERROR(
450  &LOG,
451  "Merging AnimData blocks while editing NLA is dangerous as it may cause data corruption");
452  return;
453  }
454 
455  /* handle actions... */
456  if (action_mode == ADT_MERGECOPY_SRC_COPY) {
457  /* make a copy of the actions */
458  dst->action = (bAction *)BKE_id_copy(bmain, &src->action->id);
459  dst->tmpact = (bAction *)BKE_id_copy(bmain, &src->tmpact->id);
460  }
461  else if (action_mode == ADT_MERGECOPY_SRC_REF) {
462  /* make a reference to it */
463  dst->action = src->action;
464  id_us_plus((ID *)dst->action);
465 
466  dst->tmpact = src->tmpact;
467  id_us_plus((ID *)dst->tmpact);
468  }
469 
470  /* duplicate NLA data */
471  if (src->nla_tracks.first) {
472  ListBase tracks = {NULL, NULL};
473 
474  BKE_nla_tracks_copy(bmain, &tracks, &src->nla_tracks, 0);
476  }
477 
478  /* duplicate drivers (F-Curves) */
479  if (src->drivers.first) {
480  ListBase drivers = {NULL, NULL};
481 
482  BKE_fcurves_copy(&drivers, &src->drivers);
483 
484  /* Fix up all driver targets using the old target id
485  * - This assumes that the src ID is being merged into the dst ID
486  */
487  if (fix_drivers) {
488  FCurve *fcu;
489 
490  for (fcu = drivers.first; fcu; fcu = fcu->next) {
491  ChannelDriver *driver = fcu->driver;
492  DriverVar *dvar;
493 
494  for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
496  if (dtar->id == src_id) {
497  dtar->id = dst_id;
498  }
499  }
501  }
502  }
503  }
504 
505  BLI_movelisttolist(&dst->drivers, &drivers);
506  }
507 }
508 
509 /* Sub-ID Regrouping ------------------------------------------- */
510 
518 static bool animpath_matches_basepath(const char path[], const char basepath[])
519 {
520  /* we need start of path to be basepath */
521  return (path && basepath) && STRPREFIX(path, basepath);
522 }
523 
525  const char *old_basepath,
526  const char *new_basepath)
527 {
528  BLI_assert(animpath_matches_basepath(fcu->rna_path, old_basepath));
529  if (STREQ(old_basepath, new_basepath)) {
530  return;
531  }
532 
533  char *new_path = BLI_sprintfN("%s%s", new_basepath, fcu->rna_path + strlen(old_basepath));
534  MEM_freeN(fcu->rna_path);
535  fcu->rna_path = new_path;
536 }
537 
538 /* Move F-Curves in src action to dst action, setting up all the necessary groups
539  * for this to happen, but only if the F-Curves being moved have the appropriate
540  * "base path".
541  * - This is used when data moves from one data-block to another, causing the
542  * F-Curves to need to be moved over too
543  */
545  bAction *dstAct,
546  const char *src_basepath,
547  const char *dst_basepath)
548 {
549  FCurve *fcu, *fcn = NULL;
550 
551  /* sanity checks */
552  if (ELEM(NULL, srcAct, dstAct, src_basepath, dst_basepath)) {
553  if (G.debug & G_DEBUG) {
554  CLOG_ERROR(&LOG,
555  "srcAct: %p, dstAct: %p, src_basepath: %p, dst_basepath: %p has insufficient "
556  "info to work with",
557  (void *)srcAct,
558  (void *)dstAct,
559  (void *)src_basepath,
560  (void *)dst_basepath);
561  }
562  return;
563  }
564 
565  /* clear 'temp' flags on all groups in src, as we'll be needing them later
566  * to identify groups that we've managed to empty out here
567  */
569 
570  /* iterate over all src F-Curves, moving over the ones that need to be moved */
571  for (fcu = srcAct->curves.first; fcu; fcu = fcn) {
572  /* store next pointer in case we move stuff */
573  fcn = fcu->next;
574 
575  /* should F-Curve be moved over?
576  * - we only need the start of the path to match basepath
577  */
578  if (animpath_matches_basepath(fcu->rna_path, src_basepath)) {
579  bActionGroup *agrp = NULL;
580 
581  /* if grouped... */
582  if (fcu->grp) {
583  /* make sure there will be a matching group on the other side for the migrants */
584  agrp = BKE_action_group_find_name(dstAct, fcu->grp->name);
585 
586  if (agrp == NULL) {
587  /* add a new one with a similar name (usually will be the same though) */
588  agrp = action_groups_add_new(dstAct, fcu->grp->name);
589  }
590 
591  /* old groups should be tagged with 'temp' flags so they can be removed later
592  * if we remove everything from them
593  */
594  fcu->grp->flag |= AGRP_TEMP;
595  }
596 
597  /* perform the migration now */
598  action_groups_remove_channel(srcAct, fcu);
599 
600  animpath_update_basepath(fcu, src_basepath, dst_basepath);
601 
602  if (agrp) {
603  action_groups_add_channel(dstAct, agrp, fcu);
604  }
605  else {
606  BLI_addtail(&dstAct->curves, fcu);
607  }
608  }
609  }
610 
611  /* cleanup groups (if present) */
612  if (srcAct->groups.first) {
613  bActionGroup *agrp, *grp = NULL;
614 
615  for (agrp = srcAct->groups.first; agrp; agrp = grp) {
616  grp = agrp->next;
617 
618  /* only tagged groups need to be considered - clearing these tags or removing them */
619  if (agrp->flag & AGRP_TEMP) {
620  /* if group is empty and tagged, then we can remove as this operation
621  * moved out all the channels that were formerly here
622  */
623  if (BLI_listbase_is_empty(&agrp->channels)) {
624  BLI_freelinkN(&srcAct->groups, agrp);
625  }
626  else {
627  agrp->flag &= ~AGRP_TEMP;
628  }
629  }
630  }
631  }
632 }
633 
635  AnimData *dstAdt,
636  const char *src_basepath,
637  const char *dst_basepath)
638 {
639  LISTBASE_FOREACH_MUTABLE (FCurve *, fcu, &srcAdt->drivers) {
640  if (animpath_matches_basepath(fcu->rna_path, src_basepath)) {
641  animpath_update_basepath(fcu, src_basepath, dst_basepath);
642  BLI_remlink(&srcAdt->drivers, fcu);
643  BLI_addtail(&dstAdt->drivers, fcu);
644 
645  /* TODO: add depsgraph flushing calls? */
646  }
647  }
648 }
649 
650 /* Transfer the animation data from srcID to dstID where the srcID
651  * animation data is based off "basepath", creating new AnimData and
652  * associated data as necessary.
653  *
654  * basepaths is a list of AnimationBasePathChange.
655  */
656 void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBase *basepaths)
657 {
658  AnimData *srcAdt = NULL, *dstAdt = NULL;
659 
660  /* sanity checks */
661  if (ELEM(NULL, srcID, dstID)) {
662  if (G.debug & G_DEBUG) {
663  CLOG_ERROR(&LOG, "no source or destination ID to separate AnimData with");
664  }
665  return;
666  }
667 
668  /* get animdata from src, and create for destination (if needed) */
669  srcAdt = BKE_animdata_from_id(srcID);
670  dstAdt = BKE_animdata_add_id(dstID);
671 
672  if (ELEM(NULL, srcAdt, dstAdt)) {
673  if (G.debug & G_DEBUG) {
674  CLOG_ERROR(&LOG, "no AnimData for this pair of ID's");
675  }
676  return;
677  }
678 
679  /* active action */
680  if (srcAdt->action) {
681  /* Set up an action if necessary,
682  * and name it in a similar way so that it can be easily found again. */
683  if (dstAdt->action == NULL) {
684  dstAdt->action = BKE_action_add(bmain, srcAdt->action->id.name + 2);
685  BKE_animdata_action_ensure_idroot(dstID, dstAdt->action);
686  }
687  else if (dstAdt->action == srcAdt->action) {
688  CLOG_WARN(&LOG,
689  "Argh! Source and Destination share animation! "
690  "('%s' and '%s' both use '%s') Making new empty action",
691  srcID->name,
692  dstID->name,
693  srcAdt->action->id.name);
694 
695  /* TODO: review this... */
696  id_us_min(&dstAdt->action->id);
697  dstAdt->action = BKE_action_add(bmain, dstAdt->action->id.name + 2);
698  BKE_animdata_action_ensure_idroot(dstID, dstAdt->action);
699  }
700 
701  /* loop over base paths, trying to fix for each one... */
702  LISTBASE_FOREACH (const AnimationBasePathChange *, basepath_change, basepaths) {
704  dstAdt->action,
705  basepath_change->src_basepath,
706  basepath_change->dst_basepath);
707  }
708  }
709 
710  /* drivers */
711  if (srcAdt->drivers.first) {
712  LISTBASE_FOREACH (const AnimationBasePathChange *, basepath_change, basepaths) {
714  srcAdt, dstAdt, basepath_change->src_basepath, basepath_change->dst_basepath);
715  }
716  }
717  /* Tag source action because list of fcurves changed. */
719 }
720 
733  PointerRNA *ptr,
734  PropertyRNA *prop,
735  char *base_path)
736 {
737  ID *id = ptr->owner_id;
739 
740  /* get standard path which may be extended */
741  char *basepath = base_path ? base_path : RNA_path_from_ID_to_property(ptr, prop);
742  char *path = basepath; /* in case no remapping is needed */
743 
744  /* Remapping will only be performed in the Properties Editor, as only this
745  * restricts the subspace of options to the 'active' data (a manageable state)
746  */
747  /* TODO: watch out for pinned context? */
748  if ((area) && (area->spacetype == SPACE_PROPERTIES)) {
750 
751  if (ob && id) {
752  /* TODO: after material textures were removed, this function serves
753  * no purpose anymore, but could be used again so was not removed. */
754 
755  /* fix RNA pointer, as we've now changed the ID root by changing the paths */
756  if (basepath != path) {
757  /* rebase provided pointer so that it starts from object... */
758  RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
759  }
760  }
761  }
762 
763  /* the path should now have been corrected for use */
764  return path;
765 }
766 
767 /* Path Validation -------------------------------------------- */
768 
769 /* Check if a given RNA Path is valid, by tracing it from the given ID,
770  * and seeing if we can resolve it. */
771 static bool check_rna_path_is_valid(ID *owner_id, const char *path)
772 {
773  PointerRNA id_ptr, ptr;
774  PropertyRNA *prop = NULL;
775 
776  /* make initial RNA pointer to start resolving from */
777  RNA_id_pointer_create(owner_id, &id_ptr);
778 
779  /* try to resolve */
780  return RNA_path_resolve_property(&id_ptr, path, &ptr, &prop);
781 }
782 
783 /* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate
784  * NOTE: we assume that oldName and newName have [" "] padding around them
785  */
786 static char *rna_path_rename_fix(ID *owner_id,
787  const char *prefix,
788  const char *oldName,
789  const char *newName,
790  char *oldpath,
791  bool verify_paths)
792 {
793  char *prefixPtr = strstr(oldpath, prefix);
794  char *oldNamePtr = strstr(oldpath, oldName);
795  int prefixLen = strlen(prefix);
796  int oldNameLen = strlen(oldName);
797 
798  /* only start fixing the path if the prefix and oldName feature in the path,
799  * and prefix occurs immediately before oldName
800  */
801  if ((prefixPtr && oldNamePtr) && (prefixPtr + prefixLen == oldNamePtr)) {
802  /* if we haven't aren't able to resolve the path now, try again after fixing it */
803  if (!verify_paths || check_rna_path_is_valid(owner_id, oldpath) == 0) {
804  DynStr *ds = BLI_dynstr_new();
805  const char *postfixPtr = oldNamePtr + oldNameLen;
806  char *newPath = NULL;
807 
808  /* add the part of the string that goes up to the start of the prefix */
809  if (prefixPtr > oldpath) {
810  BLI_dynstr_nappend(ds, oldpath, prefixPtr - oldpath);
811  }
812 
813  /* add the prefix */
814  BLI_dynstr_append(ds, prefix);
815 
816  /* add the new name (complete with brackets) */
817  BLI_dynstr_append(ds, newName);
818 
819  /* add the postfix */
820  BLI_dynstr_append(ds, postfixPtr);
821 
822  /* create new path, and cleanup old data */
823  newPath = BLI_dynstr_get_cstring(ds);
824  BLI_dynstr_free(ds);
825 
826  /* check if the new path will solve our problems */
827  /* TODO: will need to check whether this step really helps in practice */
828  if (!verify_paths || check_rna_path_is_valid(owner_id, newPath)) {
829  /* free the old path, and return the new one, since we've solved the issues */
830  MEM_freeN(oldpath);
831  return newPath;
832  }
833 
834  /* still couldn't resolve the path... so, might as well just leave it alone */
835  MEM_freeN(newPath);
836  }
837  }
838 
839  /* the old path doesn't need to be changed */
840  return oldpath;
841 }
842 
843 /* Check RNA-Paths for a list of F-Curves */
844 static bool fcurves_path_rename_fix(ID *owner_id,
845  const char *prefix,
846  const char *oldName,
847  const char *newName,
848  const char *oldKey,
849  const char *newKey,
850  ListBase *curves,
851  bool verify_paths)
852 {
853  FCurve *fcu;
854  bool is_changed = false;
855  /* We need to check every curve. */
856  for (fcu = curves->first; fcu; fcu = fcu->next) {
857  if (fcu->rna_path == NULL) {
858  continue;
859  }
860  const char *old_path = fcu->rna_path;
861  /* Firstly, handle the F-Curve's own path. */
863  owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
864  /* if path changed and the F-Curve is grouped, check if its group also needs renaming
865  * (i.e. F-Curve is first of a bone's F-Curves;
866  * hence renaming this should also trigger rename) */
867  if (fcu->rna_path != old_path) {
868  bActionGroup *agrp = fcu->grp;
869  is_changed = true;
870  if ((agrp != NULL) && STREQ(oldName, agrp->name)) {
871  BLI_strncpy(agrp->name, newName, sizeof(agrp->name));
872  }
873  }
874  }
875  return is_changed;
876 }
877 
878 /* Check RNA-Paths for a list of Drivers */
879 static bool drivers_path_rename_fix(ID *owner_id,
880  ID *ref_id,
881  const char *prefix,
882  const char *oldName,
883  const char *newName,
884  const char *oldKey,
885  const char *newKey,
886  ListBase *curves,
887  bool verify_paths)
888 {
889  bool is_changed = false;
890  FCurve *fcu;
891  /* We need to check every curve - drivers are F-Curves too. */
892  for (fcu = curves->first; fcu; fcu = fcu->next) {
893  /* firstly, handle the F-Curve's own path */
894  if (fcu->rna_path != NULL) {
895  const char *old_rna_path = fcu->rna_path;
897  owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
898  is_changed |= (fcu->rna_path != old_rna_path);
899  }
900  if (fcu->driver == NULL) {
901  continue;
902  }
903  ChannelDriver *driver = fcu->driver;
904  DriverVar *dvar;
905  /* driver variables */
906  for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
907  /* only change the used targets, since the others will need fixing manually anyway */
909  /* rename RNA path */
910  if (dtar->rna_path && dtar->id) {
911  const char *old_rna_path = dtar->rna_path;
912  dtar->rna_path = rna_path_rename_fix(
913  dtar->id, prefix, oldKey, newKey, dtar->rna_path, verify_paths);
914  is_changed |= (dtar->rna_path != old_rna_path);
915  }
916  /* also fix the bone-name (if applicable) */
917  if (strstr(prefix, "bones")) {
918  if (((dtar->id) && (GS(dtar->id->name) == ID_OB) &&
919  (!ref_id || ((Object *)(dtar->id))->data == ref_id)) &&
920  (dtar->pchan_name[0]) && STREQ(oldName, dtar->pchan_name)) {
921  is_changed = true;
922  BLI_strncpy(dtar->pchan_name, newName, sizeof(dtar->pchan_name));
923  }
924  }
925  }
927  }
928  }
929  return is_changed;
930 }
931 
932 /* Fix all RNA-Paths for Actions linked to NLA Strips */
933 static bool nlastrips_path_rename_fix(ID *owner_id,
934  const char *prefix,
935  const char *oldName,
936  const char *newName,
937  const char *oldKey,
938  const char *newKey,
939  ListBase *strips,
940  bool verify_paths)
941 {
942  NlaStrip *strip;
943  bool is_changed = false;
944  /* Recursively check strips, fixing only actions. */
945  for (strip = strips->first; strip; strip = strip->next) {
946  /* fix strip's action */
947  if (strip->act != NULL) {
948  is_changed |= fcurves_path_rename_fix(
949  owner_id, prefix, oldName, newName, oldKey, newKey, &strip->act->curves, verify_paths);
950  }
951  /* Ignore own F-Curves, since those are local. */
952  /* Check sub-strips (if metas) */
953  is_changed |= nlastrips_path_rename_fix(
954  owner_id, prefix, oldName, newName, oldKey, newKey, &strip->strips, verify_paths);
955  }
956  return is_changed;
957 }
958 
959 /* Rename Sub-ID Entities in RNA Paths ----------------------- */
960 
961 /* Fix up the given RNA-Path
962  *
963  * This is just an external wrapper for the RNA-Path fixing function,
964  * with input validity checks on top of the basic method.
965  *
966  * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
967  * i.e. pose.bones["Bone"]
968  */
970  char *old_path,
971  const char *prefix,
972  const char *oldName,
973  const char *newName,
974  int oldSubscript,
975  int newSubscript,
976  bool verify_paths)
977 {
978  char *oldN, *newN;
979  char *result;
980 
981  /* if no action, no need to proceed */
982  if (ELEM(NULL, owner_id, old_path)) {
983  if (G.debug & G_DEBUG) {
984  CLOG_WARN(&LOG, "early abort");
985  }
986  return old_path;
987  }
988 
989  /* Name sanitation logic - copied from BKE_animdata_fix_paths_rename() */
990  if ((oldName != NULL) && (newName != NULL)) {
991  /* pad the names with [" "] so that only exact matches are made */
992  const size_t name_old_len = strlen(oldName);
993  const size_t name_new_len = strlen(newName);
994  char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
995  char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
996 
997  BLI_str_escape(name_old_esc, oldName, (name_old_len * 2) + 1);
998  BLI_str_escape(name_new_esc, newName, (name_new_len * 2) + 1);
999  oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
1000  newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
1001  }
1002  else {
1003  oldN = BLI_sprintfN("[%d]", oldSubscript);
1004  newN = BLI_sprintfN("[%d]", newSubscript);
1005  }
1006 
1007  /* fix given path */
1008  if (G.debug & G_DEBUG) {
1009  printf("%s | %s | oldpath = %p ", oldN, newN, old_path);
1010  }
1011  result = rna_path_rename_fix(owner_id, prefix, oldN, newN, old_path, verify_paths);
1012  if (G.debug & G_DEBUG) {
1013  printf("path rename result = %p\n", result);
1014  }
1015 
1016  /* free the temp names */
1017  MEM_freeN(oldN);
1018  MEM_freeN(newN);
1019 
1020  /* return the resulting path - may be the same path again if nothing changed */
1021  return result;
1022 }
1023 
1024 /* Fix all RNA_Paths in the given Action, relative to the given ID block
1025  *
1026  * This is just an external wrapper for the F-Curve fixing function,
1027  * with input validity checks on top of the basic method.
1028  *
1029  * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
1030  * i.e. pose.bones["Bone"]
1031  */
1033  bAction *act,
1034  const char *prefix,
1035  const char *oldName,
1036  const char *newName,
1037  int oldSubscript,
1038  int newSubscript,
1039  bool verify_paths)
1040 {
1041  char *oldN, *newN;
1042 
1043  /* if no action, no need to proceed */
1044  if (ELEM(NULL, owner_id, act)) {
1045  return;
1046  }
1047 
1048  /* Name sanitation logic - copied from BKE_animdata_fix_paths_rename() */
1049  if ((oldName != NULL) && (newName != NULL)) {
1050  /* pad the names with [" "] so that only exact matches are made */
1051  const size_t name_old_len = strlen(oldName);
1052  const size_t name_new_len = strlen(newName);
1053  char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
1054  char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
1055 
1056  BLI_str_escape(name_old_esc, oldName, (name_old_len * 2) + 1);
1057  BLI_str_escape(name_new_esc, newName, (name_new_len * 2) + 1);
1058  oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
1059  newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
1060  }
1061  else {
1062  oldN = BLI_sprintfN("[%d]", oldSubscript);
1063  newN = BLI_sprintfN("[%d]", newSubscript);
1064  }
1065 
1066  /* fix paths in action */
1068  owner_id, prefix, oldName, newName, oldN, newN, &act->curves, verify_paths);
1069 
1070  /* free the temp names */
1071  MEM_freeN(oldN);
1072  MEM_freeN(newN);
1073 }
1074 
1075 /* Fix all RNA-Paths in the AnimData block used by the given ID block
1076  * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
1077  * i.e. pose.bones["Bone"]
1078  */
1080  AnimData *adt,
1081  ID *ref_id,
1082  const char *prefix,
1083  const char *oldName,
1084  const char *newName,
1085  int oldSubscript,
1086  int newSubscript,
1087  bool verify_paths)
1088 {
1089  NlaTrack *nlt;
1090  char *oldN, *newN;
1091  /* If no AnimData, no need to proceed. */
1092  if (ELEM(NULL, owner_id, adt)) {
1093  return;
1094  }
1095  bool is_self_changed = false;
1096  /* Name sanitation logic - shared with BKE_action_fix_paths_rename(). */
1097  if ((oldName != NULL) && (newName != NULL)) {
1098  /* Pad the names with [" "] so that only exact matches are made. */
1099  const size_t name_old_len = strlen(oldName);
1100  const size_t name_new_len = strlen(newName);
1101  char *name_old_esc = BLI_array_alloca(name_old_esc, (name_old_len * 2) + 1);
1102  char *name_new_esc = BLI_array_alloca(name_new_esc, (name_new_len * 2) + 1);
1103 
1104  BLI_str_escape(name_old_esc, oldName, (name_old_len * 2) + 1);
1105  BLI_str_escape(name_new_esc, newName, (name_new_len * 2) + 1);
1106  oldN = BLI_sprintfN("[\"%s\"]", name_old_esc);
1107  newN = BLI_sprintfN("[\"%s\"]", name_new_esc);
1108  }
1109  else {
1110  oldN = BLI_sprintfN("[%d]", oldSubscript);
1111  newN = BLI_sprintfN("[%d]", newSubscript);
1112  }
1113  /* Active action and temp action. */
1114  if (adt->action != NULL) {
1116  owner_id, prefix, oldName, newName, oldN, newN, &adt->action->curves, verify_paths)) {
1118  }
1119  }
1120  if (adt->tmpact) {
1122  owner_id, prefix, oldName, newName, oldN, newN, &adt->tmpact->curves, verify_paths)) {
1124  }
1125  }
1126  /* Drivers - Drivers are really F-Curves */
1127  is_self_changed |= drivers_path_rename_fix(
1128  owner_id, ref_id, prefix, oldName, newName, oldN, newN, &adt->drivers, verify_paths);
1129  /* NLA Data - Animation Data for Strips */
1130  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
1131  is_self_changed |= nlastrips_path_rename_fix(
1132  owner_id, prefix, oldName, newName, oldN, newN, &nlt->strips, verify_paths);
1133  }
1134  /* Tag owner ID if it */
1135  if (is_self_changed) {
1137  }
1138  /* free the temp names */
1139  MEM_freeN(oldN);
1140  MEM_freeN(newN);
1141 }
1142 
1143 /* Remove FCurves with Prefix -------------------------------------- */
1144 
1145 /* Check RNA-Paths for a list of F-Curves */
1146 static bool fcurves_path_remove_fix(const char *prefix, ListBase *curves)
1147 {
1148  FCurve *fcu, *fcn;
1149  bool any_removed = false;
1150  if (!prefix) {
1151  return any_removed;
1152  }
1153 
1154  /* we need to check every curve... */
1155  for (fcu = curves->first; fcu; fcu = fcn) {
1156  fcn = fcu->next;
1157 
1158  if (fcu->rna_path) {
1159  if (STRPREFIX(fcu->rna_path, prefix)) {
1160  BLI_remlink(curves, fcu);
1161  BKE_fcurve_free(fcu);
1162  any_removed = true;
1163  }
1164  }
1165  }
1166  return any_removed;
1167 }
1168 
1169 /* Check RNA-Paths for a list of F-Curves */
1170 static bool nlastrips_path_remove_fix(const char *prefix, ListBase *strips)
1171 {
1172  NlaStrip *strip;
1173  bool any_removed = false;
1174 
1175  /* recursively check strips, fixing only actions... */
1176  for (strip = strips->first; strip; strip = strip->next) {
1177  /* fix strip's action */
1178  if (strip->act) {
1179  any_removed |= fcurves_path_remove_fix(prefix, &strip->act->curves);
1180  }
1181 
1182  /* check sub-strips (if metas) */
1183  any_removed |= nlastrips_path_remove_fix(prefix, &strip->strips);
1184  }
1185  return any_removed;
1186 }
1187 
1188 bool BKE_animdata_fix_paths_remove(ID *id, const char *prefix)
1189 {
1190  /* Only some ID-blocks have this info for now, so we cast the
1191  * types that do to be of type IdAdtTemplate
1192  */
1193  if (!id_can_have_animdata(id)) {
1194  return false;
1195  }
1196  bool any_removed = false;
1197  IdAdtTemplate *iat = (IdAdtTemplate *)id;
1198  AnimData *adt = iat->adt;
1199  /* check if there's any AnimData to start with */
1200  if (adt) {
1201  /* free fcurves */
1202  if (adt->action != NULL) {
1203  any_removed |= fcurves_path_remove_fix(prefix, &adt->action->curves);
1204  }
1205  if (adt->tmpact != NULL) {
1206  any_removed |= fcurves_path_remove_fix(prefix, &adt->tmpact->curves);
1207  }
1208  /* free drivers - stored as a list of F-Curves */
1209  any_removed |= fcurves_path_remove_fix(prefix, &adt->drivers);
1210  /* NLA Data - Animation Data for Strips */
1211  LISTBASE_FOREACH (NlaTrack *, nlt, &adt->nla_tracks) {
1212  any_removed |= nlastrips_path_remove_fix(prefix, &nlt->strips);
1213  }
1214  }
1215  return any_removed;
1216 }
1217 
1218 /* Apply Op to All FCurves in Database --------------------------- */
1219 
1220 /* "User-Data" wrapper used by BKE_fcurves_main_cb() */
1221 typedef struct AllFCurvesCbWrapper {
1222  ID_FCurve_Edit_Callback func; /* Operation to apply on F-Curve */
1223  void *user_data; /* Custom data for that operation */
1225 
1226 /* Helper for adt_apply_all_fcurves_cb() - Apply wrapped operator to list of F-Curves */
1227 static void fcurves_apply_cb(ID *id,
1228  ListBase *fcurves,
1230  void *user_data)
1231 {
1232  FCurve *fcu;
1233 
1234  for (fcu = fcurves->first; fcu; fcu = fcu->next) {
1235  func(id, fcu, user_data);
1236  }
1237 }
1238 
1239 /* Helper for adt_apply_all_fcurves_cb() - Recursively go through each NLA strip */
1241 {
1242  NlaStrip *strip;
1243 
1244  for (strip = strips->first; strip; strip = strip->next) {
1245  /* fix strip's action */
1246  if (strip->act) {
1247  fcurves_apply_cb(id, &strip->act->curves, wrapper->func, wrapper->user_data);
1248  }
1249 
1250  /* check sub-strips (if metas) */
1251  nlastrips_apply_all_curves_cb(id, &strip->strips, wrapper);
1252  }
1253 }
1254 
1255 /* Helper for BKE_fcurves_main_cb() - Dispatch wrapped operator to all F-Curves */
1256 static void adt_apply_all_fcurves_cb(ID *id, AnimData *adt, void *wrapper_data)
1257 {
1258  AllFCurvesCbWrapper *wrapper = wrapper_data;
1259  NlaTrack *nlt;
1260 
1261  if (adt->action) {
1262  fcurves_apply_cb(id, &adt->action->curves, wrapper->func, wrapper->user_data);
1263  }
1264 
1265  if (adt->tmpact) {
1266  fcurves_apply_cb(id, &adt->tmpact->curves, wrapper->func, wrapper->user_data);
1267  }
1268 
1269  /* free drivers - stored as a list of F-Curves */
1270  fcurves_apply_cb(id, &adt->drivers, wrapper->func, wrapper->user_data);
1271 
1272  /* NLA Data - Animation Data for Strips */
1273  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
1274  nlastrips_apply_all_curves_cb(id, &nlt->strips, wrapper);
1275  }
1276 }
1277 
1279 {
1280  AnimData *adt = BKE_animdata_from_id(id);
1281  if (adt != NULL) {
1282  AllFCurvesCbWrapper wrapper = {func, user_data};
1283  adt_apply_all_fcurves_cb(id, adt, &wrapper);
1284  }
1285 }
1286 
1287 /* apply the given callback function on all F-Curves attached to data in main database */
1289 {
1290  /* Wrap F-Curve operation stuff to pass to the general AnimData-level func */
1291  AllFCurvesCbWrapper wrapper = {func, user_data};
1292 
1293  /* Use the AnimData-based function so that we don't have to reimplement all that stuff */
1295 }
1296 
1297 /* Whole Database Ops -------------------------------------------- */
1298 
1299 /* apply the given callback function on all data in main database */
1301 {
1302  ID *id;
1303 
1304  /* standard data version */
1305 #define ANIMDATA_IDS_CB(first) \
1306  for (id = first; id; id = id->next) { \
1307  AnimData *adt = BKE_animdata_from_id(id); \
1308  if (adt) { \
1309  func(id, adt, user_data); \
1310  } \
1311  } \
1312  (void)0
1313 
1314  /* "embedded" nodetree cases (i.e. scene/material/texture->nodetree) */
1315 #define ANIMDATA_NODETREE_IDS_CB(first, NtId_Type) \
1316  for (id = first; id; id = id->next) { \
1317  AnimData *adt = BKE_animdata_from_id(id); \
1318  NtId_Type *ntp = (NtId_Type *)id; \
1319  if (ntp->nodetree) { \
1320  AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
1321  if (adt2) { \
1322  func(id, adt2, user_data); \
1323  } \
1324  } \
1325  if (adt) { \
1326  func(id, adt, user_data); \
1327  } \
1328  } \
1329  (void)0
1330 
1331  /* nodes */
1333 
1334  /* textures */
1336 
1337  /* lights */
1339 
1340  /* materials */
1342 
1343  /* cameras */
1344  ANIMDATA_IDS_CB(bmain->cameras.first);
1345 
1346  /* shapekeys */
1348 
1349  /* metaballs */
1351 
1352  /* curves */
1353  ANIMDATA_IDS_CB(bmain->curves.first);
1354 
1355  /* armatures */
1357 
1358  /* lattices */
1359  ANIMDATA_IDS_CB(bmain->lattices.first);
1360 
1361  /* meshes */
1362  ANIMDATA_IDS_CB(bmain->meshes.first);
1363 
1364  /* particles */
1366 
1367  /* speakers */
1368  ANIMDATA_IDS_CB(bmain->speakers.first);
1369 
1370  /* movie clips */
1372 
1373  /* objects */
1374  ANIMDATA_IDS_CB(bmain->objects.first);
1375 
1376  /* masks */
1377  ANIMDATA_IDS_CB(bmain->masks.first);
1378 
1379  /* worlds */
1381 
1382  /* scenes */
1384 
1385  /* line styles */
1387 
1388  /* grease pencil */
1389  ANIMDATA_IDS_CB(bmain->gpencils.first);
1390 
1391  /* palettes */
1392  ANIMDATA_IDS_CB(bmain->palettes.first);
1393 
1394  /* cache files */
1396 
1397  /* hairs */
1398  ANIMDATA_IDS_CB(bmain->hairs.first);
1399 
1400  /* pointclouds */
1402 
1403  /* volumes */
1404  ANIMDATA_IDS_CB(bmain->volumes.first);
1405 
1406  /* simulations */
1408 }
1409 
1410 /* Fix all RNA-Paths throughout the database (directly access the Global.main version)
1411  * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
1412  * i.e. pose.bones["Bone"]
1413  */
1415  const char *prefix,
1416  const char *oldName,
1417  const char *newName)
1418 {
1419  Main *bmain = G.main; /* XXX UGLY! */
1420  BKE_animdata_fix_paths_rename_all_ex(bmain, ref_id, prefix, oldName, newName, 0, 0, 1);
1421 }
1422 
1423 /* Fix all RNA-Paths throughout the database
1424  * NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
1425  * i.e. pose.bones["Bone"]
1426  */
1427 /* TODO: use BKE_animdata_main_cb for looping over all data */
1429  ID *ref_id,
1430  const char *prefix,
1431  const char *oldName,
1432  const char *newName,
1433  const int oldSubscript,
1434  const int newSubscript,
1435  const bool verify_paths)
1436 {
1437 
1438  ID *id;
1439 
1440  /* macro for less typing
1441  * - whether animdata exists is checked for by the main renaming callback, though taking
1442  * this outside of the function may make things slightly faster?
1443  */
1444 #define RENAMEFIX_ANIM_IDS(first) \
1445  for (id = first; id; id = id->next) { \
1446  AnimData *adt = BKE_animdata_from_id(id); \
1447  BKE_animdata_fix_paths_rename( \
1448  id, adt, ref_id, prefix, oldName, newName, oldSubscript, newSubscript, verify_paths); \
1449  } \
1450  (void)0
1451 
1452  /* another version of this macro for nodetrees */
1453 #define RENAMEFIX_ANIM_NODETREE_IDS(first, NtId_Type) \
1454  for (id = first; id; id = id->next) { \
1455  AnimData *adt = BKE_animdata_from_id(id); \
1456  NtId_Type *ntp = (NtId_Type *)id; \
1457  if (ntp->nodetree) { \
1458  AnimData *adt2 = BKE_animdata_from_id((ID *)ntp->nodetree); \
1459  BKE_animdata_fix_paths_rename((ID *)ntp->nodetree, \
1460  adt2, \
1461  ref_id, \
1462  prefix, \
1463  oldName, \
1464  newName, \
1465  oldSubscript, \
1466  newSubscript, \
1467  verify_paths); \
1468  } \
1469  BKE_animdata_fix_paths_rename( \
1470  id, adt, ref_id, prefix, oldName, newName, oldSubscript, newSubscript, verify_paths); \
1471  } \
1472  (void)0
1473 
1474  /* nodes */
1476 
1477  /* textures */
1479 
1480  /* lights */
1482 
1483  /* materials */
1485 
1486  /* cameras */
1488 
1489  /* shapekeys */
1491 
1492  /* metaballs */
1494 
1495  /* curves */
1497 
1498  /* armatures */
1500 
1501  /* lattices */
1503 
1504  /* meshes */
1506 
1507  /* particles */
1509 
1510  /* speakers */
1512 
1513  /* movie clips */
1515 
1516  /* objects */
1518 
1519  /* masks */
1520  RENAMEFIX_ANIM_IDS(bmain->masks.first);
1521 
1522  /* worlds */
1524 
1525  /* linestyles */
1527 
1528  /* grease pencil */
1530 
1531  /* cache files */
1533 
1534  /* hairs */
1535  RENAMEFIX_ANIM_IDS(bmain->hairs.first);
1536 
1537  /* pointclouds */
1539 
1540  /* volumes */
1542 
1543  /* simulations */
1545 
1546  /* scenes */
1548 }
1549 
1550 /* .blend file API -------------------------------------------- */
1551 
1553 {
1554  /* firstly, just write the AnimData block */
1555  BLO_write_struct(writer, AnimData, adt);
1556 
1557  /* write drivers */
1558  BKE_fcurve_blend_write(writer, &adt->drivers);
1559 
1560  /* write overrides */
1561  /* FIXME: are these needed? */
1562  LISTBASE_FOREACH (AnimOverride *, aor, &adt->overrides) {
1563  /* overrides consist of base data + rna_path */
1564  BLO_write_struct(writer, AnimOverride, aor);
1565  BLO_write_string(writer, aor->rna_path);
1566  }
1567 
1568  /* TODO write the remaps (if they are needed) */
1569 
1570  /* write NLA data */
1571  BKE_nla_blend_write(writer, &adt->nla_tracks);
1572 }
1573 
1575 {
1576  /* NOTE: must have called BLO_read_data_address already before doing this... */
1577  if (adt == NULL) {
1578  return;
1579  }
1580 
1581  /* link drivers */
1582  BLO_read_list(reader, &adt->drivers);
1583  BKE_fcurve_blend_read_data(reader, &adt->drivers);
1584  adt->driver_array = NULL;
1585 
1586  /* link overrides */
1587  /* TODO... */
1588 
1589  /* link NLA-data */
1590  BLO_read_list(reader, &adt->nla_tracks);
1591  BKE_nla_blend_read_data(reader, &adt->nla_tracks);
1592 
1593  /* relink active track/strip - even though strictly speaking this should only be used
1594  * if we're in 'tweaking mode', we need to be able to have this loaded back for
1595  * undo, but also since users may not exit tweakmode before saving (T24535)
1596  */
1597  /* TODO: it's not really nice that anyone should be able to save the file in this
1598  * state, but it's going to be too hard to enforce this single case... */
1599  BLO_read_data_address(reader, &adt->act_track);
1600  BLO_read_data_address(reader, &adt->actstrip);
1601 }
1602 
1604 {
1605  if (adt == NULL) {
1606  return;
1607  }
1608 
1609  /* link action data */
1610  BLO_read_id_address(reader, id->lib, &adt->action);
1611  BLO_read_id_address(reader, id->lib, &adt->tmpact);
1612 
1613  /* link drivers */
1614  BKE_fcurve_blend_read_lib(reader, id, &adt->drivers);
1615 
1616  /* overrides don't have lib-link for now, so no need to do anything */
1617 
1618  /* link NLA-data */
1619  BKE_nla_blend_read_lib(reader, id, &adt->nla_tracks);
1620 }
1621 
1623 {
1624  /* own action */
1625  BLO_expand(expander, adt->action);
1626  BLO_expand(expander, adt->tmpact);
1627 
1628  /* drivers - assume that these F-Curves have driver data to be in this list... */
1629  BKE_fcurve_blend_read_expand(expander, &adt->drivers);
1630 
1631  /* NLA data - referenced actions. */
1632  BKE_nla_blend_read_expand(expander, &adt->nla_tracks);
1633 }
Blender kernel action and pose functionality.
struct bActionGroup * action_groups_add_new(struct bAction *act, const char name[])
Definition: action.c:402
void action_groups_remove_channel(struct bAction *act, struct FCurve *fcu)
Definition: action.c:538
void action_groups_clear_tempflags(struct bAction *act)
Definition: action.c:591
struct bActionGroup * BKE_action_group_find_name(struct bAction *act, const char name[])
Definition: action.c:579
struct bAction * BKE_action_add(struct Main *bmain, const char name[])
Definition: action.c:320
void action_groups_add_channel(struct bAction *act, struct bActionGroup *agrp, struct FCurve *fcurve)
Definition: action.c:431
eAnimData_MergeCopy_Modes
Definition: BKE_anim_data.h:90
@ ADT_MERGECOPY_SRC_COPY
Definition: BKE_anim_data.h:95
@ ADT_MERGECOPY_SRC_REF
Definition: BKE_anim_data.h:98
void(* ID_AnimData_Edit_Callback)(struct ID *id, struct AnimData *adt, void *user_data)
Definition: BKE_animsys.h:194
void(* ID_FCurve_Edit_Callback)(struct ID *id, struct FCurve *fcu, void *user_data)
Definition: BKE_animsys.h:197
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:714
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
void BKE_fcurve_blend_write(struct BlendWriter *writer, struct ListBase *fcurves)
Definition: fcurve.c:2397
void BKE_fcurve_blend_read_data(struct BlendDataReader *reader, struct ListBase *fcurves)
Definition: fcurve.c:2436
void BKE_fcurve_free(struct FCurve *fcu)
Definition: fcurve.c:81
void BKE_fcurve_foreach_id(struct FCurve *fcu, struct LibraryForeachIDData *data)
Definition: fcurve.c:188
void BKE_fcurve_blend_read_lib(struct BlendLibReader *reader, struct ID *id, struct ListBase *fcurves)
Definition: fcurve.c:2491
void BKE_fcurve_blend_read_expand(struct BlendExpander *expander, struct ListBase *fcurves)
Definition: fcurve.c:2521
void BKE_fcurves_free(ListBase *list)
Definition: fcurve.c:103
void BKE_fcurves_copy(ListBase *dst, ListBase *src)
Definition: fcurve.c:165
#define DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
#define DRIVER_TARGETS_LOOPER_END
@ G_DEBUG
Definition: BKE_global.h:133
@ IDTYPE_FLAGS_NO_ANIMDATA
Definition: BKE_idtype.h:51
const struct IDTypeInfo * BKE_idtype_get_info_from_idcode(const short id_code)
Definition: idtype.c:131
struct ID * BKE_id_copy(struct Main *bmain, const struct ID *id)
void id_us_min(struct ID *id)
Definition: lib_id.c:297
@ LIB_ID_COPY_ACTIONS
Definition: BKE_lib_id.h:129
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:92
@ LIB_ID_CREATE_NO_MAIN
Definition: BKE_lib_id.h:88
struct ID * BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag)
void id_us_plus(struct ID *id)
Definition: lib_id.c:288
#define BKE_LIB_FOREACHID_PROCESS(_data, _id_super, _cb_flag)
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:87
void BKE_nla_strip_foreach_id(struct NlaStrip *strip, struct LibraryForeachIDData *data)
Definition: nla.c:441
void BKE_nla_blend_read_data(struct BlendDataReader *reader, struct ListBase *tracks)
Definition: nla.c:2284
void BKE_nla_tracks_copy(struct Main *bmain, ListBase *dst, ListBase *src, const int flag)
Definition: nla.c:257
void BKE_nla_tracks_free(ListBase *tracks, bool do_id_user)
Definition: nla.c:141
void BKE_nla_blend_write(struct BlendWriter *writer, struct ListBase *tracks)
Definition: nla.c:2272
void BKE_nla_blend_read_lib(struct BlendLibReader *reader, struct ID *id, struct ListBase *tracks)
Definition: nla.c:2295
void BKE_nla_blend_read_expand(struct BlendExpander *expander, struct ListBase *tracks)
Definition: nla.c:2308
struct bNodeTree * ntreeFromID(struct ID *id)
Definition: node.cc:3147
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:36
#define BLI_assert(a)
Definition: BLI_assert.h:58
A dynamically sized string ADT.
DynStr * BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_dynstr.c:71
void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len) ATTR_NONNULL()
Definition: BLI_dynstr.c:133
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL()
Definition: BLI_dynstr.c:358
char * BLI_dynstr_get_cstring(DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_dynstr.c:323
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL()
Definition: BLI_dynstr.c:107
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:281
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:188
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void void void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:133
size_t size_t char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
size_t size_t char size_t BLI_str_escape(char *__restrict dst, const char *__restrict src, const size_t dst_maxncpy) ATTR_NONNULL()
Definition: string.c:333
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
#define STRPREFIX(a, b)
#define ELEM(...)
#define STREQ(a, b)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5654
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
Definition: writefile.c:1401
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define BLO_expand(expander, id)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:204
#define CLOG_WARN(clg_ref,...)
Definition: CLG_log.h:203
void DEG_id_tag_update(struct ID *id, int flag)
ID and Library types, which are fundamental for sdna.
@ ID_RECALC_COPY_ON_WRITE
Definition: DNA_ID.h:654
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:445
#define ID_NEW_SET(_id, _idn)
Definition: DNA_ID.h:464
@ ID_OB
Definition: DNA_ID_enums.h:59
@ AGRP_TEMP
@ ADT_NLA_EDIT_ON
@ SPACE_PROPERTIES
eDupli_ID_Flags
@ USER_DUP_LINKED_ID
@ USER_DUP_ACT
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define C
Definition: RandGen.cpp:39
bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const int flag)
Definition: anim_data.c:375
static void animdata_copy_id_action(Main *bmain, ID *id, const bool set_newid, const bool do_linked_id)
Definition: anim_data.c:394
bool BKE_animdata_action_ensure_idroot(const ID *owner, bAction *action)
Definition: anim_data.c:209
void BKE_animdata_blend_read_lib(BlendLibReader *reader, ID *id, AnimData *adt)
Definition: anim_data.c:1603
bool BKE_animdata_fix_paths_remove(ID *id, const char *prefix)
Definition: anim_data.c:1188
void BKE_animdata_fix_paths_rename_all_ex(Main *bmain, ID *ref_id, const char *prefix, const char *oldName, const char *newName, const int oldSubscript, const int newSubscript, const bool verify_paths)
Definition: anim_data.c:1428
void BKE_animdata_merge_copy(Main *bmain, ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers)
Definition: anim_data.c:436
#define RENAMEFIX_ANIM_NODETREE_IDS(first, NtId_Type)
static bool drivers_path_rename_fix(ID *owner_id, ID *ref_id, const char *prefix, const char *oldName, const char *newName, const char *oldKey, const char *newKey, ListBase *curves, bool verify_paths)
Definition: anim_data.c:879
static bool check_rna_path_is_valid(ID *owner_id, const char *path)
Definition: anim_data.c:771
static bool fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, const char *oldKey, const char *newKey, ListBase *curves, bool verify_paths)
Definition: anim_data.c:844
static bool nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, const char *oldKey, const char *newKey, ListBase *strips, bool verify_paths)
Definition: anim_data.c:933
bool id_can_have_animdata(const ID *id)
Definition: anim_data.c:82
static bool fcurves_path_remove_fix(const char *prefix, ListBase *curves)
Definition: anim_data.c:1146
void BKE_action_fix_paths_rename(ID *owner_id, bAction *act, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
Definition: anim_data.c:1032
void BKE_animdata_foreach_id(AnimData *adt, LibraryForeachIDData *data)
Definition: anim_data.c:294
#define ANIMDATA_NODETREE_IDS_CB(first, NtId_Type)
bool id_type_can_have_animdata(const short id_type)
Definition: anim_data.c:73
char * BKE_animdata_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop, char *base_path)
Definition: anim_data.c:732
static void adt_apply_all_fcurves_cb(ID *id, AnimData *adt, void *wrapper_data)
Definition: anim_data.c:1256
static void fcurves_apply_cb(ID *id, ListBase *fcurves, ID_FCurve_Edit_Callback func, void *user_data)
Definition: anim_data.c:1227
void BKE_animdata_blend_write(BlendWriter *writer, struct AnimData *adt)
Definition: anim_data.c:1552
void BKE_animdata_main_cb(Main *bmain, ID_AnimData_Edit_Callback func, void *user_data)
Definition: anim_data.c:1300
bool BKE_animdata_action_editable(const AnimData *adt)
Definition: anim_data.c:201
struct AllFCurvesCbWrapper AllFCurvesCbWrapper
#define RENAMEFIX_ANIM_IDS(first)
bool BKE_animdata_set_action(ReportList *reports, ID *id, bAction *act)
Definition: anim_data.c:150
void BKE_fcurves_id_cb(ID *id, ID_FCurve_Edit_Callback func, void *user_data)
Definition: anim_data.c:1278
bool BKE_animdata_id_is_animated(const struct ID *id)
Definition: anim_data.c:271
void BKE_animdata_free(ID *id, const bool do_id_user)
Definition: anim_data.c:230
static bool animpath_matches_basepath(const char path[], const char basepath[])
Definition: anim_data.c:518
static bool nlastrips_path_remove_fix(const char *prefix, ListBase *strips)
Definition: anim_data.c:1170
AnimData * BKE_animdata_copy(Main *bmain, AnimData *adt, const int flag)
Definition: anim_data.c:318
void BKE_animdata_duplicate_id_action(struct Main *bmain, struct ID *id, const eDupli_ID_Flags duplicate_flags)
Definition: anim_data.c:426
void BKE_animdata_blend_read_data(BlendDataReader *reader, AnimData *adt)
Definition: anim_data.c:1574
AnimData * BKE_animdata_add_id(ID *id)
Definition: anim_data.c:113
AnimData * BKE_animdata_from_id(ID *id)
Definition: anim_data.c:96
static void animpath_update_basepath(FCurve *fcu, const char *old_basepath, const char *new_basepath)
Definition: anim_data.c:524
void BKE_animdata_blend_read_expand(struct BlendExpander *expander, AnimData *adt)
Definition: anim_data.c:1622
static CLG_LogRef LOG
Definition: anim_data.c:65
#define ANIMDATA_IDS_CB(first)
void BKE_animdata_transfer_by_basepath(Main *bmain, ID *srcID, ID *dstID, ListBase *basepaths)
Definition: anim_data.c:656
void BKE_animdata_fix_paths_rename_all(ID *ref_id, const char *prefix, const char *oldName, const char *newName)
Definition: anim_data.c:1414
void BKE_fcurves_main_cb(Main *bmain, ID_FCurve_Edit_Callback func, void *user_data)
Definition: anim_data.c:1288
void BKE_animdata_copy_id_action(Main *bmain, ID *id)
Definition: anim_data.c:420
static char * rna_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName, char *oldpath, bool verify_paths)
Definition: anim_data.c:786
static void animdata_move_drivers_by_basepath(AnimData *srcAdt, AnimData *dstAdt, const char *src_basepath, const char *dst_basepath)
Definition: anim_data.c:634
void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
Definition: anim_data.c:1079
static void nlastrips_apply_all_curves_cb(ID *id, ListBase *strips, AllFCurvesCbWrapper *wrapper)
Definition: anim_data.c:1240
char * BKE_animsys_fix_rna_path_rename(ID *owner_id, char *old_path, const char *prefix, const char *oldName, const char *newName, int oldSubscript, int newSubscript, bool verify_paths)
Definition: anim_data.c:969
static void action_move_fcurves_by_basepath(bAction *srcAct, bAction *dstAct, const char *src_basepath, const char *dst_basepath)
Definition: anim_data.c:544
void * user_data
bNodeTree * ntree
#define GS(x)
Definition: iris.c:241
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:42
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static void area(int d1, int d2, int e1, int e2, float weights[2])
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
void RNA_id_pointer_create(ID *id, PointerRNA *r_ptr)
Definition: rna_access.c:122
char * RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6027
bool RNA_path_resolve_property(PointerRNA *ptr, const char *path, PointerRNA *r_ptr, PropertyRNA **r_prop)
Definition: rna_access.c:5434
ID_FCurve_Edit_Callback func
Definition: anim_data.c:1222
bAction * action
NlaStrip * actstrip
ListBase overrides
float act_influence
FCurve ** driver_array
NlaTrack * act_track
bAction * tmpact
ListBase drivers
ListBase nla_tracks
ListBase variables
struct DriverVar * next
struct FCurve * next
bActionGroup * grp
char * rna_path
ChannelDriver * driver
uint32_t flags
Definition: BKE_idtype.h:145
Definition: DNA_ID.h:273
struct Library * lib
Definition: DNA_ID.h:277
char name[66]
Definition: DNA_ID.h:283
AnimData * adt
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
ListBase volumes
Definition: BKE_main.h:184
ListBase masks
Definition: BKE_main.h:178
ListBase scenes
Definition: BKE_main.h:146
ListBase textures
Definition: BKE_main.h:153
ListBase meshes
Definition: BKE_main.h:149
ListBase movieclips
Definition: BKE_main.h:177
ListBase lights
Definition: BKE_main.h:156
ListBase nodetrees
Definition: BKE_main.h:170
ListBase particles
Definition: BKE_main.h:172
ListBase materials
Definition: BKE_main.h:152
ListBase linestyles
Definition: BKE_main.h:179
ListBase pointclouds
Definition: BKE_main.h:183
ListBase lattices
Definition: BKE_main.h:155
ListBase shapekeys
Definition: BKE_main.h:159
ListBase cameras
Definition: BKE_main.h:157
char name[1024]
Definition: BKE_main.h:118
ListBase armatures
Definition: BKE_main.h:168
ListBase speakers
Definition: BKE_main.h:164
ListBase curves
Definition: BKE_main.h:150
ListBase worlds
Definition: BKE_main.h:160
ListBase palettes
Definition: BKE_main.h:173
ListBase hairs
Definition: BKE_main.h:182
ListBase metaballs
Definition: BKE_main.h:151
ListBase simulations
Definition: BKE_main.h:185
ListBase gpencils
Definition: BKE_main.h:176
ListBase objects
Definition: BKE_main.h:148
ListBase cachefiles
Definition: BKE_main.h:180
struct NlaStrip * next
ListBase strips
bAction * act
ListBase strips
struct NlaTrack * next
struct StructRNA * type
Definition: RNA_types.h:51
void * data
Definition: RNA_types.h:52
struct ID * owner_id
Definition: RNA_types.h:50
struct bActionGroup * next
ListBase curves
ListBase groups
ListBase tracks
Definition: tracking.c:75
#define G(x, y, z)
PointerRNA * ptr
Definition: wm_files.c:3157