Blender  V2.93
nla.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 
24 #include <float.h>
25 #include <math.h>
26 #include <stddef.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 
31 #include "CLG_log.h"
32 
33 #include "MEM_guardedalloc.h"
34 
35 #include "BLI_ghash.h"
36 #include "BLI_listbase.h"
37 #include "BLI_string.h"
38 #include "BLI_string_utils.h"
39 #include "BLI_utildefines.h"
40 
41 #include "BLT_translation.h"
42 
43 #include "DNA_anim_types.h"
44 #include "DNA_scene_types.h"
45 #include "DNA_sound_types.h"
46 #include "DNA_speaker_types.h"
47 
48 #include "BKE_action.h"
49 #include "BKE_fcurve.h"
50 #include "BKE_global.h"
51 #include "BKE_lib_id.h"
52 #include "BKE_lib_query.h"
53 #include "BKE_main.h"
54 #include "BKE_nla.h"
55 #include "BKE_sound.h"
56 
57 #include "BLO_read_write.h"
58 
59 #include "RNA_access.h"
60 #include "nla_private.h"
61 
62 static CLG_LogRef LOG = {"bke.nla"};
63 
64 /* *************************************************** */
65 /* Data Management */
66 
67 /* Freeing ------------------------------------------- */
68 
69 /* Remove the given NLA strip from the NLA track it occupies, free the strip's data,
70  * and the strip itself.
71  */
72 void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user)
73 {
74  NlaStrip *cs, *csn;
75 
76  /* sanity checks */
77  if (strip == NULL) {
78  return;
79  }
80 
81  /* free child-strips */
82  for (cs = strip->strips.first; cs; cs = csn) {
83  csn = cs->next;
84  BKE_nlastrip_free(&strip->strips, cs, do_id_user);
85  }
86 
87  /* remove reference to action */
88  if (strip->act != NULL && do_id_user) {
89  id_us_min(&strip->act->id);
90  }
91 
92  /* free remapping info */
93  // if (strip->remap)
94  // BKE_animremap_free();
95 
96  /* free own F-Curves */
97  BKE_fcurves_free(&strip->fcurves);
98 
99  /* free own F-Modifiers */
100  free_fmodifiers(&strip->modifiers);
101 
102  /* free the strip itself */
103  if (strips) {
104  BLI_freelinkN(strips, strip);
105  }
106  else {
107  MEM_freeN(strip);
108  }
109 }
110 
111 /* Remove the given NLA track from the set of NLA tracks, free the track's data,
112  * and the track itself.
113  */
114 void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user)
115 {
116  NlaStrip *strip, *stripn;
117 
118  /* sanity checks */
119  if (nlt == NULL) {
120  return;
121  }
122 
123  /* free strips */
124  for (strip = nlt->strips.first; strip; strip = stripn) {
125  stripn = strip->next;
126  BKE_nlastrip_free(&nlt->strips, strip, do_id_user);
127  }
128 
129  /* free NLA track itself now */
130  if (tracks) {
131  BLI_freelinkN(tracks, nlt);
132  }
133  else {
134  MEM_freeN(nlt);
135  }
136 }
137 
138 /* Free the elements of type NLA Tracks provided in the given list, but do not free
139  * the list itself since that is not free-standing
140  */
141 void BKE_nla_tracks_free(ListBase *tracks, bool do_id_user)
142 {
143  NlaTrack *nlt, *nltn;
144 
145  /* sanity checks */
146  if (ELEM(NULL, tracks, tracks->first)) {
147  return;
148  }
149 
150  /* free tracks one by one */
151  for (nlt = tracks->first; nlt; nlt = nltn) {
152  nltn = nlt->next;
153  BKE_nlatrack_free(tracks, nlt, do_id_user);
154  }
155 
156  /* clear the list's pointers to be safe */
158 }
159 
160 /* Copying ------------------------------------------- */
161 
170  NlaStrip *strip,
171  const bool use_same_action,
172  const int flag)
173 {
174  NlaStrip *strip_d;
175  NlaStrip *cs, *cs_d;
176 
177  const bool do_id_user = (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0;
178 
179  /* sanity check */
180  if (strip == NULL) {
181  return NULL;
182  }
183 
184  /* make a copy */
185  strip_d = MEM_dupallocN(strip);
186  strip_d->next = strip_d->prev = NULL;
187 
188  /* handle action */
189  if (strip_d->act) {
190  if (use_same_action) {
191  if (do_id_user) {
192  /* increase user-count of action */
193  id_us_plus(&strip_d->act->id);
194  }
195  }
196  else {
197  /* use a copy of the action instead (user count shouldn't have changed yet) */
198  BKE_id_copy_ex(bmain, &strip_d->act->id, (ID **)&strip_d->act, flag);
199  }
200  }
201 
202  /* copy F-Curves and modifiers */
203  BKE_fcurves_copy(&strip_d->fcurves, &strip->fcurves);
204  copy_fmodifiers(&strip_d->modifiers, &strip->modifiers);
205 
206  /* make a copy of all the child-strips, one at a time */
207  BLI_listbase_clear(&strip_d->strips);
208 
209  for (cs = strip->strips.first; cs; cs = cs->next) {
210  cs_d = BKE_nlastrip_copy(bmain, cs, use_same_action, flag);
211  BLI_addtail(&strip_d->strips, cs_d);
212  }
213 
214  /* return the strip */
215  return strip_d;
216 }
217 
224  NlaTrack *nlt,
225  const bool use_same_actions,
226  const int flag)
227 {
228  NlaStrip *strip, *strip_d;
229  NlaTrack *nlt_d;
230 
231  /* sanity check */
232  if (nlt == NULL) {
233  return NULL;
234  }
235 
236  /* make a copy */
237  nlt_d = MEM_dupallocN(nlt);
238  nlt_d->next = nlt_d->prev = NULL;
239 
240  /* make a copy of all the strips, one at a time */
241  BLI_listbase_clear(&nlt_d->strips);
242 
243  for (strip = nlt->strips.first; strip; strip = strip->next) {
244  strip_d = BKE_nlastrip_copy(bmain, strip, use_same_actions, flag);
245  BLI_addtail(&nlt_d->strips, strip_d);
246  }
247 
248  /* return the copy */
249  return nlt_d;
250 }
251 
257 void BKE_nla_tracks_copy(Main *bmain, ListBase *dst, ListBase *src, const int flag)
258 {
259  NlaTrack *nlt, *nlt_d;
260 
261  /* sanity checks */
262  if (ELEM(NULL, dst, src)) {
263  return;
264  }
265 
266  /* clear out the destination list first for precautions... */
267  BLI_listbase_clear(dst);
268 
269  /* copy each NLA-track, one at a time */
270  for (nlt = src->first; nlt; nlt = nlt->next) {
271  /* make a copy, and add the copy to the destination list */
272  // XXX: we need to fix this sometime
273  nlt_d = BKE_nlatrack_copy(bmain, nlt, true, flag);
274  BLI_addtail(dst, nlt_d);
275  }
276 }
277 
278 /* Adding ------------------------------------------- */
279 
280 /* Add a NLA Track to the given AnimData
281  * - prev: NLA-Track to add the new one after
282  */
283 NlaTrack *BKE_nlatrack_add(AnimData *adt, NlaTrack *prev, const bool is_liboverride)
284 {
285  NlaTrack *nlt;
286 
287  /* sanity checks */
288  if (adt == NULL) {
289  return NULL;
290  }
291 
292  /* allocate new track */
293  nlt = MEM_callocN(sizeof(NlaTrack), "NlaTrack");
294 
295  /* set settings requiring the track to not be part of the stack yet */
297  nlt->index = BLI_listbase_count(&adt->nla_tracks);
298 
299  /* In liboverride case, we only add local tracks after all those coming from the linked data,
300  * so we need to find the first local track. */
301  if (is_liboverride && prev != NULL && (prev->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0) {
302  NlaTrack *first_local = prev->next;
303  for (; first_local != NULL && (first_local->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0;
304  first_local = first_local->next) {
305  }
306  prev = first_local != NULL ? first_local->prev : NULL;
307  }
308  /* Add track to stack, and make it the active one. */
309  if (prev != NULL) {
310  BLI_insertlinkafter(&adt->nla_tracks, prev, nlt);
311  }
312  else {
313  BLI_addtail(&adt->nla_tracks, nlt);
314  }
316 
317  /* must have unique name, but we need to seed this */
318  strcpy(nlt->name, "NlaTrack");
320  &adt->nla_tracks, nlt, DATA_("NlaTrack"), '.', offsetof(NlaTrack, name), sizeof(nlt->name));
321 
322  /* return the new track */
323  return nlt;
324 }
325 
326 /* Create a NLA Strip referencing the given Action */
328 {
329  NlaStrip *strip;
330 
331  /* sanity checks */
332  if (act == NULL) {
333  return NULL;
334  }
335 
336  /* allocate new strip */
337  strip = MEM_callocN(sizeof(NlaStrip), "NlaStrip");
338 
339  /* generic settings
340  * - selected flag to highlight this to the user
341  * - (XXX) disabled Auto-Blends, as this was often causing some unwanted effects
342  */
344 
345  /* assign the action reference */
346  strip->act = act;
347  id_us_plus(&act->id);
348 
349  /* determine initial range
350  * - strip length cannot be 0... ever...
351  */
352  calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
353 
354  strip->start = strip->actstart;
355  strip->end = (IS_EQF(strip->actstart, strip->actend)) ? (strip->actstart + 1.0f) :
356  (strip->actend);
357 
358  /* strip should be referenced as-is */
359  strip->scale = 1.0f;
360  strip->repeat = 1.0f;
361 
362  /* return the new strip */
363  return strip;
364 }
365 
366 /* Add new NLA-strip to the top of the NLA stack - i.e.
367  * into the last track if space, or a new one otherwise. */
368 NlaStrip *BKE_nlastack_add_strip(AnimData *adt, bAction *act, const bool is_liboverride)
369 {
370  NlaStrip *strip;
371  NlaTrack *nlt;
372 
373  /* sanity checks */
374  if (ELEM(NULL, adt, act)) {
375  return NULL;
376  }
377 
378  /* create a new NLA strip */
379  strip = BKE_nlastrip_new(act);
380  if (strip == NULL) {
381  return NULL;
382  }
383 
384  /* firstly try adding strip to last track, but if that fails, add to a new track */
385  if (BKE_nlatrack_add_strip(adt->nla_tracks.last, strip, is_liboverride) == 0) {
386  /* trying to add to the last track failed (no track or no space),
387  * so add a new track to the stack, and add to that...
388  */
389  nlt = BKE_nlatrack_add(adt, NULL, is_liboverride);
390  BKE_nlatrack_add_strip(nlt, strip, is_liboverride);
391  }
392 
393  /* automatically name it too */
394  BKE_nlastrip_validate_name(adt, strip);
395 
396  /* returns the strip added */
397  return strip;
398 }
399 
400 /* Add a NLA Strip referencing the given speaker's sound */
402 {
403  NlaStrip *strip = MEM_callocN(sizeof(NlaStrip), "NlaSoundStrip");
404 
405  /* if speaker has a sound, set the strip length to the length of the sound,
406  * otherwise default to length of 10 frames
407  */
408 #ifdef WITH_AUDASPACE
409  if (speaker->sound) {
410  SoundInfo info;
411  if (BKE_sound_info_get(bmain, speaker->sound, &info)) {
412  strip->end = (float)ceil((double)info.length * FPS);
413  }
414  }
415  else
416 #endif
417  {
418  strip->end = 10.0f;
419  /* quiet compiler warnings */
420  UNUSED_VARS(bmain, scene, speaker);
421  }
422 
423  /* general settings */
424  strip->type = NLASTRIP_TYPE_SOUND;
425 
426  strip->flag = NLASTRIP_FLAG_SELECT;
427  strip->extendmode = NLASTRIP_EXTEND_NOTHING; /* nothing to extend... */
428 
429  /* strip should be referenced as-is */
430  strip->scale = 1.0f;
431  strip->repeat = 1.0f;
432 
433  /* return this strip */
434  return strip;
435 }
436 
442 {
444 
445  LISTBASE_FOREACH (FCurve *, fcu, &strip->fcurves) {
447  }
448 
449  LISTBASE_FOREACH (NlaStrip *, substrip, &strip->strips) {
450  BKE_nla_strip_foreach_id(substrip, data);
451  }
452 }
453 
454 /* *************************************************** */
455 /* NLA Evaluation <-> Editing Stuff */
456 
457 /* Strip Mapping ------------------------------------- */
458 
459 /* non clipped mapping for strip-time <-> global time (for Action-Clips)
460  * invert = convert action-strip time to global time
461  */
462 static float nlastrip_get_frame_actionclip(NlaStrip *strip, float cframe, short mode)
463 {
464  float actlength, scale;
465  // float repeat; // UNUSED
466 
467  /* get number of repeats */
468  if (IS_EQF(strip->repeat, 0.0f)) {
469  strip->repeat = 1.0f;
470  }
471  // repeat = strip->repeat; // UNUSED
472 
473  /* scaling */
474  if (IS_EQF(strip->scale, 0.0f)) {
475  strip->scale = 1.0f;
476  }
477 
478  /* Scale must be positive - we've got a special flag for reversing. */
479  scale = fabsf(strip->scale);
480 
481  /* length of referenced action */
482  actlength = strip->actend - strip->actstart;
483  if (IS_EQF(actlength, 0.0f)) {
484  actlength = 1.0f;
485  }
486 
487  /* reversed = play strip backwards */
488  if (strip->flag & NLASTRIP_FLAG_REVERSE) {
489  /* FIXME: this won't work right with Graph Editor? */
490  if (mode == NLATIME_CONVERT_MAP) {
491  return strip->end - scale * (cframe - strip->actstart);
492  }
493  if (mode == NLATIME_CONVERT_UNMAP) {
494  return (strip->end + (strip->actstart * scale - cframe)) / scale;
495  }
496  /* if (mode == NLATIME_CONVERT_EVAL) */
497  if (IS_EQF((float)cframe, strip->end) && IS_EQF(strip->repeat, floorf(strip->repeat))) {
498  /* This case prevents the motion snapping back to the first frame at the end of the strip
499  * by catching the case where repeats is a whole number, which means that the end of the
500  * strip could also be interpreted as the end of the start of a repeat. */
501  return strip->actstart;
502  }
503 
504  /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working
505  * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat
506  */
507  return strip->actend - fmodf(cframe - strip->start, actlength * scale) / scale;
508  }
509 
510  if (mode == NLATIME_CONVERT_MAP) {
511  return strip->start + scale * (cframe - strip->actstart);
512  }
513  if (mode == NLATIME_CONVERT_UNMAP) {
514  return strip->actstart + (cframe - strip->start) / scale;
515  }
516  /* if (mode == NLATIME_CONVERT_EVAL) */
517  if (IS_EQF(cframe, strip->end) && IS_EQF(strip->repeat, floorf(strip->repeat))) {
518  /* This case prevents the motion snapping back to the first frame at the end of the strip
519  * by catching the case where repeats is a whole number, which means that the end of the
520  * strip could also be interpreted as the end of the start of a repeat. */
521  return strip->actend;
522  }
523 
524  /* - the 'fmod(..., actlength * scale)' is needed to get the repeats working
525  * - the '/ scale' is needed to ensure that scaling influences the timing within the repeat
526  */
527  return strip->actstart + fmodf(cframe - strip->start, actlength * scale) / scale;
528 }
529 
530 /* non clipped mapping for strip-time <-> global time (for Transitions)
531  * invert = convert action-strip time to global time
532  */
533 static float nlastrip_get_frame_transition(NlaStrip *strip, float cframe, short mode)
534 {
535  float length;
536 
537  /* length of strip */
538  length = strip->end - strip->start;
539 
540  /* reversed = play strip backwards */
541  if (strip->flag & NLASTRIP_FLAG_REVERSE) {
542  if (mode == NLATIME_CONVERT_MAP) {
543  return strip->end - (length * cframe);
544  }
545 
546  return (strip->end - cframe) / length;
547  }
548 
549  if (mode == NLATIME_CONVERT_MAP) {
550  return (length * cframe) + strip->start;
551  }
552 
553  return (cframe - strip->start) / length;
554 }
555 
556 /* non clipped mapping for strip-time <-> global time
557  * mode = eNlaTime_ConvertModes[] -> NLATIME_CONVERT_*
558  *
559  * only secure for 'internal' (i.e. within AnimSys evaluation) operations,
560  * but should not be directly relied on for stuff which interacts with editors
561  */
562 float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode)
563 {
564  switch (strip->type) {
565  case NLASTRIP_TYPE_META: /* Meta - for now, does the same as transition
566  * (is really just an empty container). */
567  case NLASTRIP_TYPE_TRANSITION: /* transition */
568  return nlastrip_get_frame_transition(strip, cframe, mode);
569 
570  case NLASTRIP_TYPE_CLIP: /* action-clip (default) */
571  default:
572  return nlastrip_get_frame_actionclip(strip, cframe, mode);
573  }
574 }
575 
576 /* Non clipped mapping for strip-time <-> global time
577  * mode = eNlaTime_ConvertModes -> NLATIME_CONVERT_*
578  *
579  * Public API method - perform this mapping using the given AnimData block
580  * and perform any necessary sanity checks on the value
581  */
582 float BKE_nla_tweakedit_remap(AnimData *adt, float cframe, short mode)
583 {
584  NlaStrip *strip;
585 
586  /* sanity checks
587  * - obviously we've got to have some starting data
588  * - when not in tweakmode, the active Action does not have any scaling applied :)
589  * - when in tweakmode, if the no-mapping flag is set, do not map
590  */
591  if ((adt == NULL) || (adt->flag & ADT_NLA_EDIT_ON) == 0 || (adt->flag & ADT_NLA_EDIT_NOMAP)) {
592  return cframe;
593  }
594 
595  /* if the active-strip info has been stored already, access this, otherwise look this up
596  * and store for (very probable) future usage
597  */
598  if (adt->act_track == NULL) {
599  if (adt->actstrip) {
601  }
602  else {
604  }
605  }
606  if (adt->actstrip == NULL) {
608  }
609  strip = adt->actstrip;
610 
611  /* Sanity checks:
612  * - In rare cases, we may not be able to find this strip for some reason (internal error)
613  * - For now, if the user has defined a curve to control the time, this correction cannot be
614  * performed reliably.
615  */
616  if ((strip == NULL) || (strip->flag & NLASTRIP_FLAG_USR_TIME)) {
617  return cframe;
618  }
619 
620  /* perform the correction now... */
621  return nlastrip_get_frame(strip, cframe, mode);
622 }
623 
624 /* *************************************************** */
625 /* NLA API */
626 
627 /* List of Strips ------------------------------------ */
628 /* (these functions are used for NLA-Tracks and also for nested/meta-strips) */
629 
630 /* Check if there is any space in the given list to add the given strip */
631 bool BKE_nlastrips_has_space(ListBase *strips, float start, float end)
632 {
633  NlaStrip *strip;
634 
635  /* sanity checks */
636  if ((strips == NULL) || IS_EQF(start, end)) {
637  return false;
638  }
639  if (start > end) {
640  puts("BKE_nlastrips_has_space() error... start and end arguments swapped");
641  SWAP(float, start, end);
642  }
643 
644  /* loop over NLA strips checking for any overlaps with this area... */
645  for (strip = strips->first; strip; strip = strip->next) {
646  /* if start frame of strip is past the target end-frame, that means that
647  * we've gone past the window we need to check for, so things are fine
648  */
649  if (strip->start >= end) {
650  return true;
651  }
652 
653  /* if the end of the strip is greater than either of the boundaries, the range
654  * must fall within the extents of the strip
655  */
656  if ((strip->end > start) || (strip->end > end)) {
657  return false;
658  }
659  }
660 
661  /* if we are still here, we haven't encountered any overlapping strips */
662  return true;
663 }
664 
665 /* Rearrange the strips in the track so that they are always in order
666  * (usually only needed after a strip has been moved)
667  */
669 {
670  ListBase tmp = {NULL, NULL};
671  NlaStrip *strip, *sstrip, *stripn;
672 
673  /* sanity checks */
674  if (ELEM(NULL, strips, strips->first)) {
675  return;
676  }
677 
678  /* we simply perform insertion sort on this list, since it is assumed that per track,
679  * there are only likely to be at most 5-10 strips
680  */
681  for (strip = strips->first; strip; strip = stripn) {
682  short not_added = 1;
683 
684  stripn = strip->next;
685 
686  /* remove this strip from the list, and add it to the new list, searching from the end of
687  * the list, assuming that the lists are in order
688  */
689  BLI_remlink(strips, strip);
690 
691  for (sstrip = tmp.last; sstrip; sstrip = sstrip->prev) {
692  /* check if add after */
693  if (sstrip->end <= strip->start) {
694  BLI_insertlinkafter(&tmp, sstrip, strip);
695  not_added = 0;
696  break;
697  }
698  }
699 
700  /* add before first? */
701  if (not_added) {
702  BLI_addhead(&tmp, strip);
703  }
704  }
705 
706  /* reassign the start and end points of the strips */
707  strips->first = tmp.first;
708  strips->last = tmp.last;
709 }
710 
711 /* Add the given NLA-Strip to the given list of strips, assuming that it
712  * isn't currently a member of another list
713  */
715 {
716  NlaStrip *ns;
717  bool not_added = true;
718 
719  /* sanity checks */
720  if (ELEM(NULL, strips, strip)) {
721  return false;
722  }
723 
724  /* check if any space to add */
725  if (BKE_nlastrips_has_space(strips, strip->start, strip->end) == 0) {
726  return false;
727  }
728 
729  /* find the right place to add the strip to the nominated track */
730  for (ns = strips->first; ns; ns = ns->next) {
731  /* if current strip occurs after the new strip, add it before */
732  if (ns->start >= strip->end) {
733  BLI_insertlinkbefore(strips, ns, strip);
734  not_added = 0;
735  break;
736  }
737  }
738  if (not_added) {
739  /* just add to the end of the list of the strips then... */
740  BLI_addtail(strips, strip);
741  }
742 
743  /* added... */
744  return true;
745 }
746 
747 /* Meta-Strips ------------------------------------ */
748 
749 /* Convert 'islands' (i.e. continuous string of) selected strips to be
750  * contained within 'Meta-Strips' which act as strips which contain strips.
751  * temp: are the meta-strips to be created 'temporary' ones used for transforms?
752  */
753 void BKE_nlastrips_make_metas(ListBase *strips, bool is_temp)
754 {
755  NlaStrip *mstrip = NULL;
756  NlaStrip *strip, *stripn;
757 
758  /* sanity checks */
759  if (ELEM(NULL, strips, strips->first)) {
760  return;
761  }
762 
763  /* group all continuous chains of selected strips into meta-strips */
764  for (strip = strips->first; strip; strip = stripn) {
765  stripn = strip->next;
766 
767  if (strip->flag & NLASTRIP_FLAG_SELECT) {
768  /* if there is an existing meta-strip, add this strip to it, otherwise, create a new one */
769  if (mstrip == NULL) {
770  /* add a new meta-strip, and add it before the current strip that it will replace... */
771  mstrip = MEM_callocN(sizeof(NlaStrip), "Meta-NlaStrip");
772  mstrip->type = NLASTRIP_TYPE_META;
773  BLI_insertlinkbefore(strips, strip, mstrip);
774 
775  /* set flags */
776  mstrip->flag = NLASTRIP_FLAG_SELECT;
777 
778  /* set temp flag if appropriate (i.e. for transform-type editing) */
779  if (is_temp) {
780  mstrip->flag |= NLASTRIP_FLAG_TEMP_META;
781  }
782 
783  /* set default repeat/scale values to prevent warnings */
784  mstrip->repeat = mstrip->scale = 1.0f;
785 
786  /* make its start frame be set to the start frame of the current strip */
787  mstrip->start = strip->start;
788  }
789 
790  /* remove the selected strips from the track, and add to the meta */
791  BLI_remlink(strips, strip);
792  BLI_addtail(&mstrip->strips, strip);
793 
794  /* expand the meta's dimensions to include the newly added strip- i.e. its last frame */
795  mstrip->end = strip->end;
796  }
797  else {
798  /* current strip wasn't selected, so the end of 'island' of selected strips has been reached,
799  * so stop adding strips to the current meta
800  */
801  mstrip = NULL;
802  }
803  }
804 }
805 
806 /* Split a meta-strip into a set of normal strips */
808 {
809  NlaStrip *cs, *csn;
810 
811  /* sanity check */
812  if (ELEM(NULL, strips, strip)) {
813  return;
814  }
815 
816  /* move each one of the meta-strip's children before the meta-strip
817  * in the list of strips after unlinking them from the meta-strip
818  */
819  for (cs = strip->strips.first; cs; cs = csn) {
820  csn = cs->next;
821  BLI_remlink(&strip->strips, cs);
822  BLI_insertlinkbefore(strips, strip, cs);
823  }
824 
825  /* free the meta-strip now */
826  BKE_nlastrip_free(strips, strip, true);
827 }
828 
829 /* Remove meta-strips (i.e. flatten the list of strips) from the top-level of the list of strips
830  * sel: only consider selected meta-strips, otherwise all meta-strips are removed
831  * onlyTemp: only remove the 'temporary' meta-strips used for transforms
832  */
833 void BKE_nlastrips_clear_metas(ListBase *strips, bool only_sel, bool only_temp)
834 {
835  NlaStrip *strip, *stripn;
836 
837  /* sanity checks */
838  if (ELEM(NULL, strips, strips->first)) {
839  return;
840  }
841 
842  /* remove meta-strips fitting the criteria of the arguments */
843  for (strip = strips->first; strip; strip = stripn) {
844  stripn = strip->next;
845 
846  /* check if strip is a meta-strip */
847  if (strip->type == NLASTRIP_TYPE_META) {
848  /* if check if selection and 'temporary-only' considerations are met */
849  if ((!only_sel) || (strip->flag & NLASTRIP_FLAG_SELECT)) {
850  if ((!only_temp) || (strip->flag & NLASTRIP_FLAG_TEMP_META)) {
851  BKE_nlastrips_clear_metastrip(strips, strip);
852  }
853  }
854  }
855  }
856 }
857 
858 /* Add the given NLA-Strip to the given Meta-Strip, assuming that the
859  * strip isn't attached to any list of strips
860  */
862 {
863  /* sanity checks */
864  if (ELEM(NULL, mstrip, strip)) {
865  return false;
866  }
867 
868  /* firstly, check if the meta-strip has space for this */
869  if (BKE_nlastrips_has_space(&mstrip->strips, strip->start, strip->end) == 0) {
870  return false;
871  }
872 
873  /* check if this would need to be added to the ends of the meta,
874  * and subsequently, if the neighboring strips allow us enough room
875  */
876  if (strip->start < mstrip->start) {
877  /* check if strip to the left (if it exists) ends before the
878  * start of the strip we're trying to add
879  */
880  if ((mstrip->prev == NULL) || (mstrip->prev->end <= strip->start)) {
881  /* add strip to start of meta's list, and expand dimensions */
882  BLI_addhead(&mstrip->strips, strip);
883  mstrip->start = strip->start;
884 
885  return true;
886  }
887  /* failed... no room before */
888  return false;
889  }
890  if (strip->end > mstrip->end) {
891  /* check if strip to the right (if it exists) starts before the
892  * end of the strip we're trying to add
893  */
894  if ((mstrip->next == NULL) || (mstrip->next->start >= strip->end)) {
895  /* add strip to end of meta's list, and expand dimensions */
896  BLI_addtail(&mstrip->strips, strip);
897  mstrip->end = strip->end;
898 
899  return true;
900  }
901  /* failed... no room after */
902  return false;
903  }
904 
905  /* just try to add to the meta-strip (no dimension changes needed) */
906  return BKE_nlastrips_add_strip(&mstrip->strips, strip);
907 }
908 
909 /* Adjust the settings of NLA-Strips contained within a Meta-Strip (recursively),
910  * until the Meta-Strips children all fit within the Meta-Strip's new dimensions
911  */
913 {
914  NlaStrip *strip;
915  float oStart, oEnd, offset;
916  float oLen, nLen;
917  short scaleChanged = 0;
918 
919  /* sanity checks
920  * - strip must exist
921  * - strip must be a meta-strip with some contents
922  */
923  if (ELEM(NULL, mstrip, mstrip->strips.first)) {
924  return;
925  }
926  if (mstrip->type != NLASTRIP_TYPE_META) {
927  return;
928  }
929 
930  /* get the original start/end points, and calculate the start-frame offset
931  * - these are simply the start/end frames of the child strips,
932  * since we assume they weren't transformed yet
933  */
934  oStart = ((NlaStrip *)mstrip->strips.first)->start;
935  oEnd = ((NlaStrip *)mstrip->strips.last)->end;
936  offset = mstrip->start - oStart;
937 
938  /* optimization:
939  * don't flush if nothing changed yet
940  * TODO: maybe we need a flag to say always flush?
941  */
942  if (IS_EQF(oStart, mstrip->start) && IS_EQF(oEnd, mstrip->end)) {
943  return;
944  }
945 
946  /* check if scale changed */
947  oLen = oEnd - oStart;
948  nLen = mstrip->end - mstrip->start;
949  if (IS_EQF(nLen, oLen) == 0) {
950  scaleChanged = 1;
951  }
952 
953  /* for each child-strip, calculate new start/end points based on this new info */
954  for (strip = mstrip->strips.first; strip; strip = strip->next) {
955  if (scaleChanged) {
956  float p1, p2;
957 
958  /* compute positions of endpoints relative to old extents of strip */
959  p1 = (strip->start - oStart) / oLen;
960  p2 = (strip->end - oStart) / oLen;
961 
962  /* Apply new strip endpoints using the proportions,
963  * then wait for second pass to flush scale properly. */
964  strip->start = (p1 * nLen) + mstrip->start;
965  strip->end = (p2 * nLen) + mstrip->start;
966  }
967  else {
968  /* just apply the changes in offset to both ends of the strip */
969  strip->start += offset;
970  strip->end += offset;
971  }
972  }
973 
974  /* apply a second pass over child strips, to finish up unfinished business */
975  for (strip = mstrip->strips.first; strip; strip = strip->next) {
976  /* only if scale changed, need to perform RNA updates */
977  if (scaleChanged) {
978  PointerRNA ptr;
979 
980  /* use RNA updates to compute scale properly */
982 
983  RNA_float_set(&ptr, "frame_start", strip->start);
984  RNA_float_set(&ptr, "frame_end", strip->end);
985  }
986 
987  /* finally, make sure the strip's children (if it is a meta-itself), get updated */
989  }
990 }
991 
992 /* NLA-Tracks ---------------------------------------- */
993 
994 /* Find the active NLA-track for the given stack */
996 {
997  NlaTrack *nlt;
998 
999  /* sanity check */
1000  if (ELEM(NULL, tracks, tracks->first)) {
1001  return NULL;
1002  }
1003 
1004  /* try to find the first active track */
1005  for (nlt = tracks->first; nlt; nlt = nlt->next) {
1006  if (nlt->flag & NLATRACK_ACTIVE) {
1007  return nlt;
1008  }
1009  }
1010 
1011  /* none found */
1012  return NULL;
1013 }
1014 
1015 /* Get the NLA Track that the active action/action strip comes from,
1016  * since this info is not stored in AnimData. It also isn't as simple
1017  * as just using the active track, since multiple tracks may have been
1018  * entered at the same time.
1019  */
1021 {
1022  NlaTrack *nlt;
1023 
1024  /* sanity check */
1025  if (adt == NULL) {
1026  return NULL;
1027  }
1028 
1029  /* Since the track itself gets disabled, we want the first disabled... */
1030  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
1031  if (nlt->flag & (NLATRACK_ACTIVE | NLATRACK_DISABLED)) {
1032  /* For good measure, make sure that strip actually exists there */
1033  if (BLI_findindex(&nlt->strips, adt->actstrip) != -1) {
1034  return nlt;
1035  }
1036  if (G.debug & G_DEBUG) {
1037  printf("%s: Active strip (%p, %s) not in NLA track found (%p, %s)\n",
1038  __func__,
1039  adt->actstrip,
1040  (adt->actstrip) ? adt->actstrip->name : "<None>",
1041  nlt,
1042  nlt->name);
1043  }
1044  }
1045  }
1046 
1047  /* Not found! */
1048  return NULL;
1049 }
1050 
1051 /* Toggle the 'solo' setting for the given NLA-track, making sure that it is the only one
1052  * that has this status in its AnimData block.
1053  */
1055 {
1056  NlaTrack *nt;
1057 
1058  /* sanity check */
1059  if (ELEM(NULL, adt, adt->nla_tracks.first)) {
1060  return;
1061  }
1062 
1063  /* firstly, make sure 'solo' flag for all tracks is disabled */
1064  for (nt = adt->nla_tracks.first; nt; nt = nt->next) {
1065  if (nt != nlt) {
1066  nt->flag &= ~NLATRACK_SOLO;
1067  }
1068  }
1069 
1070  /* now, enable 'solo' for the given track if appropriate */
1071  if (nlt) {
1072  /* toggle solo status */
1073  nlt->flag ^= NLATRACK_SOLO;
1074 
1075  /* set or clear solo-status on AnimData */
1076  if (nlt->flag & NLATRACK_SOLO) {
1077  adt->flag |= ADT_NLA_SOLO_TRACK;
1078  }
1079  else {
1080  adt->flag &= ~ADT_NLA_SOLO_TRACK;
1081  }
1082  }
1083  else {
1084  adt->flag &= ~ADT_NLA_SOLO_TRACK;
1085  }
1086 }
1087 
1088 /* Make the given NLA-track the active one for the given stack. If no track is provided,
1089  * this function can be used to simply deactivate all the NLA tracks in the given stack too.
1090  */
1092 {
1093  NlaTrack *nlt;
1094 
1095  /* sanity check */
1096  if (ELEM(NULL, tracks, tracks->first)) {
1097  return;
1098  }
1099 
1100  /* deactivate all the rest */
1101  for (nlt = tracks->first; nlt; nlt = nlt->next) {
1102  nlt->flag &= ~NLATRACK_ACTIVE;
1103  }
1104 
1105  /* set the given one as the active one */
1106  if (nlt_a) {
1107  nlt_a->flag |= NLATRACK_ACTIVE;
1108  }
1109 }
1110 
1111 /* Check if there is any space in the given track to add a strip of the given length */
1112 bool BKE_nlatrack_has_space(NlaTrack *nlt, float start, float end)
1113 {
1114  /* sanity checks
1115  * - track must exist
1116  * - track must be editable
1117  * - bounds cannot be equal (0-length is nasty)
1118  */
1119  if ((nlt == NULL) || (nlt->flag & NLATRACK_PROTECTED) || IS_EQF(start, end)) {
1120  return false;
1121  }
1122 
1123  if (start > end) {
1124  puts("BKE_nlatrack_has_space() error... start and end arguments swapped");
1125  SWAP(float, start, end);
1126  }
1127 
1128  /* check if there's any space left in the track for a strip of the given length */
1129  return BKE_nlastrips_has_space(&nlt->strips, start, end);
1130 }
1131 
1132 /* Rearrange the strips in the track so that they are always in order
1133  * (usually only needed after a strip has been moved)
1134  */
1136 {
1137  /* sanity checks */
1138  if (ELEM(NULL, nlt, nlt->strips.first)) {
1139  return;
1140  }
1141 
1142  /* sort the strips with a more generic function */
1144 }
1145 
1146 /* Add the given NLA-Strip to the given NLA-Track, assuming that it
1147  * isn't currently attached to another one
1148  */
1149 bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip, const bool is_liboverride)
1150 {
1151  /* sanity checks */
1152  if (ELEM(NULL, nlt, strip)) {
1153  return false;
1154  }
1155 
1156  /* Do not allow adding strips if this track is locked, or not a local one in liboverride case. */
1157  if (nlt->flag & NLATRACK_PROTECTED ||
1158  (is_liboverride && (nlt->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0)) {
1159  return false;
1160  }
1161 
1162  /* try to add the strip to the track using a more generic function */
1163  return BKE_nlastrips_add_strip(&nlt->strips, strip);
1164 }
1165 
1166 /* Get the extents of the given NLA-Track including gaps between strips,
1167  * returning whether this succeeded or not
1168  */
1170 {
1171  NlaStrip *strip;
1172 
1173  /* initialize bounds */
1174  if (bounds) {
1175  bounds[0] = bounds[1] = 0.0f;
1176  }
1177  else {
1178  return false;
1179  }
1180 
1181  /* sanity checks */
1182  if (ELEM(NULL, nlt, nlt->strips.first)) {
1183  return false;
1184  }
1185 
1186  /* lower bound is first strip's start frame */
1187  strip = nlt->strips.first;
1188  bounds[0] = strip->start;
1189 
1190  /* upper bound is last strip's end frame */
1191  strip = nlt->strips.last;
1192  bounds[1] = strip->end;
1193 
1194  /* done */
1195  return true;
1196 }
1197 
1205 {
1206  return (ID_IS_OVERRIDE_LIBRARY(id) &&
1207  (nlt == NULL || (nlt->flag & NLATRACK_OVERRIDELIBRARY_LOCAL) == 0));
1208 }
1209 
1210 /* NLA Strips -------------------------------------- */
1211 
1212 /* Find the active NLA-strip within the given track */
1214 {
1215  NlaStrip *strip;
1216 
1217  /* sanity check */
1218  if (ELEM(NULL, nlt, nlt->strips.first)) {
1219  return NULL;
1220  }
1221 
1222  /* try to find the first active strip */
1223  for (strip = nlt->strips.first; strip; strip = strip->next) {
1224  if (strip->flag & NLASTRIP_FLAG_ACTIVE) {
1225  return strip;
1226  }
1227  }
1228 
1229  /* none found */
1230  return NULL;
1231 }
1232 
1233 /* Make the given NLA-Strip the active one within the given block */
1235 {
1236  NlaTrack *nlt;
1237  NlaStrip *nls;
1238 
1239  /* sanity checks */
1240  if (adt == NULL) {
1241  return;
1242  }
1243 
1244  /* loop over tracks, deactivating*/
1245  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
1246  for (nls = nlt->strips.first; nls; nls = nls->next) {
1247  if (nls != strip) {
1248  nls->flag &= ~NLASTRIP_FLAG_ACTIVE;
1249  }
1250  else {
1251  nls->flag |= NLASTRIP_FLAG_ACTIVE;
1252  }
1253  }
1254  }
1255 }
1256 
1257 /* Does the given NLA-strip fall within the given bounds (times)? */
1258 bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max)
1259 {
1260  const float stripLen = (strip) ? strip->end - strip->start : 0.0f;
1261  const float boundsLen = fabsf(max - min);
1262 
1263  /* sanity checks */
1264  if ((strip == NULL) || IS_EQF(stripLen, 0.0f) || IS_EQF(boundsLen, 0.0f)) {
1265  return false;
1266  }
1267 
1268  /* only ok if at least part of the strip is within the bounding window
1269  * - first 2 cases cover when the strip length is less than the bounding area
1270  * - second 2 cases cover when the strip length is greater than the bounding area
1271  */
1272  if ((stripLen < boundsLen) &&
1273  !(IN_RANGE(strip->start, min, max) || IN_RANGE(strip->end, min, max))) {
1274  return false;
1275  }
1276  if ((stripLen > boundsLen) &&
1277  !(IN_RANGE(min, strip->start, strip->end) || IN_RANGE(max, strip->start, strip->end))) {
1278  return false;
1279  }
1280 
1281  /* should be ok! */
1282  return true;
1283 }
1284 
1285 /* Ensure that strip doesn't overlap those around it after resizing
1286  * by offsetting those which follow. */
1288 {
1289  /* next strips - do this first, since we're often just getting longer */
1290  if (strip->next) {
1291  NlaStrip *nls = strip->next;
1292  float offset = 0.0f;
1293 
1294  if (nls->type == NLASTRIP_TYPE_TRANSITION) {
1295  /* transition strips should grow/shrink to accommodate the resized strip,
1296  * but if the strip's bounds now exceed the transition, we're forced to
1297  * offset everything to maintain the balance
1298  */
1299  if (strip->end <= nls->start) {
1300  /* grow the transition to fill the void */
1301  nls->start = strip->end;
1302  }
1303  else if (strip->end < nls->end) {
1304  /* shrink the transition to give the strip room */
1305  nls->start = strip->end;
1306  }
1307  else {
1308  /* Shrink transition down to 1 frame long (so that it can still be found),
1309  * then offset everything else by the remaining deficit to give the strip room. */
1310  nls->start = nls->end - 1.0f;
1311 
1312  /* XXX: review whether preventing fractional values is good here... */
1313  offset = ceilf(strip->end - nls->start);
1314 
1315  /* apply necessary offset to ensure that the strip has enough space */
1316  for (; nls; nls = nls->next) {
1317  nls->start += offset;
1318  nls->end += offset;
1319  }
1320  }
1321  }
1322  else if (strip->end > nls->start) {
1323  /* NOTE: need to ensure we don't have a fractional frame offset, even if that leaves a gap,
1324  * otherwise it will be very hard to get rid of later
1325  */
1326  offset = ceilf(strip->end - nls->start);
1327 
1328  /* apply to times of all strips in this direction */
1329  for (; nls; nls = nls->next) {
1330  nls->start += offset;
1331  nls->end += offset;
1332  }
1333  }
1334  }
1335 
1336  /* previous strips - same routine as before */
1337  /* NOTE: when strip bounds are recalculated, this is not considered! */
1338  if (strip->prev) {
1339  NlaStrip *nls = strip->prev;
1340  float offset = 0.0f;
1341 
1342  if (nls->type == NLASTRIP_TYPE_TRANSITION) {
1343  /* transition strips should grow/shrink to accommodate the resized strip,
1344  * but if the strip's bounds now exceed the transition, we're forced to
1345  * offset everything to maintain the balance
1346  */
1347  if (strip->start >= nls->end) {
1348  /* grow the transition to fill the void */
1349  nls->end = strip->start;
1350  }
1351  else if (strip->start > nls->start) {
1352  /* shrink the transition to give the strip room */
1353  nls->end = strip->start;
1354  }
1355  else {
1356  /* Shrink transition down to 1 frame long (so that it can still be found),
1357  * then offset everything else by the remaining deficit to give the strip room. */
1358  nls->end = nls->start + 1.0f;
1359 
1360  /* XXX: review whether preventing fractional values is good here... */
1361  offset = ceilf(nls->end - strip->start);
1362 
1363  /* apply necessary offset to ensure that the strip has enough space */
1364  for (; nls; nls = nls->prev) {
1365  nls->start -= offset;
1366  nls->end -= offset;
1367  }
1368  }
1369  }
1370  else if (strip->start < nls->end) {
1371  /* NOTE: need to ensure we don't have a fractional frame offset, even if that leaves a gap,
1372  * otherwise it will be very hard to get rid of later
1373  */
1374  offset = ceilf(nls->end - strip->start);
1375 
1376  /* apply to times of all strips in this direction */
1377  for (; nls; nls = nls->prev) {
1378  nls->start -= offset;
1379  nls->end -= offset;
1380  }
1381  }
1382  }
1383 }
1384 
1390 {
1391  float prev_actstart;
1392 
1393  if (strip == NULL || strip->type != NLASTRIP_TYPE_CLIP) {
1394  return;
1395  }
1396 
1397  prev_actstart = strip->actstart;
1398 
1399  calc_action_range(strip->act, &strip->actstart, &strip->actend, 0);
1400 
1401  /* Set start such that key's do not visually move, to preserve the overall animation result. */
1402  strip->start += (strip->actstart - prev_actstart) * strip->scale;
1403 
1405 }
1406 /* Recalculate the start and end frames for the current strip, after changing
1407  * the extents of the action or the mapping (repeats or scale factor) info
1408  */
1410 {
1411  float actlen, mapping;
1412 
1413  /* sanity checks
1414  * - must have a strip
1415  * - can only be done for action clips
1416  */
1417  if ((strip == NULL) || (strip->type != NLASTRIP_TYPE_CLIP)) {
1418  return;
1419  }
1420 
1421  /* calculate new length factors */
1422  actlen = strip->actend - strip->actstart;
1423  if (IS_EQF(actlen, 0.0f)) {
1424  actlen = 1.0f;
1425  }
1426 
1427  mapping = strip->scale * strip->repeat;
1428 
1429  /* adjust endpoint of strip in response to this */
1430  if (IS_EQF(mapping, 0.0f) == 0) {
1431  strip->end = (actlen * mapping) + strip->start;
1432  }
1433 
1434  /* make sure we don't overlap our neighbors */
1436 }
1437 
1438 /* Is the given NLA-strip the first one to occur for the given AnimData block */
1439 // TODO: make this an api method if necessary, but need to add prefix first
1440 static bool nlastrip_is_first(AnimData *adt, NlaStrip *strip)
1441 {
1442  NlaTrack *nlt;
1443  NlaStrip *ns;
1444 
1445  /* sanity checks */
1446  if (ELEM(NULL, adt, strip)) {
1447  return false;
1448  }
1449 
1450  /* check if strip has any strips before it */
1451  if (strip->prev) {
1452  return false;
1453  }
1454 
1455  /* check other tracks to see if they have a strip that's earlier */
1456  /* TODO: or should we check that the strip's track is also the first? */
1457  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
1458  /* only check the first strip, assuming that they're all in order */
1459  ns = nlt->strips.first;
1460  if (ns) {
1461  if (ns->start < strip->start) {
1462  return false;
1463  }
1464  }
1465  }
1466 
1467  /* should be first now */
1468  return true;
1469 }
1470 
1471 /* Animated Strips ------------------------------------------- */
1472 
1473 /* Check if the given NLA-Track has any strips with own F-Curves */
1475 {
1476  NlaStrip *strip;
1477 
1478  /* sanity checks */
1479  if (ELEM(NULL, nlt, nlt->strips.first)) {
1480  return false;
1481  }
1482 
1483  /* check each strip for F-Curves only (don't care about whether the flags are set) */
1484  for (strip = nlt->strips.first; strip; strip = strip->next) {
1485  if (strip->fcurves.first) {
1486  return true;
1487  }
1488  }
1489 
1490  /* none found */
1491  return false;
1492 }
1493 
1494 /* Check if given NLA-Tracks have any strips with own F-Curves */
1496 {
1497  NlaTrack *nlt;
1498 
1499  /* sanity checks */
1500  if (ELEM(NULL, tracks, tracks->first)) {
1501  return false;
1502  }
1503 
1504  /* check each track, stopping on the first hit */
1505  for (nlt = tracks->first; nlt; nlt = nlt->next) {
1507  return true;
1508  }
1509  }
1510 
1511  /* none found */
1512  return false;
1513 }
1514 
1515 /* Validate the NLA-Strips 'control' F-Curves based on the flags set*/
1517 {
1518  FCurve *fcu;
1519 
1520  /* sanity checks */
1521  if (strip == NULL) {
1522  return;
1523  }
1524 
1525  /* if controlling influence... */
1526  if (strip->flag & NLASTRIP_FLAG_USR_INFLUENCE) {
1527  /* try to get F-Curve */
1528  fcu = BKE_fcurve_find(&strip->fcurves, "influence", 0);
1529 
1530  /* add one if not found */
1531  if (fcu == NULL) {
1532  /* make new F-Curve */
1533  fcu = BKE_fcurve_create();
1534  BLI_addtail(&strip->fcurves, fcu);
1535 
1536  /* set default flags */
1537  fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
1538  fcu->auto_smoothing = U.auto_smoothing_new;
1539 
1540  /* store path - make copy, and store that */
1541  fcu->rna_path = BLI_strdupn("influence", 9);
1542 
1543  /* insert keyframe to ensure current value stays on first refresh */
1544  fcu->bezt = MEM_callocN(sizeof(BezTriple), "nlastrip influence bezt");
1545  fcu->totvert = 1;
1546 
1547  fcu->bezt->vec[1][0] = strip->start;
1548  fcu->bezt->vec[1][1] = strip->influence;
1549 
1550  /* Respect User Preferences for default interpolation and handles. */
1551  fcu->bezt->h1 = fcu->bezt->h2 = U.keyhandles_new;
1552  fcu->bezt->ipo = U.ipo_new;
1553  }
1554  }
1555 
1556  /* if controlling time... */
1557  if (strip->flag & NLASTRIP_FLAG_USR_TIME) {
1558  /* try to get F-Curve */
1559  fcu = BKE_fcurve_find(&strip->fcurves, "strip_time", 0);
1560 
1561  /* add one if not found */
1562  if (fcu == NULL) {
1563  /* make new F-Curve */
1564  fcu = BKE_fcurve_create();
1565  BLI_addtail(&strip->fcurves, fcu);
1566 
1567  /* set default flags */
1568  fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
1569  fcu->auto_smoothing = U.auto_smoothing_new;
1570 
1571  /* store path - make copy, and store that */
1572  fcu->rna_path = BLI_strdupn("strip_time", 10);
1573 
1574  /* TODO: insert a few keyframes to ensure default behavior? */
1575  }
1576  }
1577 }
1578 
1579 /* Check if the given RNA pointer + property combo should be handled by
1580  * NLA strip curves or not.
1581  */
1583 {
1584  /* sanity checks */
1585  if (ELEM(NULL, ptr, prop)) {
1586  return false;
1587  }
1588 
1589  /* 1) Must be NLA strip */
1590  if (ptr->type == &RNA_NlaStrip) {
1591  /* 2) Must be one of the predefined properties */
1592  static PropertyRNA *prop_influence = NULL;
1593  static PropertyRNA *prop_time = NULL;
1594  static bool needs_init = true;
1595 
1596  /* Init the properties on first use */
1597  if (needs_init) {
1598  prop_influence = RNA_struct_type_find_property(&RNA_NlaStrip, "influence");
1599  prop_time = RNA_struct_type_find_property(&RNA_NlaStrip, "strip_time");
1600 
1601  needs_init = false;
1602  }
1603 
1604  /* Check if match */
1605  if (ELEM(prop, prop_influence, prop_time)) {
1606  return true;
1607  }
1608  }
1609 
1610  /* No criteria met */
1611  return false;
1612 }
1613 
1614 /* Sanity Validation ------------------------------------ */
1615 
1616 static bool nla_editbone_name_check(void *arg, const char *name)
1617 {
1618  return BLI_ghash_haskey((GHash *)arg, (const void *)name);
1619 }
1620 
1621 /* Find (and set) a unique name for a strip from the whole AnimData block
1622  * Uses a similar method to the BLI method, but is implemented differently
1623  * as we need to ensure that the name is unique over several lists of tracks,
1624  * not just a single track.
1625  */
1627 {
1628  GHash *gh;
1629  NlaStrip *tstrip;
1630  NlaTrack *nlt;
1631 
1632  /* sanity checks */
1633  if (ELEM(NULL, adt, strip)) {
1634  return;
1635  }
1636 
1637  /* give strip a default name if none already */
1638  if (strip->name[0] == 0) {
1639  switch (strip->type) {
1640  case NLASTRIP_TYPE_CLIP: /* act-clip */
1641  BLI_strncpy(strip->name,
1642  (strip->act) ? (strip->act->id.name + 2) : ("<No Action>"),
1643  sizeof(strip->name));
1644  break;
1645  case NLASTRIP_TYPE_TRANSITION: /* transition */
1646  BLI_strncpy(strip->name, "Transition", sizeof(strip->name));
1647  break;
1648  case NLASTRIP_TYPE_META: /* meta */
1649  BLI_strncpy(strip->name, "Meta", sizeof(strip->name));
1650  break;
1651  default:
1652  BLI_strncpy(strip->name, "NLA Strip", sizeof(strip->name));
1653  break;
1654  }
1655  }
1656 
1657  /* build a hash-table of all the strips in the tracks
1658  * - this is easier than iterating over all the tracks+strips hierarchy every time
1659  * (and probably faster)
1660  */
1661  gh = BLI_ghash_str_new("nlastrip_validate_name gh");
1662 
1663  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
1664  for (tstrip = nlt->strips.first; tstrip; tstrip = tstrip->next) {
1665  /* don't add the strip of interest */
1666  if (tstrip == strip) {
1667  continue;
1668  }
1669 
1670  /* Use the name of the strip as the key, and the strip as the value,
1671  * since we're mostly interested in the keys. */
1672  BLI_ghash_insert(gh, tstrip->name, tstrip);
1673  }
1674  }
1675 
1676  /* If the hash-table has a match for this name, try other names...
1677  * - In an extreme case, it might not be able to find a name,
1678  * but then everything else in Blender would fail too :).
1679  */
1681  (void *)gh,
1682  DATA_("NlaStrip"),
1683  '.',
1684  strip->name,
1685  sizeof(strip->name));
1686 
1687  /* free the hash... */
1688  BLI_ghash_free(gh, NULL, NULL);
1689 }
1690 
1691 /* ---- */
1692 
1693 /* Get strips which overlap the given one at the start/end of its range
1694  * - strip: strip that we're finding overlaps for
1695  * - track: nla-track that the overlapping strips should be found from
1696  * - start, end: frames for the offending endpoints
1697  */
1699  NlaTrack *track,
1700  float **start,
1701  float **end)
1702 {
1703  NlaStrip *nls;
1704 
1705  /* find strips that overlap over the start/end of the given strip,
1706  * but which don't cover the entire length
1707  */
1708  /* TODO: this scheme could get quite slow for doing this on many strips... */
1709  for (nls = track->strips.first; nls; nls = nls->next) {
1710  /* Check if strip overlaps (extends over or exactly on)
1711  * the entire range of the strip we're validating. */
1712  if ((nls->start <= strip->start) && (nls->end >= strip->end)) {
1713  *start = NULL;
1714  *end = NULL;
1715  return;
1716  }
1717 
1718  /* check if strip doesn't even occur anywhere near... */
1719  if (nls->end < strip->start) {
1720  continue; /* skip checking this strip... not worthy of mention */
1721  }
1722  if (nls->start > strip->end) {
1723  return; /* the range we're after has already passed */
1724  }
1725 
1726  /* if this strip is not part of an island of continuous strips, it can be used
1727  * - this check needs to be done for each end of the strip we try and use...
1728  */
1729  if ((nls->next == NULL) || IS_EQF(nls->next->start, nls->end) == 0) {
1730  if ((nls->end > strip->start) && (nls->end < strip->end)) {
1731  *start = &nls->end;
1732  }
1733  }
1734  if ((nls->prev == NULL) || IS_EQF(nls->prev->end, nls->start) == 0) {
1735  if ((nls->start < strip->end) && (nls->start > strip->start)) {
1736  *end = &nls->start;
1737  }
1738  }
1739  }
1740 }
1741 
1742 /* Determine auto-blending for the given strip */
1744 {
1745  float *ps = NULL, *pe = NULL;
1746  float *ns = NULL, *ne = NULL;
1747 
1748  /* sanity checks */
1749  if (ELEM(NULL, nls, nlt)) {
1750  return;
1751  }
1752  if ((nlt->prev == NULL) && (nlt->next == NULL)) {
1753  return;
1754  }
1755  if ((nls->flag & NLASTRIP_FLAG_AUTO_BLENDS) == 0) {
1756  return;
1757  }
1758 
1759  /* get test ranges */
1760  if (nlt->prev) {
1761  nlastrip_get_endpoint_overlaps(nls, nlt->prev, &ps, &pe);
1762  }
1763  if (nlt->next) {
1764  nlastrip_get_endpoint_overlaps(nls, nlt->next, &ns, &ne);
1765  }
1766 
1767  /* set overlaps for this strip
1768  * - don't use the values obtained though if the end in question
1769  * is directly followed/preceded by another strip, forming an
1770  * 'island' of continuous strips
1771  */
1772  if ((ps || ns) && ((nls->prev == NULL) || IS_EQF(nls->prev->end, nls->start) == 0)) {
1773  /* start overlaps - pick the largest overlap */
1774  if (((ps && ns) && (*ps > *ns)) || (ps)) {
1775  nls->blendin = *ps - nls->start;
1776  }
1777  else {
1778  nls->blendin = *ns - nls->start;
1779  }
1780  }
1781  else { /* no overlap allowed/needed */
1782  nls->blendin = 0.0f;
1783  }
1784 
1785  if ((pe || ne) && ((nls->next == NULL) || IS_EQF(nls->next->start, nls->end) == 0)) {
1786  /* end overlaps - pick the largest overlap */
1787  if (((pe && ne) && (*pe > *ne)) || (pe)) {
1788  nls->blendout = nls->end - *pe;
1789  }
1790  else {
1791  nls->blendout = nls->end - *ne;
1792  }
1793  }
1794  else { /* no overlap allowed/needed */
1795  nls->blendout = 0.0f;
1796  }
1797 }
1798 
1799 /* Ensure that auto-blending and other settings are set correctly */
1801 {
1802  NlaStrip *strip, *fstrip = NULL;
1803  NlaTrack *nlt;
1804 
1805  /* sanity checks */
1806  if (ELEM(NULL, adt, adt->nla_tracks.first)) {
1807  return;
1808  }
1809 
1810  /* Adjust blending values for auto-blending,
1811  * and also do an initial pass to find the earliest strip. */
1812  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
1813  for (strip = nlt->strips.first; strip; strip = strip->next) {
1814  /* auto-blending first */
1816 
1817  /* extend mode - find first strip */
1818  if ((fstrip == NULL) || (strip->start < fstrip->start)) {
1819  fstrip = strip;
1820  }
1821  }
1822  }
1823 
1824  /* second pass over the strips to adjust the extend-mode to fix any problems */
1825  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
1826  for (strip = nlt->strips.first; strip; strip = strip->next) {
1827  /* apart from 'nothing' option which user has to explicitly choose, we don't really know if
1828  * we should be overwriting the extend setting (but assume that's what the user wanted)
1829  */
1830  /* TODO: 1 solution is to tie this in with auto-blending... */
1831  if (strip->extendmode != NLASTRIP_EXTEND_NOTHING) {
1832  /* 1) First strip must be set to extend hold, otherwise, stuff before acts dodgy
1833  * 2) Only overwrite extend mode if *not* changing it will most probably result in
1834  * occlusion problems, which will occur if...
1835  * - blendmode = REPLACE
1836  * - all channels the same (this is fiddly to test, so is currently assumed)
1837  *
1838  * Should fix problems such as T29869.
1839  */
1840  if (strip == fstrip) {
1842  }
1843  else if (strip->blendmode == NLASTRIP_MODE_REPLACE) {
1845  }
1846  }
1847  }
1848  }
1849 }
1850 
1851 /* Action Stashing -------------------------------------- */
1852 
1853 /* name of stashed tracks - the translation stuff is included here to save extra work */
1854 #define STASH_TRACK_NAME DATA_("[Action Stash]")
1855 
1856 /* Check if an action is "stashed" in the NLA already
1857  *
1858  * The criteria for this are:
1859  * 1) The action in question lives in a "stash" track
1860  * 2) We only check first-level strips. That is, we will not check inside meta strips.
1861  */
1863 {
1864  NlaTrack *nlt;
1865  NlaStrip *strip;
1866 
1867  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
1868  if (strstr(nlt->name, STASH_TRACK_NAME)) {
1869  for (strip = nlt->strips.first; strip; strip = strip->next) {
1870  if (strip->act == act) {
1871  return true;
1872  }
1873  }
1874  }
1875  }
1876 
1877  return false;
1878 }
1879 
1880 /* "Stash" an action (i.e. store it as a track/layer in the NLA, but non-contributing)
1881  * to retain it in the file for future uses
1882  */
1883 bool BKE_nla_action_stash(AnimData *adt, const bool is_liboverride)
1884 {
1885  NlaTrack *prev_track = NULL;
1886  NlaTrack *nlt;
1887  NlaStrip *strip;
1888 
1889  /* sanity check */
1890  if (ELEM(NULL, adt, adt->action)) {
1891  CLOG_ERROR(&LOG, "Invalid argument - %p %p", adt, adt->action);
1892  return false;
1893  }
1894 
1895  /* do not add if it is already stashed */
1896  if (BKE_nla_action_is_stashed(adt, adt->action)) {
1897  return false;
1898  }
1899 
1900  /* create a new track, and add this immediately above the previous stashing track */
1901  for (prev_track = adt->nla_tracks.last; prev_track; prev_track = prev_track->prev) {
1902  if (strstr(prev_track->name, STASH_TRACK_NAME)) {
1903  break;
1904  }
1905  }
1906 
1907  nlt = BKE_nlatrack_add(adt, prev_track, is_liboverride);
1908  BLI_assert(nlt != NULL);
1909 
1910  /* We need to ensure that if there wasn't any previous instance,
1911  * it must go to be bottom of the stack. */
1912  if (prev_track == NULL) {
1913  BLI_remlink(&adt->nla_tracks, nlt);
1914  BLI_addhead(&adt->nla_tracks, nlt);
1915  }
1916 
1917  BLI_strncpy(nlt->name, STASH_TRACK_NAME, sizeof(nlt->name));
1919  &adt->nla_tracks, nlt, STASH_TRACK_NAME, '.', offsetof(NlaTrack, name), sizeof(nlt->name));
1920 
1921  /* add the action as a strip in this new track
1922  * NOTE: a new user is created here
1923  */
1924  strip = BKE_nlastrip_new(adt->action);
1925  BLI_assert(strip != NULL);
1926 
1927  BKE_nlatrack_add_strip(nlt, strip, is_liboverride);
1928  BKE_nlastrip_validate_name(adt, strip);
1929 
1930  /* mark the stash track and strip so that they doesn't disturb the stack animation,
1931  * and are unlikely to draw attention to itself (or be accidentally bumped around)
1932  *
1933  * NOTE: this must be done *after* adding the strip to the track, or else
1934  * the strip locking will prevent the strip from getting added
1935  */
1938 
1939  /* also mark the strip for auto syncing the length, so that the strips accurately
1940  * reflect the length of the action
1941  * XXX: we could do with some extra flags here to prevent repeats/scaling options from working!
1942  */
1943  strip->flag |= NLASTRIP_FLAG_SYNC_LENGTH;
1944 
1945  /* succeeded */
1946  return true;
1947 }
1948 
1949 /* Core Tools ------------------------------------------- */
1950 
1951 /* For the given AnimData block, add the active action to the NLA
1952  * stack (i.e. 'push-down' action). The UI should only allow this
1953  * for normal editing only (i.e. not in editmode for some strip's action),
1954  * so no checks for this are performed.
1955  */
1956 /* TODO: maybe we should have checks for this too... */
1957 void BKE_nla_action_pushdown(AnimData *adt, const bool is_liboverride)
1958 {
1959  NlaStrip *strip;
1960  const bool is_first = (adt) && (adt->nla_tracks.first == NULL);
1961 
1962  /* sanity checks */
1963  /* TODO: need to report the error for this */
1964  if (ELEM(NULL, adt, adt->action)) {
1965  return;
1966  }
1967 
1968  /* if the action is empty, we also shouldn't try to add to stack,
1969  * as that will cause us grief down the track
1970  */
1971  /* TODO: what about modifiers? */
1972  if (action_has_motion(adt->action) == 0) {
1973  CLOG_ERROR(&LOG, "action has no data");
1974  return;
1975  }
1976 
1977  /* add a new NLA strip to the track, which references the active action */
1978  strip = BKE_nlastack_add_strip(adt, adt->action, is_liboverride);
1979  if (strip == NULL) {
1980  return;
1981  }
1982 
1983  /* clear reference to action now that we've pushed it onto the stack */
1984  id_us_min(&adt->action->id);
1985  adt->action = NULL;
1986 
1987  /* copy current "action blending" settings from adt to the strip,
1988  * as it was keyframed with these settings, so omitting them will
1989  * change the effect [T54233]
1990  *
1991  * NOTE: We only do this when there are no tracks
1992  */
1993  if (is_first == false) {
1994  strip->blendmode = adt->act_blendmode;
1995  strip->influence = adt->act_influence;
1996  strip->extendmode = adt->act_extendmode;
1997 
1998  if (adt->act_influence < 1.0f) {
1999  /* enable "user-controlled" influence (which will insert a default keyframe)
2000  * so that the influence doesn't get lost on the new update
2001  *
2002  * NOTE: An alternative way would have been to instead hack the influence
2003  * to not get always get reset to full strength if NLASTRIP_FLAG_USR_INFLUENCE
2004  * is disabled but auto-blending isn't being used. However, that approach
2005  * is a bit hacky/hard to discover, and may cause backwards compatibility issues,
2006  * so it's better to just do it this way.
2007  */
2010  }
2011  }
2012 
2013  /* if the strip is the first one in the track it lives in, check if there
2014  * are strips in any other tracks that may be before this, and set the extend
2015  * mode accordingly
2016  */
2017  if (nlastrip_is_first(adt, strip) == 0) {
2018  /* Not first, so extend mode can only be:
2019  * NLASTRIP_EXTEND_HOLD_FORWARD not NLASTRIP_EXTEND_HOLD,
2020  * so that it doesn't override strips in previous tracks. */
2021  /* FIXME: this needs to be more automated, since user can rearrange strips */
2022  if (strip->extendmode == NLASTRIP_EXTEND_HOLD) {
2024  }
2025  }
2026 
2027  /* make strip the active one... */
2028  BKE_nlastrip_set_active(adt, strip);
2029 }
2030 
2031 /* Find the active strip + track combo, and set them up as the tweaking track,
2032  * and return if successful or not.
2033  */
2035 {
2036  NlaTrack *nlt, *activeTrack = NULL;
2037  NlaStrip *strip, *activeStrip = NULL;
2038 
2039  /* verify that data is valid */
2040  if (ELEM(NULL, adt, adt->nla_tracks.first)) {
2041  return false;
2042  }
2043 
2044  /* if block is already in tweakmode, just leave, but we should report
2045  * that this block is in tweakmode (as our returncode)
2046  */
2047  if (adt->flag & ADT_NLA_EDIT_ON) {
2048  return true;
2049  }
2050 
2051  /* go over the tracks, finding the active one, and its active strip
2052  * - if we cannot find both, then there's nothing to do
2053  */
2054  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
2055  /* check if active */
2056  if (nlt->flag & NLATRACK_ACTIVE) {
2057  /* store reference to this active track */
2058  activeTrack = nlt;
2059 
2060  /* now try to find active strip */
2061  activeStrip = BKE_nlastrip_find_active(nlt);
2062  break;
2063  }
2064  }
2065 
2066  /* There are situations where we may have multiple strips selected and we want to enter tweakmode
2067  * on all of those at once. Usually in those cases,
2068  * it will usually just be a single strip per AnimData.
2069  * In such cases, compromise and take the last selected track and/or last selected strip, T28468.
2070  */
2071  if (activeTrack == NULL) {
2072  /* try last selected track for active strip */
2073  for (nlt = adt->nla_tracks.last; nlt; nlt = nlt->prev) {
2074  if (nlt->flag & NLATRACK_SELECTED) {
2075  /* assume this is the active track */
2076  activeTrack = nlt;
2077 
2078  /* try to find active strip */
2079  activeStrip = BKE_nlastrip_find_active(nlt);
2080  break;
2081  }
2082  }
2083  }
2084  if ((activeTrack) && (activeStrip == NULL)) {
2085  /* No active strip in active or last selected track;
2086  * compromise for first selected (assuming only single). */
2087  for (strip = activeTrack->strips.first; strip; strip = strip->next) {
2088  if (strip->flag & (NLASTRIP_FLAG_SELECT | NLASTRIP_FLAG_ACTIVE)) {
2089  activeStrip = strip;
2090  break;
2091  }
2092  }
2093  }
2094 
2095  if (ELEM(NULL, activeTrack, activeStrip, activeStrip->act)) {
2096  if (G.debug & G_DEBUG) {
2097  printf("NLA tweakmode enter - neither active requirement found\n");
2098  printf("\tactiveTrack = %p, activeStrip = %p\n", (void *)activeTrack, (void *)activeStrip);
2099  }
2100  return false;
2101  }
2102 
2103  /* Go over all the tracks, tagging each strip that uses the same
2104  * action as the active strip, but leaving everything else alone.
2105  */
2106  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
2107  for (strip = nlt->strips.first; strip; strip = strip->next) {
2108  if (strip->act == activeStrip->act) {
2109  strip->flag |= NLASTRIP_FLAG_TWEAKUSER;
2110  }
2111  else {
2112  strip->flag &= ~NLASTRIP_FLAG_TWEAKUSER;
2113  }
2114  }
2115  }
2116 
2117  /* Untag tweaked track. This leads to non tweaked actions being drawn differently than the
2118  * tweaked action. */
2119  activeStrip->flag &= ~NLASTRIP_FLAG_TWEAKUSER;
2120 
2121  /* go over all the tracks after AND INCLUDING the active one, tagging them as being disabled
2122  * - the active track needs to also be tagged, otherwise, it'll overlap with the tweaks going on
2123  */
2124  for (nlt = activeTrack; nlt; nlt = nlt->next) {
2125  nlt->flag |= NLATRACK_DISABLED;
2126  }
2127 
2128  /* handle AnimData level changes:
2129  * - 'real' active action to temp storage (no need to change user-counts).
2130  * - Action of active strip set to be the 'active action', and have its usercount incremented.
2131  * - Editing-flag for this AnimData block should also get turned on
2132  * (for more efficient restoring).
2133  * - Take note of the active strip for mapping-correction of keyframes
2134  * in the action being edited.
2135  */
2136  adt->tmpact = adt->action;
2137  adt->action = activeStrip->act;
2138  adt->act_track = activeTrack;
2139  adt->actstrip = activeStrip;
2140  id_us_plus(&activeStrip->act->id);
2141  adt->flag |= ADT_NLA_EDIT_ON;
2142 
2143  /* done! */
2144  return true;
2145 }
2146 
2147 /* Exit tweakmode for this AnimData block */
2149 {
2150  NlaStrip *strip;
2151  NlaTrack *nlt;
2152 
2153  /* verify that data is valid */
2154  if (ELEM(NULL, adt, adt->nla_tracks.first)) {
2155  return;
2156  }
2157 
2158  /* hopefully the flag is correct - skip if not on */
2159  if ((adt->flag & ADT_NLA_EDIT_ON) == 0) {
2160  return;
2161  }
2162 
2163  /* sync the length of the user-strip with the new state of the action
2164  * but only if the user has explicitly asked for this to happen
2165  * (see T34645 for things to be careful about)
2166  */
2167  if ((adt->actstrip) && (adt->actstrip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) {
2168  strip = adt->actstrip;
2169 
2170  /* must be action-clip only (transitions don't have scale) */
2171  if ((strip->type == NLASTRIP_TYPE_CLIP) && (strip->act)) {
2173  }
2174  }
2175 
2176  /* for all Tracks, clear the 'disabled' flag
2177  * for all Strips, clear the 'tweak-user' flag
2178  */
2179  for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
2180  nlt->flag &= ~NLATRACK_DISABLED;
2181 
2182  for (strip = nlt->strips.first; strip; strip = strip->next) {
2183  /* sync strip extents if this strip uses the same action */
2184  if ((adt->actstrip) && (adt->actstrip->act == strip->act) &&
2185  (strip->flag & NLASTRIP_FLAG_SYNC_LENGTH)) {
2187  }
2188 
2189  /* clear tweakuser flag */
2190  strip->flag &= ~NLASTRIP_FLAG_TWEAKUSER;
2191  }
2192  }
2193 
2194  /* handle AnimData level changes:
2195  * - 'temporary' active action needs its usercount decreased, since we're removing this reference
2196  * - 'real' active action is restored from storage
2197  * - storage pointer gets cleared (to avoid having bad notes hanging around)
2198  * - editing-flag for this AnimData block should also get turned off
2199  * - clear pointer to active strip
2200  */
2201  if (adt->action) {
2202  id_us_min(&adt->action->id);
2203  }
2204  adt->action = adt->tmpact;
2205  adt->tmpact = NULL;
2206  adt->act_track = NULL;
2207  adt->actstrip = NULL;
2208  adt->flag &= ~ADT_NLA_EDIT_ON;
2209 }
2210 
2211 static void blend_write_nla_strips(BlendWriter *writer, ListBase *strips)
2212 {
2213  BLO_write_struct_list(writer, NlaStrip, strips);
2214  LISTBASE_FOREACH (NlaStrip *, strip, strips) {
2215  /* write the strip's F-Curves and modifiers */
2216  BKE_fcurve_blend_write(writer, &strip->fcurves);
2217  BKE_fmodifiers_blend_write(writer, &strip->modifiers);
2218 
2219  /* write the strip's children */
2220  blend_write_nla_strips(writer, &strip->strips);
2221  }
2222 }
2223 
2225 {
2226  LISTBASE_FOREACH (NlaStrip *, strip, strips) {
2227  /* strip's child strips */
2228  BLO_read_list(reader, &strip->strips);
2229  blend_data_read_nla_strips(reader, &strip->strips);
2230 
2231  /* strip's F-Curves */
2232  BLO_read_list(reader, &strip->fcurves);
2233  BKE_fcurve_blend_read_data(reader, &strip->fcurves);
2234 
2235  /* strip's F-Modifiers */
2236  BLO_read_list(reader, &strip->modifiers);
2237  BKE_fmodifiers_blend_read_data(reader, &strip->modifiers, NULL);
2238  }
2239 }
2240 
2241 static void blend_lib_read_nla_strips(BlendLibReader *reader, ID *id, ListBase *strips)
2242 {
2243  LISTBASE_FOREACH (NlaStrip *, strip, strips) {
2244  /* check strip's children */
2245  blend_lib_read_nla_strips(reader, id, &strip->strips);
2246 
2247  /* check strip's F-Curves */
2248  BKE_fcurve_blend_read_lib(reader, id, &strip->fcurves);
2249 
2250  /* reassign the counted-reference to action */
2251  BLO_read_id_address(reader, id->lib, &strip->act);
2252  }
2253 }
2254 
2255 static void blend_read_expand_nla_strips(BlendExpander *expander, ListBase *strips)
2256 {
2257  LISTBASE_FOREACH (NlaStrip *, strip, strips) {
2258  /* check child strips */
2259  blend_read_expand_nla_strips(expander, &strip->strips);
2260 
2261  /* check F-Curves */
2262  BKE_fcurve_blend_read_expand(expander, &strip->fcurves);
2263 
2264  /* check F-Modifiers */
2265  BKE_fmodifiers_blend_read_expand(expander, &strip->modifiers);
2266 
2267  /* relink referenced action */
2268  BLO_expand(expander, strip->act);
2269  }
2270 }
2271 
2273 {
2274  /* write all the tracks */
2275  LISTBASE_FOREACH (NlaTrack *, nlt, tracks) {
2276  /* write the track first */
2277  BLO_write_struct(writer, NlaTrack, nlt);
2278 
2279  /* write the track's strips */
2280  blend_write_nla_strips(writer, &nlt->strips);
2281  }
2282 }
2283 
2285 {
2286  LISTBASE_FOREACH (NlaTrack *, nlt, tracks) {
2287  /* relink list of strips */
2288  BLO_read_list(reader, &nlt->strips);
2289 
2290  /* relink strip data */
2291  blend_data_read_nla_strips(reader, &nlt->strips);
2292  }
2293 }
2294 
2296 {
2297  /* we only care about the NLA strips inside the tracks */
2298  LISTBASE_FOREACH (NlaTrack *, nlt, tracks) {
2299  /* If linking from a library, clear 'local' library override flag. */
2300  if (id->lib != NULL) {
2301  nlt->flag &= ~NLATRACK_OVERRIDELIBRARY_LOCAL;
2302  }
2303 
2304  blend_lib_read_nla_strips(reader, id, &nlt->strips);
2305  }
2306 }
2307 
2309 {
2310  /* nla-data - referenced actions */
2311  LISTBASE_FOREACH (NlaTrack *, nlt, tracks) {
2312  blend_read_expand_nla_strips(expander, &nlt->strips);
2313  }
2314 }
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
void calc_action_range(const struct bAction *act, float *start, float *end, short incl_modifiers)
bool action_has_motion(const struct bAction *act)
void copy_fmodifiers(ListBase *dst, const ListBase *src)
Definition: fmodifier.c:1197
void BKE_fcurve_blend_write(struct BlendWriter *writer, struct ListBase *fcurves)
Definition: fcurve.c:2397
void BKE_fmodifiers_blend_read_data(struct BlendDataReader *reader, ListBase *fmodifiers, struct FCurve *curve)
Definition: fcurve.c:2336
void BKE_fcurve_blend_read_data(struct BlendDataReader *reader, struct ListBase *fcurves)
Definition: fcurve.c:2436
void BKE_fcurve_foreach_id(struct FCurve *fcu, struct LibraryForeachIDData *data)
Definition: fcurve.c:188
void BKE_fmodifiers_blend_write(struct BlendWriter *writer, struct ListBase *fmodifiers)
Definition: fcurve.c:2286
void BKE_fcurve_blend_read_lib(struct BlendLibReader *reader, struct ID *id, struct ListBase *fcurves)
Definition: fcurve.c:2491
struct FCurve * BKE_fcurve_find(ListBase *list, const char rna_path[], const int array_index)
Definition: fcurve.c:274
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
struct FCurve * BKE_fcurve_create(void)
Definition: fcurve.c:68
void free_fmodifiers(ListBase *modifiers)
Definition: fmodifier.c:1269
void BKE_fmodifiers_blend_read_expand(struct BlendExpander *expander, struct ListBase *fmodifiers)
Definition: fcurve.c:2383
@ G_DEBUG
Definition: BKE_global.h:133
void id_us_min(struct ID *id)
Definition: lib_id.c:297
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:92
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
@ NLATIME_CONVERT_MAP
Definition: BKE_nla.h:156
@ NLATIME_CONVERT_UNMAP
Definition: BKE_nla.h:153
bool BKE_sound_info_get(struct Main *main, struct bSound *sound, SoundInfo *sound_info)
#define BLI_assert(a)
Definition: BLI_assert.h:58
GHash * BLI_ghash_str_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_haskey(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:941
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:87
#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
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:352
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
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:395
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
char * BLI_strdupn(const char *str, const size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:54
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
bool BLI_uniquename_cb(UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_len)
Definition: string_utils.c:294
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t len)
Definition: string_utils.c:381
#define UNUSED_VARS(...)
#define SWAP(type, a, b)
#define IN_RANGE(a, b, c)
#define ELEM(...)
#define IS_EQF(a, b)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5654
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define BLO_expand(expander, id)
#define BLO_write_struct_list(writer, struct_name, list_ptr)
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:204
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:445
@ NLASTRIP_FLAG_ACTIVE
@ NLASTRIP_FLAG_USR_INFLUENCE
@ NLASTRIP_FLAG_USR_TIME
@ NLASTRIP_FLAG_TEMP_META
@ NLASTRIP_FLAG_AUTO_BLENDS
@ NLASTRIP_FLAG_REVERSE
@ NLASTRIP_FLAG_SELECT
@ NLASTRIP_FLAG_TWEAKUSER
@ NLASTRIP_FLAG_SYNC_LENGTH
@ ADT_NLA_SOLO_TRACK
@ ADT_NLA_EDIT_NOMAP
@ ADT_NLA_EDIT_ON
@ NLASTRIP_EXTEND_HOLD_FORWARD
@ NLASTRIP_EXTEND_NOTHING
@ NLASTRIP_EXTEND_HOLD
@ NLASTRIP_MODE_REPLACE
@ NLASTRIP_TYPE_SOUND
@ NLASTRIP_TYPE_META
@ NLASTRIP_TYPE_TRANSITION
@ NLASTRIP_TYPE_CLIP
@ FCURVE_SELECTED
@ FCURVE_VISIBLE
@ NLATRACK_SOLO
@ NLATRACK_ACTIVE
@ NLATRACK_MUTED
@ NLATRACK_DISABLED
@ NLATRACK_SELECTED
@ NLATRACK_PROTECTED
@ NLATRACK_OVERRIDELIBRARY_LOCAL
#define FPS
Read Guarded memory(de)allocation.
StructRNA RNA_NlaStrip
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:299
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
Scene scene
#define ceilf(x)
#define fmodf(x, y)
#define floorf(x)
#define fabsf(x)
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
float nlastrip_get_frame(NlaStrip *strip, float cframe, short mode)
Definition: nla.c:562
float BKE_nla_tweakedit_remap(AnimData *adt, float cframe, short mode)
Definition: nla.c:582
bool BKE_nlatrack_get_bounds(NlaTrack *nlt, float bounds[2])
Definition: nla.c:1169
static void blend_write_nla_strips(BlendWriter *writer, ListBase *strips)
Definition: nla.c:2211
void BKE_nla_action_pushdown(AnimData *adt, const bool is_liboverride)
Definition: nla.c:1957
bool BKE_nla_tweakmode_enter(AnimData *adt)
Definition: nla.c:2034
void BKE_nlameta_flush_transforms(NlaStrip *mstrip)
Definition: nla.c:912
bool BKE_nlatrack_has_animated_strips(NlaTrack *nlt)
Definition: nla.c:1474
NlaTrack * BKE_nlatrack_find_tweaked(AnimData *adt)
Definition: nla.c:1020
static void blend_lib_read_nla_strips(BlendLibReader *reader, ID *id, ListBase *strips)
Definition: nla.c:2241
void BKE_nlastrips_clear_metastrip(ListBase *strips, NlaStrip *strip)
Definition: nla.c:807
void BKE_nla_blend_read_lib(BlendLibReader *reader, ID *id, ListBase *tracks)
Definition: nla.c:2295
NlaStrip * BKE_nlastrip_new(bAction *act)
Definition: nla.c:327
void BKE_nlastrip_recalculate_bounds_sync_action(NlaStrip *strip)
Definition: nla.c:1389
static float nlastrip_get_frame_actionclip(NlaStrip *strip, float cframe, short mode)
Definition: nla.c:462
void BKE_nlastrip_free(ListBase *strips, NlaStrip *strip, bool do_id_user)
Definition: nla.c:72
void BKE_nlastrips_sort_strips(ListBase *strips)
Definition: nla.c:668
void BKE_nlastrips_clear_metas(ListBase *strips, bool only_sel, bool only_temp)
Definition: nla.c:833
void BKE_nla_tracks_copy(Main *bmain, ListBase *dst, ListBase *src, const int flag)
Definition: nla.c:257
static void nlastrip_get_endpoint_overlaps(NlaStrip *strip, NlaTrack *track, float **start, float **end)
Definition: nla.c:1698
NlaStrip * BKE_nlastack_add_strip(AnimData *adt, bAction *act, const bool is_liboverride)
Definition: nla.c:368
void BKE_nla_validate_state(AnimData *adt)
Definition: nla.c:1800
void BKE_nlatrack_solo_toggle(AnimData *adt, NlaTrack *nlt)
Definition: nla.c:1054
static float nlastrip_get_frame_transition(NlaStrip *strip, float cframe, short mode)
Definition: nla.c:533
void BKE_nlatrack_free(ListBase *tracks, NlaTrack *nlt, bool do_id_user)
Definition: nla.c:114
static void blend_data_read_nla_strips(BlendDataReader *reader, ListBase *strips)
Definition: nla.c:2224
void BKE_nlastrip_recalculate_bounds(NlaStrip *strip)
Definition: nla.c:1409
bool BKE_nlastrips_has_space(ListBase *strips, float start, float end)
Definition: nla.c:631
bool BKE_nla_action_stash(AnimData *adt, const bool is_liboverride)
Definition: nla.c:1883
bool BKE_nlastrips_add_strip(ListBase *strips, NlaStrip *strip)
Definition: nla.c:714
bool BKE_nlastrip_has_curves_for_property(const PointerRNA *ptr, const PropertyRNA *prop)
Definition: nla.c:1582
NlaStrip * BKE_nla_add_soundstrip(Main *bmain, Scene *scene, Speaker *speaker)
Definition: nla.c:401
void BKE_nlastrip_set_active(AnimData *adt, NlaStrip *strip)
Definition: nla.c:1234
#define STASH_TRACK_NAME
Definition: nla.c:1854
static bool nlastrip_is_first(AnimData *adt, NlaStrip *strip)
Definition: nla.c:1440
void BKE_nla_blend_write(BlendWriter *writer, ListBase *tracks)
Definition: nla.c:2272
void BKE_nla_tracks_free(ListBase *tracks, bool do_id_user)
Definition: nla.c:141
NlaStrip * BKE_nlastrip_copy(Main *bmain, NlaStrip *strip, const bool use_same_action, const int flag)
Definition: nla.c:169
bool BKE_nlatrack_has_space(NlaTrack *nlt, float start, float end)
Definition: nla.c:1112
void BKE_nlatrack_sort_strips(NlaTrack *nlt)
Definition: nla.c:1135
static void BKE_nlastrip_validate_autoblends(NlaTrack *nlt, NlaStrip *nls)
Definition: nla.c:1743
void BKE_nlatrack_set_active(ListBase *tracks, NlaTrack *nlt_a)
Definition: nla.c:1091
static void nlastrip_fix_resize_overlaps(NlaStrip *strip)
Definition: nla.c:1287
bool BKE_nlatrack_is_nonlocal_in_liboverride(const ID *id, const NlaTrack *nlt)
Definition: nla.c:1204
bool BKE_nlastrip_within_bounds(NlaStrip *strip, float min, float max)
Definition: nla.c:1258
static CLG_LogRef LOG
Definition: nla.c:62
bool BKE_nlatrack_add_strip(NlaTrack *nlt, NlaStrip *strip, const bool is_liboverride)
Definition: nla.c:1149
static void blend_read_expand_nla_strips(BlendExpander *expander, ListBase *strips)
Definition: nla.c:2255
void BKE_nlastrip_validate_name(AnimData *adt, NlaStrip *strip)
Definition: nla.c:1626
bool BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
Definition: nla.c:861
NlaTrack * BKE_nlatrack_add(AnimData *adt, NlaTrack *prev, const bool is_liboverride)
Definition: nla.c:283
bool BKE_nlatracks_have_animated_strips(ListBase *tracks)
Definition: nla.c:1495
NlaTrack * BKE_nlatrack_find_active(ListBase *tracks)
Definition: nla.c:995
static bool nla_editbone_name_check(void *arg, const char *name)
Definition: nla.c:1616
NlaStrip * BKE_nlastrip_find_active(NlaTrack *nlt)
Definition: nla.c:1213
NlaTrack * BKE_nlatrack_copy(Main *bmain, NlaTrack *nlt, const bool use_same_actions, const int flag)
Definition: nla.c:223
void BKE_nlastrip_validate_fcurves(NlaStrip *strip)
Definition: nla.c:1516
void BKE_nla_tweakmode_exit(AnimData *adt)
Definition: nla.c:2148
bool BKE_nla_action_is_stashed(AnimData *adt, bAction *act)
Definition: nla.c:1862
void BKE_nla_blend_read_expand(struct BlendExpander *expander, struct ListBase *tracks)
Definition: nla.c:2308
void BKE_nla_strip_foreach_id(NlaStrip *strip, LibraryForeachIDData *data)
Definition: nla.c:441
void BKE_nlastrips_make_metas(ListBase *strips, bool is_temp)
Definition: nla.c:753
void BKE_nla_blend_read_data(BlendDataReader *reader, ListBase *tracks)
Definition: nla.c:2284
void RNA_pointer_create(ID *id, StructRNA *type, void *data, PointerRNA *r_ptr)
Definition: rna_access.c:146
PropertyRNA * RNA_struct_type_find_property(StructRNA *srna, const char *identifier)
Definition: rna_access.c:953
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
Definition: rna_access.c:6366
#define min(a, b)
Definition: sort.c:51
bAction * action
short act_blendmode
NlaStrip * actstrip
float act_influence
NlaTrack * act_track
bAction * tmpact
short act_extendmode
ListBase nla_tracks
float vec[3][3]
char * rna_path
BezTriple * bezt
short flag
unsigned int totvert
char auto_smoothing
Definition: DNA_ID.h:273
struct Library * lib
Definition: DNA_ID.h:277
char name[66]
Definition: DNA_ID.h:283
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
float actstart
struct NlaStrip * next
short blendmode
float blendout
ListBase fcurves
char name[64]
float influence
ListBase strips
float actend
ListBase modifiers
float repeat
struct NlaStrip * prev
float blendin
short extendmode
bAction * act
ListBase strips
struct NlaTrack * next
char name[64]
struct NlaTrack * prev
struct StructRNA * type
Definition: RNA_types.h:51
float length
Definition: BKE_sound.h:99
struct bSound * sound
ListBase tracks
Definition: tracking.c:75
float max
ccl_device_inline float3 ceil(const float3 &a)
#define G(x, y, z)
PointerRNA * ptr
Definition: wm_files.c:3157