diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2018-09-19 04:08:54 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2018-09-28 16:25:23 +0300 |
commit | 75b2091d42535d8815d5cd59812a2e793b6dca2c (patch) | |
tree | 608b9eb4165843ae7daee86336eaf10cf6f59e49 /source/blender/editors/mesh/editmesh_select_similar.c | |
parent | d2d0b4fcd7f0fdb42cfbbbc6b708a6748b4d474f (diff) |
Multi-Objects: Select similar vertex: SIMVERT_VGROUP
I'm storing the name of the vertex groups in a gset. This way
we can select vertex groups with the same name across different
objects.
Also this is the last select similar mode that needs porting o/
Diffstat (limited to 'source/blender/editors/mesh/editmesh_select_similar.c')
-rw-r--r-- | source/blender/editors/mesh/editmesh_select_similar.c | 89 |
1 files changed, 84 insertions, 5 deletions
diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c index b50e0735083..b3c96068d82 100644 --- a/source/blender/editors/mesh/editmesh_select_similar.c +++ b/source/blender/editors/mesh/editmesh_select_similar.c @@ -1072,11 +1072,6 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) const float thresh_radians = thresh * (float)M_PI + FLT_EPSILON; const int compare = RNA_enum_get(op->ptr, "compare"); - if (type == SIMVERT_VGROUP) { - BKE_report(op->reports, RPT_ERROR, "Select similar vertex groups not supported at the moment."); - return OPERATOR_CANCELLED; - } - int tot_verts_selected_all = 0; uint objects_len = 0; Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len); @@ -1104,6 +1099,9 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) case SIMVERT_FACE: gset = BLI_gset_ptr_new("Select similar vertex: edge/face"); break; + case SIMVERT_VGROUP: + gset = BLI_gset_str_new("Select similar vertex: vertex groups"); + break; } int normal_tree_index = 0; @@ -1111,12 +1109,21 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) Object *ob = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(ob); BMesh *bm = em->bm; + int cd_dvert_offset = -1; + int dvert_selected = 0; invert_m4_m4(ob->imat, ob->obmat); if (bm->totvertsel == 0) { continue; } + if (type == SIMVERT_VGROUP) { + cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT); + if (cd_dvert_offset == -1) { + continue; + } + } + BMVert *vert; /* Mesh vertex. */ BMIter iter; /* Selected verts iterator. */ @@ -1139,11 +1146,43 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) BLI_kdtree_insert(tree, normal_tree_index++, normal); break; } + case SIMVERT_VGROUP: + { + MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(vert, cd_dvert_offset); + MDeformWeight *dw = dvert->dw; + + for (int i = 0; i < dvert->totweight; i++, dw++) { + if (dw->weight > 0.0f) { + dvert_selected |= (1 << dw->def_nr); + } + } + break; + } + } + } + } + + if (type == SIMVERT_VGROUP) { + /* We store the names of the vertex groups, so we can select + * vertex groups with the same name in different objects. */ + const int dvert_tot = BLI_listbase_count(&ob->defbase); + for (int i = 0; i < dvert_tot; i++) { + if (dvert_selected & (1 << i)) { + bDeformGroup *dg = BLI_findlink(&ob->defbase, i); + BLI_gset_add(gset, dg->name); } } } } + if (type == SIMVERT_VGROUP) { + if (BLI_gset_len(gset) == 0) { + BKE_report(op->reports, + RPT_INFO, + "No vertex group among the selected vertices"); + } + } + /* Remove duplicated entries. */ if (tree != NULL) { BLI_kdtree_balance(tree); @@ -1155,6 +1194,31 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) BMEditMesh *em = BKE_editmesh_from_object(ob); BMesh *bm = em->bm; bool changed = false; + int cd_dvert_offset = -1; + int dvert_selected = 0; + + if (type == SIMVERT_VGROUP) { + cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT); + if (cd_dvert_offset == -1) { + continue; + } + + /* We map back the names of the vertex groups to their corresponsing indices + * for this object. This is fast, and keep the logic for each vertex very simple. */ + GSetIterator gs_iter; + GSET_ITER(gs_iter, gset) { + const char *name = BLI_gsetIterator_getKey(&gs_iter); + int vgroup_id = BLI_findstringindex(&ob->defbase, + name, + offsetof(bDeformGroup, name)); + if (vgroup_id != -1) { + dvert_selected |= (1 << vgroup_id); + } + } + if (dvert_selected == 0) { + continue; + } + } BMVert *vert; /* Mesh vertex. */ BMIter iter; /* Selected verts iterator. */ @@ -1210,6 +1274,21 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) } break; } + case SIMVERT_VGROUP: + { + MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(vert, cd_dvert_offset); + MDeformWeight *dw = dvert->dw; + + for (int i = 0; i < dvert->totweight; i++, dw++) { + if (dw->weight > 0.0f) { + if (dvert_selected & (1 << dw->def_nr)) { + select = true; + break; + } + } + } + break; + } } if (select) { |