Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2009-09-30 08:59:14 +0400
committerJoshua Leung <aligorith@gmail.com>2009-09-30 08:59:14 +0400
commit2a21c1acbef1920a7bf177974119800c23a993c7 (patch)
treef1cfeb8544f0c31b1a198455e7349f57f2f417c1 /source/blender/blenkernel/intern
parent8b6f5c171da4d9b165c5ba0628f0302430dbed2b (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/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c13
-rw-r--r--source/blender/blenkernel/intern/ipo.c54
-rw-r--r--source/blender/blenkernel/intern/library.c44
-rw-r--r--source/blender/blenkernel/intern/nla.c3
-rw-r--r--source/blender/blenkernel/intern/object.c27
-rw-r--r--source/blender/blenkernel/intern/scene.c10
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) {