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