diff options
author | Joshua Leung <aligorith@gmail.com> | 2011-03-29 13:37:53 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2011-03-29 13:37:53 +0400 |
commit | dbd13d67b1aa03a08d02e686d0d2b542d38abb50 (patch) | |
tree | fb6ad248af878de3566e803a18fa5124fddf5636 /source | |
parent | 0f7f20325752d2e2ec7dd07c8545ca9d685b7e49 (diff) |
Bugfix [#26645] Crash when duplicating an object with driver
Missing null check for "improper" driver variables.
------
Also, this commit includes some WIP NLA evaluation reshuffling which
should be harmless. I had originally intended this for a later
commit...
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 6e933ddd386..1c6221eba8b 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -282,23 +282,31 @@ void BKE_animdata_make_local(AnimData *adt) make_local_strips(&nlt->strips); } -void BKE_relink_animdata(struct AnimData *adt) + +/* When duplicating data (i.e. objects), drivers referring to the original data will + * get updated to point to the duplicated data (if drivers belong to the new data) + */ +void BKE_relink_animdata (AnimData *adt) { + /* sanity check */ + if (adt == NULL) + return; + /* drivers */ if (adt->drivers.first) { FCurve *fcu; - + /* check each driver against all the base paths to see if any should go */ for (fcu= adt->drivers.first; fcu; fcu=fcu->next) { ChannelDriver *driver= fcu->driver; DriverVar *dvar; - + /* driver variables */ for (dvar= driver->variables.first; dvar; dvar=dvar->next) { /* only change the used targets, since the others will need fixing manually anyway */ DRIVER_TARGETS_USED_LOOPER(dvar) { - if(dtar->id->newid) { + if (dtar->id && dtar->id->newid) { dtar->id= dtar->id->newid; } } @@ -1839,23 +1847,19 @@ void nladata_flush_channels (ListBase *channels) /* ---------------------- */ -/* NLA Evaluation function (mostly for use through do_animdata) - * - All channels that will be affected are not cleared anymore. Instead, we just evaluate into - * some temp channels, where values can be accumulated in one go. +/* NLA Evaluation function - values are calculated and stored in temporary "NlaEvalChannels" + * ! This is exported so that keyframing code can use this for make use of it for anim layers support + * > echannels: (list<NlaEvalChannels>) evaluation channels with calculated values */ -static void animsys_evaluate_nla (PointerRNA *ptr, AnimData *adt, float ctime) +void animsys_evaluate_nla (ListBase *echannels, PointerRNA *ptr, AnimData *adt, float ctime) { NlaTrack *nlt; short track_index=0; short has_strips = 0; ListBase estrips= {NULL, NULL}; - ListBase echannels= {NULL, NULL}; NlaEvalStrip *nes; - // TODO: need to zero out all channels used, otherwise we have problems with threadsafety - // and also when the user jumps between different times instead of moving sequentially... - /* 1. get the stack of strips to evaluate at current time (influence calculated here) */ for (nlt=adt->nla_tracks.first; nlt; nlt=nlt->next, track_index++) { /* stop here if tweaking is on and this strip is the tweaking track (it will be the first one that's 'disabled')... */ @@ -1930,13 +1934,30 @@ static void animsys_evaluate_nla (PointerRNA *ptr, AnimData *adt, float ctime) /* 2. for each strip, evaluate then accumulate on top of existing channels, but don't set values yet */ for (nes= estrips.first; nes; nes= nes->next) - nlastrip_evaluate(ptr, &echannels, NULL, nes); + nlastrip_evaluate(ptr, echannels, NULL, nes); + + /* 3. free temporary evaluation data that's not used elsewhere */ + BLI_freelistN(&estrips); +} + +/* NLA Evaluation function (mostly for use through do_animdata) + * - All channels that will be affected are not cleared anymore. Instead, we just evaluate into + * some temp channels, where values can be accumulated in one go. + */ +static void animsys_calculate_nla (PointerRNA *ptr, AnimData *adt, float ctime) +{ + ListBase echannels= {NULL, NULL}; + + // TODO: need to zero out all channels used, otherwise we have problems with threadsafety + // and also when the user jumps between different times instead of moving sequentially... - /* 3. flush effects of accumulating channels in NLA to the actual data they affect */ + /* evaluate the NLA stack, obtaining a set of values to flush */ + animsys_evaluate_nla(&echannels, ptr, adt, ctime); + + /* flush effects of accumulating channels in NLA to the actual data they affect */ nladata_flush_channels(&echannels); - /* 4. free temporary evaluation data */ - BLI_freelistN(&estrips); + /* free temp data */ BLI_freelistN(&echannels); } @@ -2030,7 +2051,7 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re /* evaluate NLA-stack * - active action is evaluated as part of the NLA stack as the last item */ - animsys_evaluate_nla(&id_ptr, adt, ctime); + animsys_calculate_nla(&id_ptr, adt, ctime); } /* evaluate Active Action only */ else if (adt->action) |