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