diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-09-30 08:59:14 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-09-30 08:59:14 +0400 |
commit | 2a21c1acbef1920a7bf177974119800c23a993c7 (patch) | |
tree | f1cfeb8544f0c31b1a198455e7349f57f2f417c1 /source/blender | |
parent | 8b6f5c171da4d9b165c5ba0628f0302430dbed2b (diff) |
Animato: Bugfixes
* #19501: Only the first user of multi-user IPO's were getting converted to AnimData.
Now, this AnimData gets converted multiple times - once for each user. This will mean that multi-user actions will no longer be multi-user after conversion though, although this could be fixed manually if there really is such a need.
* #19503: Nasty memory leaks when duplicating objects with AnimData
Fixed a few little oversights made when coding the copying code for NLA-data (which resulted in exponential copying-loops of doom), and sanitised the AnimData copying code for ID-blocks to be simpler to manage.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 54 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 44 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 27 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 10 |
6 files changed, 56 insertions, 95 deletions
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 07b7b6dc30c..ab902bbbae5 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -187,8 +187,6 @@ AnimData *BKE_copy_animdata (AnimData *adt) dadt= MEM_dupallocN(adt); /* make a copy of action - at worst, user has to delete copies... */ - // XXX review this... it might not be optimal behaviour yet... - //id_us_plus((ID *)dadt->action); dadt->action= copy_action(adt->action); dadt->tmpact= copy_action(adt->tmpact); @@ -1466,7 +1464,11 @@ static void animsys_evaluate_overrides (PointerRNA *ptr, AnimData *adt, float ct * * Unresolved things: * - Handling of multi-user settings (i.e. time-offset, group-instancing) -> big cache grids or nodal system? but stored where? - * - Multiple-block dependencies (i.e. drivers for settings are in both local and higher levels) -> split into separate lists? + * - Multiple-block dependencies (i.e. drivers for settings are in both local and higher levels) -> split into separate lists? + * + * Current Status: + * - Currently (as of September 2009), overrides we haven't needed to (fully) implement overrides. + * However, the code fo this is relatively harmless, so is left in the code for now. */ /* Evaluation loop for evaluation animation data @@ -1623,9 +1625,10 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime) /* objects */ /* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets - * this tagged by Depsgraph on framechange + * this tagged by Depsgraph on framechange. This optimisation means that objects + * linked from other (not-visible) scenes will not need their data calculated. */ - EVAL_ANIM_IDS(main->object.first, /*ADT_RECALC_ANIM*/0); + EVAL_ANIM_IDS(main->object.first, 0); /* worlds */ EVAL_ANIM_IDS(main->world.first, ADT_RECALC_ANIM); diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 811a2658ae3..6717f5560be 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1047,10 +1047,6 @@ static ChannelDriver *idriver_to_cdriver (IpoDriver *idriver) } } - - /* free old driver */ - MEM_freeN(idriver); - /* return the new one */ return cdriver; } @@ -1122,11 +1118,9 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha /* allocate memory for a new F-Curve */ fcu= MEM_callocN(sizeof(FCurve), "FCurve"); - /* convert driver - will free the old one... */ - if (icu->driver) { + /* convert driver */ + if (icu->driver) fcu->driver= idriver_to_cdriver(icu->driver); - icu->driver= NULL; - } /* copy flags */ if (icu->flag & IPO_VISIBLE) fcu->flag |= FCURVE_VISIBLE; @@ -1233,10 +1227,6 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha /* add new F-Curve to list */ fcurve_add_to_list(groups, list, fcurve, actname); } - - /* free old data of curve now that it's no longer needed for converting any more curves */ - if (icu->bezt) MEM_freeN(icu->bezt); - if (icu->bp) MEM_freeN(icu->bezt); } else { /* get rna-path @@ -1302,9 +1292,6 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha } } } - - /* free this data now */ - MEM_freeN(icu->bezt); } else if (icu->bp) { /* TODO: need to convert from BPoint type to the more compact FPoint type... but not priority, since no data used this */ @@ -1325,7 +1312,7 @@ static void icu_to_fcurves (ListBase *groups, ListBase *list, IpoCurve *icu, cha */ static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase *animgroups, ListBase *anim, ListBase *drivers) { - IpoCurve *icu, *icn; + IpoCurve *icu; /* sanity check */ if (ELEM3(NULL, ipo, anim, drivers)) @@ -1347,25 +1334,44 @@ static void ipo_to_animato (Ipo *ipo, char actname[], char constname[], ListBase } /* loop over IPO-Curves, freeing as we progress */ - for (icu= ipo->curve.first; icu; icu= icn) { - /* get link to next (for later) */ - icn= icu->next; - + for (icu= ipo->curve.first; icu; icu= icu->next) { /* Since an IPO-Curve may end up being made into many F-Curves (i.e. bitflag curves), * we figure out the best place to put the channel, then tell the curve-converter to just dump there */ if (icu->driver) { /* Blender 2.4x allowed empty drivers, but we don't now, since they cause more trouble than they're worth */ - if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON)) + if ((icu->driver->ob) || (icu->driver->type == IPO_DRIVER_TYPE_PYTHON)) { icu_to_fcurves(NULL, drivers, icu, actname, constname); - else + } + else { MEM_freeN(icu->driver); + icu->driver= NULL; + } } else icu_to_fcurves(animgroups, anim, icu, actname, constname); + } + + /* if this IPO block doesn't have any users after this one, free... */ + ipo->id.us--; + if ( (ipo->id.us == 0) || ((ipo->id.us == 1) && (ipo->id.flag & LIB_FAKEUSER)) ) + { + IpoCurve *icn; - /* free this IpoCurve now that it's been converted */ - BLI_freelinkN(&ipo->curve, icu); + for (icu= ipo->curve.first; icu; icu= icn) { + icn= icu->next; + + /* free driver */ + if (icu->driver) + MEM_freeN(icu->driver); + + /* free old data of curve now that it's no longer needed for converting any more curves */ + if (icu->bezt) MEM_freeN(icu->bezt); + if (icu->bp) MEM_freeN(icu->bezt); + + /* free this IPO-Curve */ + BLI_freelinkN(&ipo->curve, icu); + } } } diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 45869a317e8..0f65be207d9 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -640,42 +640,15 @@ void *alloc_libblock(ListBase *lb, short type, const char *name) } /* by spec, animdata is first item after ID */ -/* we still read ->adt itself, to ensure compiler warns when it doesnt exist */ +/* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */ static void id_copy_animdata(ID *id) { - switch(GS(id->name)) { - case ID_OB: - ((Object *)id)->adt= BKE_copy_animdata(((Object *)id)->adt); - break; - case ID_CU: - ((Curve *)id)->adt= BKE_copy_animdata(((Curve *)id)->adt); - break; - case ID_CA: - ((Camera *)id)->adt= BKE_copy_animdata(((Camera *)id)->adt); - break; - case ID_KE: - ((Key *)id)->adt= BKE_copy_animdata(((Key *)id)->adt); - break; - case ID_LA: - ((Lamp *)id)->adt= BKE_copy_animdata(((Lamp *)id)->adt); - break; - case ID_MA: - ((Material *)id)->adt= BKE_copy_animdata(((Material *)id)->adt); - break; - case ID_NT: - ((bNodeTree *)id)->adt= BKE_copy_animdata(((bNodeTree *)id)->adt); - break; - case ID_SCE: - ((Scene *)id)->adt= BKE_copy_animdata(((Scene *)id)->adt); - break; - case ID_TE: - ((Tex *)id)->adt= BKE_copy_animdata(((Tex *)id)->adt); - break; - case ID_WO: - ((World *)id)->adt= BKE_copy_animdata(((World *)id)->adt); - break; - } + AnimData *adt= BKE_animdata_from_id(id); + if (adt) { + IdAdtTemplate *iat = (IdAdtTemplate *)id; + iat->adt= BKE_copy_animdata(iat->adt); + } } /* used everywhere in blenkernel and text.c */ @@ -705,8 +678,9 @@ void *copy_libblock(void *rt) id->newid= idn; idn->flag |= LIB_NEW; if (id->properties) idn->properties = IDP_CopyProperty(id->properties); - - id_copy_animdata(id); + + /* the duplicate should get a copy of the animdata */ + id_copy_animdata(idn); return idn; } diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 83ee71bfe40..3979586fb19 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -219,6 +219,9 @@ void copy_nladata (ListBase *dst, ListBase *src) if ELEM(NULL, dst, src) return; + /* clear out the destination list first for precautions... */ + dst->first= dst->last= NULL; + /* copy each NLA-track, one at a time */ for (nlt= src->first; nlt; nlt= nlt->next) { /* make a copy, and add the copy to the destination list */ diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 7e2ec106062..4c729845745 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1268,7 +1268,7 @@ Object *copy_object(Object *ob) /* increase user numbers */ id_us_plus((ID *)obn->data); id_us_plus((ID *)obn->dup_group); - // FIXME: add this for animdata too... + for(a=0; a<obn->totcol; a++) id_us_plus((ID *)obn->mat[a]); @@ -1922,31 +1922,6 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime) if(ob==NULL) return; -#if 0 // XXX old animation system - /* this is needed to be able to grab objects with ipos, otherwise it always freezes them */ - stime= bsystem_time(scene, ob, ctime, 0.0); - if(stime != ob->ctime) { - - ob->ctime= stime; - - if(ob->ipo) { - calc_ipo(ob->ipo, stime); - execute_ipo((ID *)ob, ob->ipo); - } - else - do_all_object_actions(scene, ob); - - /* do constraint ipos ..., note it needs stime (0 = all ipos) */ - do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 0); - } - else { - /* but, the drivers have to be done */ - if(ob->ipo) do_ob_ipodrivers(ob, ob->ipo, stime); - /* do constraint ipos ..., note it needs stime (1 = only drivers ipos) */ - do_constraint_channels(&ob->constraints, &ob->constraintChannels, stime, 1); - } -#endif // XXX old animation system - /* execute drivers only, as animation has already been done */ BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 4de9ff3b6d9..b3f00f884bc 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -778,11 +778,11 @@ static void scene_update(Scene *sce, unsigned int lay) DAG_scene_update_flags(sce, lay); // only stuff that moves or needs display still /* All 'standard' (i.e. without any dependencies) animation is handled here, - * with an 'local' to 'macro' order of evaluation. This should ensure that - * settings stored nestled within a hierarchy (i.e. settings in a Texture block - * can be overridden by settings from Scene, which owns the Texture through a hierarchy - * such as Scene->World->MTex/Texture) can still get correctly overridden. - */ + * with an 'local' to 'macro' order of evaluation. This should ensure that + * settings stored nestled within a hierarchy (i.e. settings in a Texture block + * can be overridden by settings from Scene, which owns the Texture through a hierarchy + * such as Scene->World->MTex/Texture) can still get correctly overridden. + */ BKE_animsys_evaluate_all_animation(G.main, ctime); for(base= sce->base.first; base; base= base->next) { |