diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_anim.h | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_depsgraph.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_displist.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_font.h | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_group.h | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/anim.c | 217 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/depsgraph.c | 23 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 19 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/font.c | 89 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/group.c | 151 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mball.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 23 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 39 |
16 files changed, 383 insertions, 235 deletions
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h index e4cd8e39aca..69fb83aac30 100644 --- a/source/blender/blenkernel/BKE_anim.h +++ b/source/blender/blenkernel/BKE_anim.h @@ -39,12 +39,18 @@ struct Object; struct PartEff; struct Scene; +typedef struct DupliObject { + struct DupliObject *next, *prev; + struct Object *ob; + float mat[4][4], omat[4][4]; +} DupliObject; + void free_path(struct Path *path); void calc_curvepath(struct Object *ob); int interval_test(int min, int max, int p1, int cycl); int where_on_path(struct Object *ob, float ctime, float *vec, float *dir); -void free_duplilist(void); -void make_duplilist(struct Scene *sce, struct Object *ob); + +ListBase *object_duplilist(struct Scene *sce, struct Object *ob); int count_duplilist(struct Object *ob); #endif diff --git a/source/blender/blenkernel/BKE_depsgraph.h b/source/blender/blenkernel/BKE_depsgraph.h index 5dd820d5a79..294f61e54bd 100644 --- a/source/blender/blenkernel/BKE_depsgraph.h +++ b/source/blender/blenkernel/BKE_depsgraph.h @@ -109,5 +109,5 @@ void DAG_scene_flush_update(struct Scene *sce, unsigned int lay); void DAG_object_flush_update(struct Scene *sce, struct Object *ob, short flag); void DAG_pose_sort(struct Object *ob); - + #endif diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 2dcf4bfe1be..05a1cfc5376 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -75,6 +75,7 @@ if( (cyclv) && a==sizev-1) { \ /* prototypes */ +struct Base; struct Object; struct Curve; struct ListBase; @@ -144,7 +145,7 @@ extern void makeDispListMesh(struct Object *ob); extern void makeDispListSurf(struct Object *ob, struct ListBase *dispbase, int forRender); extern void makeDispListCurveTypes(struct Object *ob, int forOrco); extern void makeDispListMBall(struct Object *ob); -extern void shadeDispList(struct Object *ob); +extern void shadeDispList(struct Base *base); void freefastshade(void); void imagestodisplist(void); void reshadeall_displist(void); diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h index 00a994672be..05621a4d9b2 100644 --- a/source/blender/blenkernel/BKE_font.h +++ b/source/blender/blenkernel/BKE_font.h @@ -41,6 +41,13 @@ struct Object; struct Curve; struct objfnt; +struct chartrans { + float xof, yof; + float rot; + short linenr,charnr; + char dobreak; +}; + typedef struct SelBox { float x, y, w, h; } SelBox; @@ -55,7 +62,7 @@ struct VFont *load_vfont(char *name); struct chartrans *text_to_curve(struct Object *ob, int mode); int style_to_sel(int style, int toggle); int mat_to_sel(void); -void font_duplilist(struct Object *par); + int getselection(int *start, int *end); void chtoutf8(unsigned long c, char *o); diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h index 2d42a9e284c..db4c83040a8 100644 --- a/source/blender/blenkernel/BKE_group.h +++ b/source/blender/blenkernel/BKE_group.h @@ -37,15 +37,20 @@ struct Group; struct GroupObject; struct Object; +struct bAction; -void free_group_object(struct GroupObject *go); -void free_group(struct Group *group); +void free_group_object(struct GroupObject *go); +void free_group(struct Group *group); +void unlink_group(struct Group *group); struct Group *add_group(void); -void add_to_group(struct Group *group, struct Object *ob); -void rem_from_group(struct Group *group, struct Object *ob); +void add_to_group(struct Group *group, struct Object *ob); +void rem_from_group(struct Group *group, struct Object *ob); struct Group *find_group(struct Object *ob); -int object_in_group(struct Object *ob, struct Group *group); -void group_tag_recalc(struct Group *group); +int object_in_group(struct Object *ob, struct Group *group); + +void group_tag_recalc(struct Group *group); +void group_handle_recalc_and_update(struct Object *parent, struct Group *group); +struct Object *group_get_member_with_action(struct Group *group, struct bAction *act); #endif diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 04c4d180927..a0713d3a7dd 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1823,8 +1823,6 @@ static void mesh_build_data(Object *ob) Mesh *me = ob->data; float min[3], max[3]; - if(ob->flag&OB_FROMDUPLI) return; - clear_mesh_caches(ob); if(ob!=G.obedit) { diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index d5fa6958dff..211e552f493 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -816,7 +816,7 @@ static void do_nla(Object *ob, int blocktype) actlength = strip->actend-strip->actstart; striptime = (G.scene->r.cfra-(strip->start)) / length; stripframe = (G.scene->r.cfra-(strip->start)) ; - + if (striptime>=0.0){ if(blocktype==ID_AR) @@ -979,6 +979,7 @@ void do_all_pose_actions(Object *ob) void do_all_object_actions(Object *ob) { if(ob==NULL) return; + if(ob->dup_group) return; /* prevent conflicts, might add smarter check later */ /* Do local action */ if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) { diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 5b5f1fabdf2..5700be0fcbc 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -49,17 +49,20 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_view3d_types.h" +#include "DNA_vfont_types.h" +#include "BKE_anim.h" #include "BKE_DerivedMesh.h" +#include "BKE_displist.h" +#include "BKE_effect.h" +#include "BKE_font.h" +#include "BKE_group.h" #include "BKE_global.h" -#include "BKE_utildefines.h" -#include "BKE_anim.h" #include "BKE_ipo.h" -#include "BKE_object.h" -#include "BKE_displist.h" #include "BKE_key.h" -#include "BKE_font.h" -#include "BKE_effect.h" +#include "BKE_main.h" +#include "BKE_object.h" +#include "BKE_utildefines.h" #include "BKE_bad_level_calls.h" @@ -272,53 +275,40 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK return 1; } -static Object *new_dupli_object(ListBase *lb, Object *ob, Object *par, int clearpar) -{ - Object *newob; - - newob= MEM_mallocN(sizeof(Object), "newobj dupli"); - - memcpy(newob, ob, sizeof(Object)); - newob->flag |= OB_FROMDUPLI; - newob->id.newid= (ID *)par; /* store duplicator */ - - /* only basis-ball gets displist */ - if(newob->type==OB_MBALL) newob->disp.first= newob->disp.last= NULL; +/* ****************** DUPLICATOR ************** */ - if(clearpar) { // dupliverts, particle - newob->parent= NULL; - newob->track= NULL; - } - BLI_addtail(lb, newob); - - return newob; +static void new_dupli_object(ListBase *lb, Object *ob, float mat[][4]) +{ + DupliObject *dob= MEM_mallocN(sizeof(DupliObject), "dupliobject"); + BLI_addtail(lb, dob); + dob->ob= ob; + Mat4CpyMat4(dob->mat, mat); + Mat4CpyMat4(dob->omat, ob->obmat); } -static void group_duplilist(Object *ob) +static void group_duplilist(ListBase *lb, Object *ob) { - Object *newob; GroupObject *go; float mat[4][4]; if(ob->dup_group==NULL) return; + /* handles animated groups, and */ + /* we need to check update for objects that are not in scene... */ + group_handle_recalc_and_update(ob, ob->dup_group); + for(go= ob->dup_group->gobject.first; go; go= go->next) { if(go->ob!=ob) { - /* we need to check update for objects that are not in scene... */ - if(go->ob->recalc) - object_handle_update(go->ob); // bke_object.h - - newob= new_dupli_object(&duplilist, go->ob, ob, 0); - Mat4CpyMat4(mat, newob->obmat); - Mat4MulMat4(newob->obmat, mat, ob->obmat); + Mat4MulMat4(mat, go->ob->obmat, ob->obmat); + new_dupli_object(lb, go->ob, mat); } } } -static void frames_duplilist(Object *ob) +static void frames_duplilist(ListBase *lb, Object *ob) { extern int enable_cu_speed; /* object.c */ - Object *newob, copyob; + Object copyob; int cfrao, ok; cfrao= G.scene->r.cfra; @@ -337,10 +327,9 @@ static void frames_duplilist(Object *ob) else ok= 0; } if(ok) { - newob= new_dupli_object(&duplilist, ob, ob, 0); - - do_ob_ipo(newob); - where_is_object_time(newob, (float)G.scene->r.cfra); + do_ob_ipo(ob); + where_is_object_time(ob, (float)G.scene->r.cfra); + new_dupli_object(lb, ob, ob->obmat); } } @@ -350,6 +339,7 @@ static void frames_duplilist(Object *ob) } struct vertexDupliData { + ListBase *lb; float pmat[4][4]; Object *ob, *par; }; @@ -357,16 +347,15 @@ struct vertexDupliData { static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *no_f, short *no_s) { struct vertexDupliData *vdd= userData; - Object *newob; - float vec[3], *q2, mat[3][3], tmat[4][4]; + float vec[3], *q2, mat[3][3], tmat[4][4], obmat[4][4]; VECCOPY(vec, co); Mat4MulVecfl(vdd->pmat, vec); VecSubf(vec, vec, vdd->pmat[3]); VecAddf(vec, vec, vdd->ob->obmat[3]); - newob= new_dupli_object(&duplilist, vdd->ob, vdd->par, 1); - VECCOPY(newob->obmat[3], vec); + Mat4CpyMat4(obmat, vdd->ob->obmat); + VECCOPY(obmat[3], vec); if(vdd->par->transflag & OB_DUPLIROT) { @@ -375,13 +364,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, float *co, float *n q2= vectoquat(vec, vdd->ob->trackflag, vdd->ob->upflag); QuatToMat3(q2, mat); - Mat4CpyMat4(tmat, newob->obmat); - Mat4MulMat43(newob->obmat, tmat, mat); + Mat4CpyMat4(tmat, obmat); + Mat4MulMat43(obmat, tmat, mat); } - + new_dupli_object(vdd->lb, vdd->ob, obmat); } -static void vertex_duplilist(Scene *sce, Object *par) +static void vertex_duplilist(ListBase *lb, Scene *sce, Object *par) { Object *ob; Base *base; @@ -411,6 +400,7 @@ static void vertex_duplilist(Scene *sce, Object *par) struct vertexDupliData vdd; ob= base->object; + vdd.lb= lb; vdd.ob= ob; vdd.par= par; Mat4CpyMat4(vdd.pmat, pmat); @@ -442,9 +432,9 @@ static void vertex_duplilist(Scene *sce, Object *par) dm->release(dm); } -static void particle_duplilist(Scene *sce, Object *par, PartEff *paf) +static void particle_duplilist(ListBase *lb, Scene *sce, Object *par, PartEff *paf) { - Object *ob, *newob; + Object *ob, copyob; Base *base; Particle *pa; float ctime, vec1[3]; @@ -460,21 +450,20 @@ static void particle_duplilist(Scene *sce, Object *par, PartEff *paf) } ctime= bsystem_time(par, 0, (float)G.scene->r.cfra, 0.0); - + lay= G.scene->lay; - base= sce->base.first; - while(base) { - + for(base= sce->base.first; base; base= base->next) { if(base->object->type>0 && (base->lay & lay) && G.obedit!=base->object) { ob= base->object->parent; while(ob) { if(ob==par) { ob= base->object; + /* temp copy, to have ipos etc to work OK */ + copyob= *ob; - pa= paf->keys; - for(a=0; a<paf->totpart; a++, pa+=paf->totkey) { + for(a=0, pa= paf->keys; a<paf->totpart; a++, pa+=paf->totkey) { if(paf->flag & PAF_STATIC) { float mtime; @@ -483,13 +472,12 @@ static void particle_duplilist(Scene *sce, Object *par, PartEff *paf) mtime= pa->time+pa->lifetime; for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) { - newob= new_dupli_object(&duplilist, ob, par, 1); /* make sure hair grows until the end.. */ if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime; /* to give ipos in object correct offset */ - where_is_object_time(newob, ctime-pa->time); + where_is_object_time(ob, ctime-pa->time); where_is_particle(paf, pa, ctime, vec); // makes sure there's always a vec Mat4MulVecfl(par->obmat, vec); @@ -502,11 +490,12 @@ static void particle_duplilist(Scene *sce, Object *par, PartEff *paf) q2= vectoquat(vec1, ob->trackflag, ob->upflag); QuatToMat3(q2, mat); - Mat4CpyMat4(tmat, newob->obmat); - Mat4MulMat43(newob->obmat, tmat, mat); + Mat4CpyMat4(tmat, ob->obmat); + Mat4MulMat43(ob->obmat, tmat, mat); } - VECCOPY(newob->obmat[3], vec); + VECCOPY(ob->obmat[3], vec); + new_dupli_object(lb, ob, ob->obmat); } } else { // non static particles @@ -515,10 +504,9 @@ static void particle_duplilist(Scene *sce, Object *par, PartEff *paf) if((paf->flag & PAF_DIED)==0 && ctime > pa->time+pa->lifetime) continue; //if(ctime < pa->time+pa->lifetime) { - newob= new_dupli_object(&duplilist, ob, par, 1); /* to give ipos in object correct offset */ - where_is_object_time(newob, ctime-pa->time); + where_is_object_time(ob, ctime-pa->time); where_is_particle(paf, pa, ctime, vec); if(paf->stype==PAF_VECT) { @@ -528,56 +516,129 @@ static void particle_duplilist(Scene *sce, Object *par, PartEff *paf) q2= vectoquat(vec1, ob->trackflag, ob->upflag); QuatToMat3(q2, mat); - Mat4CpyMat4(tmat, newob->obmat); - Mat4MulMat43(newob->obmat, tmat, mat); + Mat4CpyMat4(tmat, ob->obmat); + Mat4MulMat43(ob->obmat, tmat, mat); } - VECCOPY(newob->obmat[3], vec); + VECCOPY(ob->obmat[3], vec); + new_dupli_object(lb, ob, ob->obmat); } } + /* temp copy, to have ipos etc to work OK */ + *ob= copyob; + break; } ob= ob->parent; } } - base= base->next; } } -void free_duplilist() +static Object *find_family_object(Object **obar, char *family, char ch) { Object *ob; + int flen; + + if( obar[ch] ) return obar[ch]; - while( (ob= duplilist.first) ) { - BLI_remlink(&duplilist, ob); - MEM_freeN(ob); + flen= strlen(family); + + ob= G.main->object.first; + while(ob) { + if( ob->id.name[flen+2]==ch ) { + if( strncmp(ob->id.name+2, family, flen)==0 ) break; + } + ob= ob->id.next; } + obar[ch]= ob; + + return ob; } -void make_duplilist(Scene *sce, Object *ob) + +static void font_duplilist(ListBase *lb, Object *par) { - PartEff *paf; + Object *ob, *obar[256]; + Curve *cu; + struct chartrans *ct, *chartransdata; + float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof; + int slen, a; + + Mat4CpyMat4(pmat, par->obmat); + + /* in par the family name is stored, use this to find the other objects */ + + chartransdata= text_to_curve(par, FO_DUPLI); + if(chartransdata==0) return; + + memset(obar, 0, 256*sizeof(void *)); + + cu= par->data; + slen= strlen(cu->str); + fsize= cu->fsize; + xof= cu->xof; + yof= cu->yof; + + ct= chartransdata; + + for(a=0; a<slen; a++, ct++) { + + ob= find_family_object(obar, cu->family, cu->str[a]); + if(ob) { + vec[0]= fsize*(ct->xof - xof); + vec[1]= fsize*(ct->yof - yof); + vec[2]= 0.0; + + Mat4MulVecfl(pmat, vec); + + Mat4CpyMat4(obmat, par->obmat); + VECCOPY(obmat[3], vec); + + new_dupli_object(lb, ob, obmat); + } + + } + + MEM_freeN(chartransdata); +} + +/* ***************************** */ +ListBase *object_duplilist(Scene *sce, Object *ob) +{ + static ListBase duplilist={NULL, NULL}; + + if(duplilist.first) { + printf("wrong call to object_duplilist\n"); + return &duplilist; + } + duplilist.first= duplilist.last= NULL; + if(ob->transflag & OB_DUPLI) { if(ob->transflag & OB_DUPLIVERTS) { if(ob->type==OB_MESH) { if(ob->transflag & OB_DUPLIVERTS) { - if( (paf=give_parteff(ob)) ) particle_duplilist(sce, ob, paf); - else vertex_duplilist(sce, ob); + PartEff *paf; + if( (paf=give_parteff(ob)) ) particle_duplilist(&duplilist, sce, ob, paf); + else vertex_duplilist(&duplilist, sce, ob); } } else if(ob->type==OB_FONT) { - font_duplilist(ob); + font_duplilist(&duplilist, ob); } } else if(ob->transflag & OB_DUPLIFRAMES) - frames_duplilist(ob); + frames_duplilist(&duplilist, ob); else if(ob->transflag & OB_DUPLIGROUP) - group_duplilist(ob); + group_duplilist(&duplilist, ob); } + + return &duplilist; } + int count_duplilist(Object *ob) { if(ob->transflag & OB_DUPLI) { diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 36071d39207..18c8de24feb 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -1546,14 +1546,15 @@ static int exists_channel(Object *ob, char *name) return 0; } -static void object_time_update_flags(Object *ob) +static void dag_object_time_update_flags(Object *ob) { if(ob->ipo) ob->recalc |= OB_RECALC_OB; else if(ob->constraints.first) ob->recalc |= OB_RECALC_OB; else if(ob->scriptlink.totscript) ob->recalc |= OB_RECALC_OB; else if(ob->parent) { - if(ob->parent->type==OB_CURVE) ob->recalc |= OB_RECALC_OB; + /* motion path or bone child */ + if(ob->parent->type==OB_CURVE || ob->parent->type==OB_ARMATURE) ob->recalc |= OB_RECALC_OB; } if(ob->action || ob->nlastrips.first) { @@ -1632,7 +1633,7 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay) /* now if DagNode were part of base, the node->lay could be checked... */ /* we do all now, since the scene_flush checks layers and clears recalc flags even */ - object_time_update_flags(ob); + dag_object_time_update_flags(ob); /* handled in next loop */ if(ob->dup_group) @@ -1640,16 +1641,28 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay) } + /* we do groups each once */ for(group= G.main->group.first; group; group= group->id.next) { if(group->id.flag & LIB_DOIT) { for(go= group->gobject.first; go; go= go->next) { - object_time_update_flags(go->ob); + dag_object_time_update_flags(go->ob); } - group->id.flag &= ~LIB_DOIT; } } DAG_scene_flush_update(sce, lay); + + /* and store the info in groubobject */ + for(group= G.main->group.first; group; group= group->id.next) { + if(group->id.flag & LIB_DOIT) { + for(go= group->gobject.first; go; go= go->next) { + go->recalc= go->ob->recalc; +// printf("ob %s recalc %d\n", go->ob->id.name, go->recalc); + } + group->id.flag &= ~LIB_DOIT; + } + } + } /* for depgraph updating, all layers visible in a screen */ diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 219ef69d6d2..c27245fc11e 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -840,8 +840,10 @@ void mesh_create_shadedColors(Object *ob, int onlyForMesh, unsigned int **col1_r } -void shadeDispList(Object *ob) +/* has base pointer, to check for layer */ +void shadeDispList(Base *base) { + Object *ob= base->object; DispList *dl, *dlob; Material *ma = NULL; Curve *cu; @@ -850,8 +852,6 @@ void shadeDispList(Object *ob) unsigned int *col1; int a; - if(ob->flag & OB_FROMDUPLI) return; - dl = find_displist(&ob->disp, DL_VERTCOL); if (dl) { BLI_remlink(&ob->disp, dl); @@ -986,16 +986,13 @@ void reshadeall_displist(void) freefastshade(); - base= G.scene->base.first; - while(base) { + for(base= G.scene->base.first; base; base= base->next) { + ob= base->object; + freedisplist(&ob->disp); if(base->lay & G.scene->lay) { - ob= base->object; - /* Metaballs have standard displist at the Object */ - if(ob->type==OB_MBALL) shadeDispList(ob); - else freedisplist(&ob->disp); + if(ob->type==OB_MBALL) shadeDispList(base); } - base= base->next; } } @@ -1388,7 +1385,7 @@ static float calc_taper(Object *taperobj, int cur, int tot) void makeDispListMBall(Object *ob) { - if(!ob || (ob->flag&OB_FROMDUPLI) || ob->type!=OB_MBALL) return; + if(!ob || ob->type!=OB_MBALL) return; freedisplist(&(ob->disp)); diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 2ab13fe328a..b5ed7fb3688 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -73,13 +73,6 @@ struct SelBox *selboxes= NULL; -struct chartrans { - float xof, yof; - float rot; - short linenr,charnr; - char dobreak; -}; - /* UTF-8 <-> wchar transformations */ void chtoutf8(unsigned long c, char *o) @@ -1190,86 +1183,4 @@ struct chartrans *text_to_curve(Object *ob, int mode) return 0; } -/* ***************** DUPLI ***************** */ - -static Object *find_family_object(Object **obar, char *family, char ch) -{ - Object *ob; - int flen; - - if( obar[ch] ) return obar[ch]; - - flen= strlen(family); - - ob= G.main->object.first; - while(ob) { - if( ob->id.name[flen+2]==ch ) { - if( strncmp(ob->id.name+2, family, flen)==0 ) break; - } - ob= ob->id.next; - } - - obar[ch]= ob; - - return ob; -} - - -void font_duplilist(Object *par) -{ - extern ListBase duplilist; - Object *ob, *newob, *obar[256]; - Curve *cu; - struct chartrans *ct, *chartransdata; - float vec[3], pmat[4][4], fsize, xof, yof; - int slen, a; - - Mat4CpyMat4(pmat, par->obmat); - - /* in par the family name is stored, use this to find the other objects */ - - chartransdata= text_to_curve(par, FO_DUPLI); - if(chartransdata==0) return; - - memset(obar, 0, 256*4); - - cu= par->data; - slen= strlen(cu->str); - fsize= cu->fsize; - xof= cu->xof; - yof= cu->yof; - - ct= chartransdata; - - for(a=0; a<slen; a++, ct++) { - - ob= find_family_object(obar, cu->family, cu->str[a]); - if(ob) { - /* not clear if this free line here is still needed */ - freedisplist(&ob->disp); - - vec[0]= fsize*(ct->xof - xof); - vec[1]= fsize*(ct->yof - yof); - vec[2]= 0.0; - - Mat4MulVecfl(pmat, vec); - - newob= MEM_mallocN(sizeof(Object), "newobj dupli"); - memcpy(newob, ob, sizeof(Object)); - newob->flag |= OB_FROMDUPLI; - newob->id.newid= (ID *)par; /* keep duplicator */ - newob->totcol= par->totcol; /* for give_current_material */ - - Mat4CpyMat4(newob->obmat, par->obmat); - VECCOPY(newob->obmat[3], vec); - - newob->parent= 0; - newob->track= 0; - - BLI_addtail(&duplilist, newob); - } - - } - MEM_freeN(chartransdata); -} diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 0ae6208c9de..5e2d0d6fc6d 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -32,19 +32,24 @@ #include "MEM_guardedalloc.h" -#include "DNA_ID.h" +#include "DNA_action_types.h" +#include "DNA_effect_types.h" #include "DNA_group_types.h" -#include "DNA_object_types.h" +#include "DNA_ID.h" #include "DNA_ipo_types.h" +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_nla_types.h" +#include "DNA_scene_types.h" #include "BLI_blenlib.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_library.h" +#include "BKE_global.h" #include "BKE_group.h" -#include "BKE_object.h" #include "BKE_ipo.h" +#include "BKE_library.h" +#include "BKE_main.h" +#include "BKE_object.h" #ifdef HAVE_CONFIG_H #include <config.h> @@ -68,6 +73,34 @@ void free_group(Group *group) } } +void unlink_group(Group *group) +{ + Material *ma; + Object *ob; + + for(ma= G.main->mat.first; ma; ma= ma->id.next) { + if(ma->group==group) + ma->group= NULL; + } + for(ob= G.main->object.first; ob; ob= ob->id.next) { + bActionStrip *strip; + PartEff *paf; + + if(ob->dup_group==group) + ob->dup_group= NULL; + for(strip= ob->nlastrips.first; strip; strip= strip->next) { + if(strip->object==ob) + strip->object= NULL; + } + for(paf= ob->effect.first; paf; paf= paf->next) { + if(paf->type==EFF_PARTICLE) { + if(paf->group) + paf->group= NULL; + } + } + } +} + Group *add_group() { Group *group; @@ -150,3 +183,109 @@ void group_tag_recalc(Group *group) } } +/* only replaces object strips or action when parent nla instructs it */ +/* keep checking nla.c though, in case internal structure of strip changes */ +static void group_replaces_nla(Object *parent, Object *target, char mode) +{ + static ListBase nlastrips={NULL, NULL}; + static bAction *action= NULL; + static int done= 0; + bActionStrip *strip, *nstrip; + + if(mode=='s') { + + for(strip= parent->nlastrips.first; strip; strip= strip->next) { + if(strip->object==target) { + if(done==0) { + /* clear nla & action from object */ + nlastrips= target->nlastrips; + target->nlastrips.first= target->nlastrips.last= NULL; + action= target->action; + target->action= NULL; + target->nlaflag |= OB_NLA_OVERRIDE; + done= 1; + } + nstrip= MEM_dupallocN(strip); + BLI_addtail(&target->nlastrips, nstrip); + } + } + } + else if(mode=='e') { + if(done) { + BLI_freelistN(&target->nlastrips); + target->nlastrips= nlastrips; + target->action= action; + + nlastrips.first= nlastrips.last= NULL; /* not needed, but yah... :) */ + action= NULL; + done= 0; + } + } +} + + +/* puts all group members in local timing system, after this call +you can draw everything, leaves tags in objects to signal it needs further updating */ +void group_handle_recalc_and_update(Object *parent, Group *group) +{ + GroupObject *go; + + /* if animated group... */ + if(parent->sf != 0.0f || parent->nlastrips.first) { + int cfrao; + + /* switch to local time */ + cfrao= G.scene->r.cfra; + G.scene->r.cfra -= (int)parent->sf; + + /* we need a DAG per group... */ + for(go= group->gobject.first; go; go= go->next) { + if(go->ob && go->recalc) { + go->ob->recalc= go->recalc; + + group_replaces_nla(parent, go->ob, 's'); + object_handle_update(go->ob); + group_replaces_nla(parent, go->ob, 'e'); + + /* leave recalc tags in case group members are in normal scene */ + go->ob->recalc= go->recalc; + } + } + + /* restore */ + G.scene->r.cfra= cfrao; + } + else { + /* only do existing tags, as set by regular depsgraph */ + for(go= group->gobject.first; go; go= go->next) { + if(go->ob) { + if(go->ob->recalc) { + object_handle_update(go->ob); + } + } + } + } +} + +Object *group_get_member_with_action(Group *group, bAction *act) +{ + GroupObject *go; + + if(group==NULL || act==NULL) return NULL; + + for(go= group->gobject.first; go; go= go->next) { + if(go->ob) { + if(go->ob->action==act) + return go->ob; + if(go->ob->nlastrips.first) { + bActionStrip *strip; + + for(strip= go->ob->nlastrips.first; strip; strip= strip->next) { + if(strip->act==act) + return go->ob; + } + } + } + } + return NULL; +} diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index ea1608d8a18..09408e4a220 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -1437,11 +1437,12 @@ float init_meta(Object *ob) /* return totsize */ Object *bob; MetaBall *mb; MetaElem *ml; - float size, totsize, (*mat)[4] = NULL, (*imat)[4] = NULL, obinv[4][4], vec[3]; + float size, totsize, (*mat)[4] = NULL, (*imat)[4] = NULL, obinv[4][4], obmat[4][4], vec[3]; float temp1[4][4], temp2[4][4], temp3[4][4]; //max=0.0; int a, obnr, zero_size=0; char obname[32]; + Mat4CpyMat4(obmat, ob->obmat); /* to cope with duplicators from next_object */ Mat4Invert(obinv, ob->obmat); a= 0; @@ -1456,7 +1457,7 @@ float init_meta(Object *ob) /* return totsize */ zero_size= 0; ml= NULL; - if(bob==ob) { + if(bob==ob && (base->flag & OB_FROMDUPLI)==0) { mat= imat= 0; mb= ob->data; @@ -1471,7 +1472,6 @@ float init_meta(Object *ob) /* return totsize */ splitIDname(bob->id.name+2, name, &nr); if( strcmp(obname, name)==0 ) { mb= bob->data; - if(G.obedit && G.obedit->type==OB_MBALL && G.obedit->data==mb) ml= editelems.first; else ml= mb->elems.first; @@ -1535,7 +1535,7 @@ float init_meta(Object *ob) /* return totsize */ imat= new_pgn_element(4*4*sizeof(float)); /* mat is the matrix to transform from mball into the basis-mball */ - Mat4Invert(obinv, ob->obmat); + Mat4Invert(obinv, obmat); Mat4MulMat4(temp2, bob->obmat, obinv); /* MetaBall transformation */ Mat4MulMat4(mat, temp1, temp2); diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index 5adde76accc..5fefc41f77c 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -46,6 +46,9 @@ #include <config.h> #endif +/* NOTE: in group.c the strips get copied for group-nla override, this assumes + that strips are one single block, without additional data to be copied */ + void copy_actionstrip (bActionStrip **dst, bActionStrip **src){ bActionStrip *dstrip; bActionStrip *sstrip = *src; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 7af6ef21e32..e7cf3577a99 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -208,6 +208,7 @@ void free_object(Object *ob) ob->path= 0; if(ob->ipo) ob->ipo->id.us--; if(ob->action) ob->action->id.us--; + if(ob->dup_group) ob->dup_group->id.us--; if(ob->defbase.first) BLI_freelistN(&ob->defbase); if(ob->pose) { @@ -255,6 +256,7 @@ void unlink_object(Object *ob) Ipo *ipo; Group *group; bConstraint *con; + bActionStrip *strip; int a; char *str; @@ -315,6 +317,7 @@ void unlink_object(Object *ob) obt->recalc |= OB_RECALC_OB; } } + /* object is deflector or field */ if(ob->pd) { if(give_parteff(obt)) @@ -322,6 +325,12 @@ void unlink_object(Object *ob) else if(obt->soft) obt->recalc |= OB_RECALC_DATA; } + + /* strips */ + for(strip= ob->nlastrips.first; strip; strip= strip->next) { + if(strip->object==ob) + strip->object= NULL; + } } obt= obt->id.next; } @@ -999,15 +1008,10 @@ float bsystem_time(Object *ob, Object *par, float cfra, float ofs) if(R.r.mode & R_FIELDSTILL); else cfra+= .5; } + cfra+= bluroffs; - if(ob && (ob->flag & OB_FROMDUPLI)); - else { - /* motion blur */ - cfra+= bluroffs; - - /* global time */ - cfra*= G.scene->r.framelen; - } + /* global time */ + cfra*= G.scene->r.framelen; if(no_speed_curve==0) if(ob && ob->ipo) cfra= calc_ipo_time(ob->ipo, cfra); @@ -1522,9 +1526,6 @@ void solve_tracking (Object *ob, float targetmat[][4]) void where_is_object(Object *ob) { - /* these have been mem copied */ - if(ob->flag & OB_FROMDUPLI) return; - where_is_object_time(ob, (float)G.scene->r.cfra); } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index fd0a6288dbe..df9e626abbf 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -76,7 +76,7 @@ #include "BKE_utildefines.h" #include "BPY_extern.h" - +#include "BLI_arithb.h" #include "BLI_blenlib.h" #include "nla.h" @@ -277,13 +277,10 @@ void set_scene_bg(Scene *sce) ob->flag= base->flag; - ob->recalc= OB_RECALC; - if(ob->dup_group) group_tag_recalc(ob->dup_group); /* for lib-linked stuff */ - ob->ctime= -1234567.0; /* force ipo to be calculated later */ base= base->next; } - // full update + // full animation update scene_update_for_newframe(sce, sce->lay); /* do we need FRAMECHANGED in set_scene? */ @@ -309,23 +306,21 @@ void set_scene_name(char *name) */ int next_object(int val, Base **base, Object **ob) { - extern ListBase duplilist; - static Object *dupob; + static ListBase *duplilist= NULL; + static DupliObject *dupob; static int fase; int run_again=1; /* init */ if(val==0) { fase= F_START; - dupob= 0; + dupob= NULL; } else { /* run_again is set when a duplilist has been ended */ while(run_again) { run_again= 0; - - /* the first base */ if(fase==F_START) { @@ -360,30 +355,40 @@ int next_object(int val, Base **base, Object **ob) } } - if(*base == 0) fase= F_START; + if(*base == NULL) fase= F_START; else { if(fase!=F_DUPLI) { if( (*base)->object->transflag & OB_DUPLI) { - make_duplilist(G.scene, (*base)->object); - dupob= duplilist.first; + duplilist= object_duplilist(G.scene, (*base)->object); + + dupob= duplilist->first; } } /* handle dupli's */ if(dupob) { - *ob= dupob; + Mat4CpyMat4(dupob->ob->obmat, dupob->mat); + + (*base)->flag |= OB_FROMDUPLI; + *ob= dupob->ob; fase= F_DUPLI; - dupob= dupob->id.next; + dupob= dupob->next; } else if(fase==F_DUPLI) { fase= F_SCENE; - free_duplilist(); + (*base)->flag &= ~OB_FROMDUPLI; + + for(dupob= duplilist->first; dupob; dupob= dupob->next) { + Mat4CpyMat4(dupob->ob->obmat, dupob->omat); + } + + BLI_freelistN(duplilist); + duplilist= NULL; run_again= 1; } - } } } |