Commit: 39b0c6f0605ef7b448a0ffab66eaaa50f047ded5
Author: Bastien Montagne
Date:   Tue Jun 20 17:53:59 2017 +0200
Branches: id_copy_refactor
https://developer.blender.org/rB39b0c6f0605ef7b448a0ffab66eaaa50f047ded5

Add Mesh and Key support to new copying code.

===================================================================

M       source/blender/blenkernel/BKE_key.h
M       source/blender/blenkernel/BKE_mesh.h
M       source/blender/blenkernel/intern/key.c
M       source/blender/blenkernel/intern/library.c
M       source/blender/blenkernel/intern/mesh.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_key.h 
b/source/blender/blenkernel/BKE_key.h
index 94e8a24fbc5..20abb4b5331 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -51,6 +51,7 @@ extern "C" {
 void        BKE_key_free(struct Key *sc);
 void        BKE_key_free_nolib(struct Key *key);
 struct Key *BKE_key_add(struct ID *id);
+void BKE_key_copy_ex(struct Main *bmain, struct Key *key_dst, const struct Key 
*key_src, const int flag);
 struct Key *BKE_key_copy(struct Main *bmain, const struct Key *key);
 struct Key *BKE_key_copy_nolib(struct Key *key);
 void        BKE_key_sort(struct Key *key);
diff --git a/source/blender/blenkernel/BKE_mesh.h 
b/source/blender/blenkernel/BKE_mesh.h
index 2411850c0d2..24762761952 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -87,6 +87,7 @@ int BKE_mesh_edge_other_vert(const struct MEdge *e, int v);
 void BKE_mesh_free(struct Mesh *me);
 void BKE_mesh_init(struct Mesh *me);
 struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name);
+void BKE_mesh_copy_ex(struct Main *bmain, struct Mesh *me_dst, const struct 
Mesh *me_src, const int flag);
 struct Mesh *BKE_mesh_copy(struct Main *bmain, const struct Mesh *me);
 void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool 
do_ensure_tess_cd);
 void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
diff --git a/source/blender/blenkernel/intern/key.c 
b/source/blender/blenkernel/intern/key.c
index 98b251294ae..6ec5daceef8 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -151,31 +151,38 @@ Key *BKE_key_add(ID *id)    /* common function */
        return key;
 }
 
-Key *BKE_key_copy(Main *bmain, const Key *key)
+/**
+ * Only copy internal data of ShapeKey ID from source to already 
allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or 
BKE_id_copy_ex for typical needs.
+ *
+ * @param flag  Copying options (see BKE_library.h's LIB_ID_COPY_... flags for 
more).
+ */
+void BKE_key_copy_ex(Main *UNUSED(bmain), Key *key_dst, const Key *key_src, 
const int UNUSED(flag))
 {
-       Key *keyn;
-       KeyBlock *kbn, *kb;
-       
-       keyn = BKE_libblock_copy(bmain, &key->id);
-       
-       BLI_duplicatelist(&keyn->block, &key->block);
-       
-       kb = key->block.first;
-       kbn = keyn->block.first;
-       while (kbn) {
-               
-               if (kbn->data) kbn->data = MEM_dupallocN(kbn->data);
-               if (kb == key->refkey) keyn->refkey = kbn;
-               
-               kbn = kbn->next;
-               kb = kb->next;
-       }
+       BLI_duplicatelist(&key_dst->block, &key_src->block);
 
-       BKE_id_copy_ensure_local(bmain, &key->id, &keyn->id);
+       KeyBlock *kb_dst, *kb_src;
+       for (kb_src = key_src->block.first, kb_dst = key_dst->block.first;
+            kb_dst;
+            kb_src = kb_src->next, kb_dst = kb_dst->next)
+       {
+               if (kb_dst->data) {
+                       kb_dst->data = MEM_dupallocN(kb_dst->data);
+               }
+               if (kb_src == key_src->refkey) {
+                       key_dst->refkey = kb_dst;
+               }
+       }
+}
 
-       return keyn;
+Key *BKE_key_copy(Main *bmain, const Key *key)
+{
+       Key *key_copy;
+       BKE_id_copy_ex(bmain, &key->id, (ID **)&key_copy, 0, false);
+       return key_copy;
 }
 
