From 7a62c05204782c77cb02a6f133aed4dc116f7d70 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Nov 2010 09:53:17 +0000 Subject: bugfix [#24403] Object.copy() duplicates armature action now duplicating ID data wont duplicate actions by default and the user preference is used with duplicate operators. --- source/blender/blenkernel/BKE_animsys.h | 7 ++- source/blender/blenkernel/BKE_library.h | 2 +- source/blender/blenkernel/intern/anim_sys.c | 35 +++++++++--- source/blender/blenkernel/intern/library.c | 10 ++-- source/blender/blenkernel/intern/node.c | 2 +- source/blender/blenkernel/intern/scene.c | 4 +- source/blender/editors/object/object_add.c | 69 +++++++++++++++--------- source/blender/editors/object/object_relations.c | 6 ++- 8 files changed, 92 insertions(+), 43 deletions(-) diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h index af5e31b1efa..07ab0e7ec2c 100644 --- a/source/blender/blenkernel/BKE_animsys.h +++ b/source/blender/blenkernel/BKE_animsys.h @@ -56,10 +56,13 @@ struct AnimData *BKE_id_add_animdata(struct ID *id); void BKE_free_animdata(struct ID *id); /* Copy AnimData */ -struct AnimData *BKE_copy_animdata(struct AnimData *adt); +struct AnimData *BKE_copy_animdata(struct AnimData *adt, const short do_action); /* Copy AnimData */ -int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from); +int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const short do_action); + +/* Copy AnimData Actions */ +void BKE_copy_animdata_id_action(struct ID *id); /* Make Local */ void BKE_animdata_make_local(struct AnimData *adt); diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index d98fb082aa9..4f0238854ef 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -46,7 +46,7 @@ struct bContext; void *alloc_libblock(struct ListBase *lb, short type, const char *name); void *copy_libblock(void *rt); -void copy_libblock_data(struct ID *id, const struct ID *id_from); +void copy_libblock_data(struct ID *id, const struct ID *id_from, const short do_action); void id_lib_extern(struct ID *id); void id_us_plus(struct ID *id); diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index febe8005317..e50d4880fbe 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -36,8 +36,10 @@ #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BKE_library.h" #include "BLI_dynstr.h" + #include "DNA_anim_types.h" #include "DNA_scene_types.h" @@ -175,7 +177,7 @@ void BKE_free_animdata (ID *id) /* Freeing -------------------------------------------- */ /* Make a copy of the given AnimData - to be used when copying datablocks */ -AnimData *BKE_copy_animdata (AnimData *adt) +AnimData *BKE_copy_animdata (AnimData *adt, const short do_action) { AnimData *dadt; @@ -185,9 +187,15 @@ AnimData *BKE_copy_animdata (AnimData *adt) dadt= MEM_dupallocN(adt); /* make a copy of action - at worst, user has to delete copies... */ - dadt->action= copy_action(adt->action); - dadt->tmpact= copy_action(adt->tmpact); - + if(do_action) { + dadt->action= copy_action(adt->action); + dadt->tmpact= copy_action(adt->tmpact); + } + else { + id_us_plus((ID *)dadt->action); + id_us_plus((ID *)dadt->tmpact); + } + /* duplicate NLA data */ copy_nladata(&dadt->nla_tracks, &adt->nla_tracks); @@ -201,7 +209,7 @@ AnimData *BKE_copy_animdata (AnimData *adt) return dadt; } -int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from) +int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const short do_action) { AnimData *adt; @@ -213,13 +221,26 @@ int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from) adt = BKE_animdata_from_id(id_from); if (adt) { IdAdtTemplate *iat = (IdAdtTemplate *)id_to; - iat->adt= BKE_copy_animdata(adt); + iat->adt= BKE_copy_animdata(adt, do_action); } return 1; } - +void BKE_copy_animdata_id_action(struct ID *id) +{ + AnimData *adt= BKE_animdata_from_id(id); + if(adt) { + if(adt->action) { + ((ID *)adt->action)->us--; + adt->action= copy_action(adt->action); + } + if(adt->tmpact) { + ((ID *)adt->tmpact)->us--; + adt->tmpact= copy_action(adt->tmpact); + } + } +} /* Make Local -------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 34351f9b113..c3bcb3dc69a 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -620,24 +620,24 @@ void *alloc_libblock(ListBase *lb, short type, const char *name) /* by spec, animdata is first item after ID */ /* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */ -static void id_copy_animdata(ID *id) +static void id_copy_animdata(ID *id, const short do_action) { AnimData *adt= BKE_animdata_from_id(id); if (adt) { IdAdtTemplate *iat = (IdAdtTemplate *)id; - iat->adt= BKE_copy_animdata(iat->adt); + iat->adt= BKE_copy_animdata(iat->adt, do_action); /* could be set to FALSE, need to investigate */ } } /* material nodes use this since they are not treated as libdata */ -void copy_libblock_data(ID *id, const ID *id_from) +void copy_libblock_data(ID *id, const ID *id_from, const short do_action) { if (id_from->properties) id->properties = IDP_CopyProperty(id_from->properties); /* the duplicate should get a copy of the animdata */ - id_copy_animdata(id); + id_copy_animdata(id, do_action); } /* used everywhere in blenkernel */ @@ -665,7 +665,7 @@ void *copy_libblock(void *rt) id->newid= idn; idn->flag |= LIB_NEW; - copy_libblock_data(idn, id); + copy_libblock_data(idn, id, FALSE); return idn; } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 6c4c566f5b1..7b25c38648d 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1077,7 +1077,7 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select) newtree= copy_libblock(ntree); } else { newtree= MEM_dupallocN(ntree); - copy_libblock_data(&newtree->id, &ntree->id); /* copy animdata and ID props */ + copy_libblock_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */ } newtree->nodes.first= newtree->nodes.last= NULL; newtree->links.first= newtree->links.last= NULL; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index e399e0bb83d..df02b3d12d2 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -171,7 +171,7 @@ Scene *copy_scene(Scene *sce, int type) BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets)); if(sce->nodetree) { - scen->nodetree= ntreeCopyTree(sce->nodetree, 0); + scen->nodetree= ntreeCopyTree(sce->nodetree, 0); /* copies actions */ ntreeSwitchID(scen->nodetree, &sce->id, &scen->id); } @@ -216,9 +216,11 @@ Scene *copy_scene(Scene *sce, int type) /* world */ if(type == SCE_COPY_FULL) { + BKE_copy_animdata_id_action((ID *)scen); if(scen->world) { id_us_plus((ID *)scen->world); scen->world= copy_world(scen->world); + BKE_copy_animdata_id_action((ID *)scen->world); } if(sce->ed) { diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index dd0f041342f..b87792d98d3 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -45,6 +45,7 @@ #include "BLI_listbase.h" #include "BKE_anim.h" +#include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_constraint.h" #include "BKE_context.h" @@ -1445,17 +1446,12 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base } } } - if(dupflag & USER_DUP_ACT){ /* Not buttons in the UI to modify this, add later? */ - id= (ID *)obn->action; - if (id){ - ID_NEW_US(obn->action) - else{ - obn->action= copy_action(obn->action); - } - id->us--; - } - } #endif // XXX old animation system + + if(dupflag & USER_DUP_ACT) { + BKE_copy_animdata_id_action(&obn->id); + } + if(dupflag & USER_DUP_MAT) { for(a=0; atotcol; a++) { id= (ID *)obn->mat[a]; @@ -1463,6 +1459,10 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base ID_NEW_US(obn->mat[a]) else obn->mat[a]= copy_material(obn->mat[a]); id->us--; + + if(dupflag & USER_DUP_ACT) { + BKE_copy_animdata_id_action(&obn->mat[a]->id); + } } } } @@ -1473,6 +1473,11 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base if(id) { ID_NEW_US(psys->part) else psys->part= psys_copy_settings(psys->part); + + if(dupflag & USER_DUP_ACT) { + BKE_copy_animdata_id_action(&psys->part->id); + } + id->us--; } } @@ -1540,7 +1545,10 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base case OB_LAMP: if(dupflag & USER_DUP_LAMP) { ID_NEW_US2(obn->data ) - else obn->data= copy_lamp(obn->data); + else { + obn->data= copy_lamp(obn->data); + didit= 1; + } id->us--; } break; @@ -1564,29 +1572,42 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base case OB_LATTICE: if(dupflag!=0) { ID_NEW_US2(obn->data ) - else obn->data= copy_lattice(obn->data); + else { + obn->data= copy_lattice(obn->data); + didit= 1; + } id->us--; } break; case OB_CAMERA: if(dupflag!=0) { ID_NEW_US2(obn->data ) - else obn->data= copy_camera(obn->data); + else { + obn->data= copy_camera(obn->data); + didit= 1; + } id->us--; } break; } - - if(dupflag & USER_DUP_MAT) { - matarar= give_matarar(obn); - if(didit && matarar) { - for(a=0; atotcol; a++) { - id= (ID *)(*matarar)[a]; - if(id) { - ID_NEW_US( (*matarar)[a] ) - else (*matarar)[a]= copy_material((*matarar)[a]); - - id->us--; + + /* check if obdata is copied */ + if(didit) { + if(dupflag & USER_DUP_ACT) { + BKE_copy_animdata_id_action((ID *)obn->data); + } + + if(dupflag & USER_DUP_MAT) { + matarar= give_matarar(obn); + if(matarar) { + for(a=0; atotcol; a++) { + id= (ID *)(*matarar)[a]; + if(id) { + ID_NEW_US( (*matarar)[a] ) + else (*matarar)[a]= copy_material((*matarar)[a]); + + id->us--; + } } } } diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index c017895c016..36aa856aec6 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -1279,8 +1279,8 @@ static int make_links_data_exec(bContext *C, wmOperator *op) } break; case MAKE_LINKS_ANIMDATA: - BKE_copy_animdata_id((ID *)obt, (ID *)ob); - BKE_copy_animdata_id((ID *)obt->data, (ID *)ob->data); + BKE_copy_animdata_id((ID *)obt, (ID *)ob, FALSE); + BKE_copy_animdata_id((ID *)obt->data, (ID *)ob->data, FALSE); break; case MAKE_LINKS_DUPLIGROUP: obt->dup_group= ob->dup_group; @@ -1573,6 +1573,8 @@ void single_ipo_users(Scene *UNUSED(scene), int UNUSED(flag)) } } #endif // XXX old animation system + // TODO, something like this but must check users first. + // BKE_copy_animdata_id_action((ID *)obn->data); } static void single_mat_users(Scene *scene, int flag, int do_textures) -- cgit v1.2.3