bugfix [#24403] Object.copy() duplicates armature action
authorCampbell Barton <ideasman42@gmail.com>
Tue, 9 Nov 2010 09:53:17 +0000 (09:53 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 9 Nov 2010 09:53:17 +0000 (09:53 +0000)
now duplicating ID data wont duplicate actions by default and the user preference is used with duplicate operators.

source/blender/blenkernel/BKE_animsys.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/node.c
source/blender/blenkernel/intern/scene.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_relations.c

index af5e31b1efad57e56ab0873b8575205ae69d2c79..07ab0e7ec2c363e21a64192b9bde3a98b3517ce0 100644 (file)
@@ -56,10 +56,13 @@ struct AnimData *BKE_id_add_animdata(struct ID *id);
 void BKE_free_animdata(struct ID *id);
 
 /* Copy AnimData */
 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 */
 
 /* 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);
 
 /* Make Local */
 void BKE_animdata_make_local(struct AnimData *adt);
index d98fb082aa9110bd84119c2a6871e56b4beaa5a5..4f0238854efb7db6547574410f84509c047a4131 100644 (file)
@@ -46,7 +46,7 @@ struct bContext;
 
 void *alloc_libblock(struct ListBase *lb, short type, const char *name);
 void *copy_libblock(void *rt);
 
 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);
 
 void id_lib_extern(struct ID *id);
 void id_us_plus(struct ID *id);
index febe80053178181450218fdd4e14277f09c6ec6d..e50d4880fbef35557047eb596b65fe7227976c29 100644 (file)
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
+#include "BKE_library.h"
 #include "BLI_dynstr.h"
 
 #include "BLI_dynstr.h"
 
+
 #include "DNA_anim_types.h"
 #include "DNA_scene_types.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 */
 /* 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;
        
 {
        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= 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);
        
        /* duplicate NLA data */
        copy_nladata(&dadt->nla_tracks, &adt->nla_tracks);
        
@@ -201,7 +209,7 @@ AnimData *BKE_copy_animdata (AnimData *adt)
        return dadt;
 }
 
        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;
 
 {
        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;
        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;
 }
 
        }
 
        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 -------------------------------------------- */
 
 
 /* Make Local -------------------------------------------- */
 
index 34351f9b113e4798e1d1dd11c2c75594c264d834..c3bcb3dc69a68446139c63b8b06ab769e2be61d0 100644 (file)
@@ -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 */
 
 /* 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;
 {
        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 */
        }
 }
 
 /* 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 */
 {
        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 */
 }
 
 /* used everywhere in blenkernel */
@@ -665,7 +665,7 @@ void *copy_libblock(void *rt)
        id->newid= idn;
        idn->flag |= LIB_NEW;
 
        id->newid= idn;
        idn->flag |= LIB_NEW;
 
-       copy_libblock_data(idn, id);
+       copy_libblock_data(idn, id, FALSE);
        
        return idn;
 }
        
        return idn;
 }
index 6c4c566f5b194f0f1a6e8d9feadb1da95f8f8677..7b25c38648d51eec159d022af0ae280eacde059a 100644 (file)
@@ -1077,7 +1077,7 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree, int internal_select)
                        newtree= copy_libblock(ntree);
                } else {
                        newtree= MEM_dupallocN(ntree);
                        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;
                }
                newtree->nodes.first= newtree->nodes.last= NULL;
                newtree->links.first= newtree->links.last= NULL;
index e399e0bb83dc29250e0c4072e1753dee67ee1a24..df02b3d12d2982570a864010bf048525d6320cd7 100644 (file)
@@ -171,7 +171,7 @@ Scene *copy_scene(Scene *sce, int type)
                BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));
 
                if(sce->nodetree) {
                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);
                }
 
                        ntreeSwitchID(scen->nodetree, &sce->id, &scen->id);
                }
 
@@ -216,9 +216,11 @@ Scene *copy_scene(Scene *sce, int type)
 
        /* world */
        if(type == SCE_COPY_FULL) {
 
        /* 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);
                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) {
                }
 
                if(sce->ed) {
index dd0f041342fe6f00c4f4be5cd33259205f728b0c..b87792d98d3c7acc130a6ae1324e11c289df2703 100644 (file)
@@ -45,6 +45,7 @@
 #include "BLI_listbase.h"
 
 #include "BKE_anim.h"
 #include "BLI_listbase.h"
 
 #include "BKE_anim.h"
+#include "BKE_animsys.h"
 #include "BKE_armature.h"
 #include "BKE_constraint.h"
 #include "BKE_context.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
 #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; a<obn->totcol; a++) {
                                id= (ID *)obn->mat[a];
                if(dupflag & USER_DUP_MAT) {
                        for(a=0; a<obn->totcol; 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--;
                                        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(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--;
                                }
                        }
                                        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 )
                        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;
                                        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 )
                        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 )
                                        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;
                }
                                        id->us--;
                                }
                                break;
                }
-               
-               if(dupflag & USER_DUP_MAT) {
-                       matarar= give_matarar(obn);
-                       if(didit && matarar) {
-                               for(a=0; a<obn->totcol; 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; a<obn->totcol; a++) {
+                                               id= (ID *)(*matarar)[a];
+                                               if(id) {
+                                                       ID_NEW_US( (*matarar)[a] )
+                                                       else (*matarar)[a]= copy_material((*matarar)[a]);
+                                                       
+                                                       id->us--;
+                                               }
                                        }
                                }
                        }
                                        }
                                }
                        }
index c017895c0168f879cd67e5fbaf46f74d105c8572..36aa856aec6d9ceadcbfa21c835e7beae81f1a48 100644 (file)
@@ -1279,8 +1279,8 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
                                        }
                                        break;
                                case MAKE_LINKS_ANIMDATA:
                                        }
                                        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;
                                        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
                }
        }
 #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)
 }
 
 static void single_mat_users(Scene *scene, int flag, int do_textures)