+/* XXX TODO get rid of this! */
 Key *BKE_key_copy_nolib(Key *key)
 {
        Key *keyn;
diff --git a/source/blender/blenkernel/intern/library.c 
b/source/blender/blenkernel/intern/library.c
index b008604a29b..356f86cbca6 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -532,7 +532,7 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID 
**r_newid, const int flag, con
 
        if (!test) {
                /* Check to be removed of course, just here until all 
BKE_xxx_copy_ex functions are done. */
-               if (ELEM(GS(id->name), ID_OB)) {
+               if (ELEM(GS(id->name), ID_OB, ID_ME, ID_KE)) {
                        BKE_libblock_copy_ex(bmain, id, r_newid, flag);
                }
        }
@@ -542,7 +542,7 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID 
**r_newid, const int flag, con
                        if (!test) BKE_object_copy_ex(bmain, (Object 
*)*r_newid, (Object *)id, flag_idtype_copy);
                        break;
                case ID_ME:
-                       if (!test) *r_newid = (ID *)BKE_mesh_copy(bmain, (Mesh 
*)id);
+                       if (!test) BKE_mesh_copy_ex(bmain, (Mesh *)*r_newid, 
(Mesh *)id, flag_idtype_copy);
                        break;
                case ID_CU:
                        if (!test) *r_newid = (ID *)BKE_curve_copy(bmain, 
(Curve *)id);
@@ -572,7 +572,7 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID 
**r_newid, const int flag, con
                        if (!test) *r_newid = (ID *)BKE_camera_copy(bmain, 
(Camera *)id);
                        break;
                case ID_KE:
-                       if (!test) *r_newid = (ID *)BKE_key_copy(bmain, (Key 
*)id);
+                       if (!test) BKE_key_copy_ex(bmain, (Key *)*r_newid, (Key 
*)id, flag_idtype_copy);
                        break;
                case ID_WO:
                        if (!test) *r_newid = (ID *)BKE_world_copy(bmain, 
(World *)id);
@@ -633,12 +633,25 @@ bool BKE_id_copy_ex(Main *bmain, const ID *id, ID 
**r_newid, const int flag, con
 
        if (!test) {
                /* Check to be removed of course, just here until all 
BKE_xxx_copy_ex functions are done. */
-               if (ELEM(GS(id->name), ID_OB)) {
+               if (ELEM(GS(id->name), ID_OB, ID_ME, ID_KE)) {
                        /* Update ID refcount, remap pointers to self in new 
ID. */
                        struct IDCopyLibManagementData data = {.id_src=id, 
.flag=flag};
                        BKE_library_foreach_ID_link(bmain, *r_newid, 
id_copy_libmanagement_cb, &data, IDWALK_NOP);
 
-                       BKE_id_copy_ensure_local(bmain, id, *r_newid);
+                       /* Grrrrrrrrrrrrr..............
+                        * Since we call IDType-spefici copying logic without 
'userrefcount' flag, we need to redo this here.
+                        * Note/TODO: maybe we'll make IDType copying functions 
'private' to be only used by this one,
+                        * in which case we could solve this issue in a better 
and nicer way. */
+                       Key *key = BKE_key_from_id(*r_newid);
+                       if (key) {
+                               data.id_src = BKE_key_from_id((ID *)id);
+                               BKE_library_foreach_ID_link(bmain, &key->id, 
id_copy_libmanagement_cb, &data, IDWALK_NOP);
+                       }
+                       /* TODO: most likely same for nodes too? */
+
+                       if ((flag & LIB_ID_COPY_NO_MAIN) == 0) {
+                               BKE_id_copy_ensure_local(bmain, id, *r_newid);
+                       }
                }
        }
 
diff --git a/source/blender/blenkernel/intern/mesh.c 
b/source/blender/blenkernel/intern/mesh.c
index 6e4ae451606..979da27cecf 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -501,46 +501,55 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name)
        return me;
 }
 
-Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me)
+/**
+ * Only copy internal data of Mesh ID from source to already 
allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or 
BKE_id_copy_ex for typical needs.
+ *
+ * @param flag  Copying options (see BKE_library.h's LIB_ID_COPY_... flags for 
more).
+ */
+void BKE_mesh_copy_ex(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int 
flag)
 {
-       Mesh *men;
        int a;
-       const int do_tessface = ((me->totface != 0) && (me->totpoly == 0)); /* 
only do tessface if we have no polys */
-       
-       men = BKE_libblock_copy(bmain, &me->id);
+       const bool do_tessface = ((me_src->totface != 0) && (me_src->totpoly == 
0)); /* only do tessface if we have no polys */
        
-       men->mat = MEM_dupallocN(me->mat);
-       for (a = 0; a < men->totcol; a++) {
-               id_us_plus((ID *)men->mat[a]);
+       me_dst->mat = MEM_dupallocN(me_src->mat);
+
+       if ((flag & LIB_ID_COPY_NO_USER_REFCOUNT) == 0) {
+               for (a = 0; a < me_dst->totcol; a++) {
+                       id_us_plus((ID *)me_dst->mat[a]);
+               }
+               id_us_plus((ID *)me_dst->texcomesh);
        }
-       id_us_plus((ID *)men->texcomesh);
 
-       CustomData_copy(&me->vdata, &men->vdata, CD_MASK_MESH, CD_DUPLICATE, 
men->totvert);
-       CustomData_copy(&me->edata, &men->edata, CD_MASK_MESH, CD_DUPLICATE, 
men->totedge);
-       CustomData_copy(&me->ldata, &men->ldata, CD_MASK_MESH, CD_DUPLICATE, 
men->totloop);
-       CustomData_copy(&me->pdata, &men->pdata, CD_MASK_MESH, CD_DUPLICATE, 
men->totpoly);
+       CustomData_copy(&me_src->vdata, &me_dst->vdata, CD_MASK_MESH, 
CD_DUPLICATE, me_dst->totvert);
+       CustomData_copy(&me_src->edata, &me_dst->edata, CD_MASK_MESH, 
CD_DUPLICATE, me_dst->totedge);
+       CustomData_copy(&me_src->ldata, &me_dst->ldata, CD_MASK_MESH, 
CD_DUPLICATE, me_dst->totloop);
+       CustomData_copy(&me_src->pdata, &me_dst->pdata, CD_MASK_MESH, 
CD_DUPLICATE, me_dst->totpoly);
        if (do_tessface) {
-               CustomData_copy(&me->fdata, &men->fdata, CD_MASK_MESH, 
CD_DUPLICATE, men->totface);
+               CustomData_copy(&me_src->fdata, &me_dst->fdata, CD_MASK_MESH, 
CD_DUPLICATE, me_dst->totface);
        }
        else {
-               mesh_tessface_clear_intern(men, false);
+               mesh_tessface_clear_intern(me_dst, false);
        }
 
-       BKE_mesh_update_customdata_pointers(men, do_tessface);
+       BKE_mesh_update_customdata_pointers(me_dst, do_tessface);
 
-       men->edit_btmesh = NULL;
+       me_dst->edit_btmesh = NULL;
 
-       men->mselect = MEM_dupallocN(men->mselect);
-       men->bb = MEM_dupallocN(men->bb);
+       me_dst->mselect = MEM_dupallocN(me_dst->mselect);
+       me_dst->bb = MEM_dupallocN(me_dst->bb);
 
-       if (me->key) {
-               men->key = BKE_key_copy(bmain, me->key);
-               men->key->from = (ID *)men;
+       /* TODO Do we want to add flag to prevent this? */
+       if (me_src->key) {
+               BKE_id_copy_ex(bmain, &me_src->key->id, (ID **)&me_dst->key, 
flag, false);
        }
+}
 
-       BKE_id_copy_ensure_local(bmain, &me->id, &men->id);
-
-       return men;
+Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me)
+{
+       Mesh *me_copy;
+       BKE_id_copy_ex(bmain, &me->id, (ID **)&me_copy, 0, false);
+       return me_copy;
 }
 
 BMesh *BKE_mesh_to_bmesh(

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to