diff options
author | Campbell Barton <ideasman42@gmail.com> | 2018-03-06 11:13:41 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2018-03-06 11:13:41 +0300 |
commit | a5a0dcec902d6bbff0fe0fc1bb7fb21045823166 (patch) | |
tree | 3d155f73d865b418a1e59889587223b2a9e2b6aa /source/blender | |
parent | dd611dd0b87a36ffafb04177ec923e3b6d76bf71 (diff) | |
parent | b5b5260464fbba81610f26d4e04e5aedeef8cfd6 (diff) |
Merge branch 'master' into blender2.8
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_object_deform.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object_deform.c | 64 | ||||
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 22 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_array.c | 32 |
4 files changed, 102 insertions, 19 deletions
diff --git a/source/blender/blenkernel/BKE_object_deform.h b/source/blender/blenkernel/BKE_object_deform.h index 19a2220006a..ab54330cf53 100644 --- a/source/blender/blenkernel/BKE_object_deform.h +++ b/source/blender/blenkernel/BKE_object_deform.h @@ -54,7 +54,8 @@ void BKE_object_defgroup_remove(struct Object *ob, struct bDeformGroup *defgroup void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked); void BKE_object_defgroup_remove_all(struct Object *ob); - +int *BKE_object_defgroup_index_map_create(struct Object *ob_src, struct Object *ob_dst, int *r_map_len); +void BKE_object_defgroup_index_map_apply(struct MDeformVert *dvert, int dvert_len, const int *map, int map_len); /* Select helpers */ enum eVGroupSelect; diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c index ffe45d42677..fb2e824b299 100644 --- a/source/blender/blenkernel/intern/object_deform.c +++ b/source/blender/blenkernel/intern/object_deform.c @@ -460,6 +460,70 @@ void BKE_object_defgroup_remove_all(struct Object *ob) BKE_object_defgroup_remove_all_ex(ob, false); } +/** + * Compute mapping for vertex groups with matching name, -1 is used for no remapping. + * Returns null if no remapping is required. + * The returned array has to be freed. + */ +int *BKE_object_defgroup_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len) +{ + /* Build src to merged mapping of vgroup indices. */ + if (BLI_listbase_is_empty(&ob_src->defbase) || BLI_listbase_is_empty(&ob_dst->defbase)) { + *r_map_len = 0; + return NULL; + } + + bDeformGroup *dg_src; + *r_map_len = BLI_listbase_count(&ob_src->defbase); + int *vgroup_index_map = MEM_malloc_arrayN(*r_map_len, sizeof(*vgroup_index_map), "defgroup index map create"); + bool is_vgroup_remap_needed = false; + int i; + + for (dg_src = ob_src->defbase.first, i = 0; dg_src; dg_src = dg_src->next, i++) { + vgroup_index_map[i] = defgroup_name_index(ob_dst, dg_src->name); + is_vgroup_remap_needed = is_vgroup_remap_needed || (vgroup_index_map[i] != i); + } + + if (!is_vgroup_remap_needed) { + MEM_freeN(vgroup_index_map); + vgroup_index_map = NULL; + *r_map_len = 0; + } + + return vgroup_index_map; +} + +void BKE_object_defgroup_index_map_apply(MDeformVert *dvert, int dvert_len, const int *map, int map_len) +{ + if (map == NULL || map_len == 0) { + return; + } + + MDeformVert *dv = dvert; + for (int i = 0; i < dvert_len; i++, dv++) { + int totweight = dv->totweight; + for (int j = 0; j < totweight; j++) { + int def_nr = dv->dw[j].def_nr; + if ((uint)def_nr < (uint)map_len && map[def_nr] != -1) { + dv->dw[j].def_nr = map[def_nr]; + } + else { + totweight--; + dv->dw[j] = dv->dw[totweight]; + j--; + } + } + if (totweight != dv->totweight) { + if (totweight) { + dv->dw = MEM_reallocN(dv->dw, sizeof(*dv->dw) * totweight); + } + else { + MEM_SAFE_FREE(dv->dw); + } + dv->totweight = totweight; + } + } +} /** * Get MDeformVert vgroup data from given object. Should only be used in Object mode. diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 64b6f5b8010..4daa4a23470 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -58,6 +58,7 @@ #include "BKE_mesh.h" #include "BKE_material.h" #include "BKE_object.h" +#include "BKE_object_deform.h" #include "BKE_report.h" #include "BKE_editmesh.h" #include "BKE_multires.h" @@ -117,21 +118,12 @@ static void join_mesh_single( BLI_assert(dvert != NULL); /* Build src to merged mapping of vgroup indices. */ - bDeformGroup *dg_src; - int *vgroup_index_map = alloca(sizeof(*vgroup_index_map) * BLI_listbase_count(&ob_src->defbase)); - bool is_vgroup_remap_needed = false; - - for (dg_src = ob_src->defbase.first, b = 0; dg_src; dg_src = dg_src->next, b++) { - vgroup_index_map[b] = defgroup_name_index(ob_dst, dg_src->name); - is_vgroup_remap_needed = is_vgroup_remap_needed || (vgroup_index_map[b] != b); - } - - if (is_vgroup_remap_needed) { - for (a = 0; a < me->totvert; a++) { - for (b = 0; b < dvert[a].totweight; b++) { - dvert[a].dw[b].def_nr = vgroup_index_map[dvert_src[a].dw[b].def_nr]; - } - } + int *vgroup_index_map; + int vgroup_index_map_len; + vgroup_index_map = BKE_object_defgroup_index_map_create(ob_src, ob_dst, &vgroup_index_map_len); + BKE_object_defgroup_index_map_apply(dvert, me->totvert, vgroup_index_map, vgroup_index_map_len); + if (vgroup_index_map != NULL) { + MEM_freeN(vgroup_index_map); } } diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 7a7a4c4bdad..f598667f96d 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -51,6 +51,7 @@ #include "BKE_library_query.h" #include "BKE_modifier.h" #include "BKE_mesh.h" +#include "BKE_object_deform.h" #include "MOD_util.h" @@ -275,7 +276,7 @@ static void dm_mvert_map_doubles( static void dm_merge_transform( DerivedMesh *result, DerivedMesh *cap_dm, float cap_offset[4][4], unsigned int cap_verts_index, unsigned int cap_edges_index, int cap_loops_index, int cap_polys_index, - int cap_nverts, int cap_nedges, int cap_nloops, int cap_npolys) + int cap_nverts, int cap_nedges, int cap_nloops, int cap_npolys, int *remap, int remap_len) { int *index_orig; int i; @@ -283,6 +284,7 @@ static void dm_merge_transform( MEdge *me; MLoop *ml; MPoly *mp; + MDeformVert *dvert; /* needed for subsurf so arrays are allocated */ cap_dm->getVertArray(cap_dm); @@ -303,6 +305,12 @@ static void dm_merge_transform( mv->flag = mv->bweight = 0; } + /* remap the vertex groups if necessary */ + dvert = DM_get_vert_data(result, cap_verts_index, CD_MDEFORMVERT); + if (dvert != NULL) { + BKE_object_defgroup_index_map_apply(dvert, cap_nverts, remap, remap_len); + } + /* adjust cap edge vertex indices */ me = CDDM_get_edges(result) + cap_edges_index; for (i = 0; i < cap_nedges; i++, me++) { @@ -379,6 +387,11 @@ static DerivedMesh *arrayModifier_doArray( DerivedMesh *result, *start_cap_dm = NULL, *end_cap_dm = NULL; + int *vgroup_start_cap_remap = NULL; + int vgroup_start_cap_remap_len = 0; + int *vgroup_end_cap_remap = NULL; + int vgroup_end_cap_remap_len = 0; + chunk_nverts = dm->getNumVerts(dm); chunk_nedges = dm->getNumEdges(dm); chunk_nloops = dm->getNumLoops(dm); @@ -387,6 +400,8 @@ static DerivedMesh *arrayModifier_doArray( count = amd->count; if (amd->start_cap && amd->start_cap != ob && amd->start_cap->type == OB_MESH) { + vgroup_start_cap_remap = BKE_object_defgroup_index_map_create(amd->start_cap, ob, &vgroup_start_cap_remap_len); + start_cap_dm = get_dm_for_modifier(amd->start_cap, flag); if (start_cap_dm) { start_cap_nverts = start_cap_dm->getNumVerts(start_cap_dm); @@ -396,6 +411,8 @@ static DerivedMesh *arrayModifier_doArray( } } if (amd->end_cap && amd->end_cap != ob && amd->end_cap->type == OB_MESH) { + vgroup_end_cap_remap = BKE_object_defgroup_index_map_create(amd->end_cap, ob, &vgroup_end_cap_remap_len); + end_cap_dm = get_dm_for_modifier(amd->end_cap, flag); if (end_cap_dm) { end_cap_nverts = end_cap_dm->getNumVerts(end_cap_dm); @@ -652,7 +669,8 @@ static DerivedMesh *arrayModifier_doArray( result_nedges - start_cap_nedges - end_cap_nedges, result_nloops - start_cap_nloops - end_cap_nloops, result_npolys - start_cap_npolys - end_cap_npolys, - start_cap_nverts, start_cap_nedges, start_cap_nloops, start_cap_npolys); + start_cap_nverts, start_cap_nedges, start_cap_nloops, start_cap_npolys, + vgroup_start_cap_remap, vgroup_start_cap_remap_len); /* Identify doubles with first chunk */ if (use_merge) { dm_mvert_map_doubles( @@ -676,7 +694,8 @@ static DerivedMesh *arrayModifier_doArray( result_nedges - end_cap_nedges, result_nloops - end_cap_nloops, result_npolys - end_cap_npolys, - end_cap_nverts, end_cap_nedges, end_cap_nloops, end_cap_npolys); + end_cap_nverts, end_cap_nedges, end_cap_nloops, end_cap_npolys, + vgroup_end_cap_remap, vgroup_end_cap_remap_len); /* Identify doubles with last chunk */ if (use_merge) { dm_mvert_map_doubles( @@ -724,6 +743,13 @@ static DerivedMesh *arrayModifier_doArray( result->dirty |= DM_DIRTY_NORMALS; } + if (vgroup_start_cap_remap) { + MEM_freeN(vgroup_start_cap_remap); + } + if (vgroup_end_cap_remap) { + MEM_freeN(vgroup_end_cap_remap); + } + return result; } |