Mesh: add option to select vertices by similar vertex crease

This adds an option to the "Select Similar" operator in edit mode to
select vertices based on vertex crease similarity. The implementation
follows that of the edge crease, with a 1-dimensional KD-tree used to
store and retrieve vertex indices base on crease values.

To maintain compatibility with old files (scripts), the `SIMEDGE_CREASE`
enumeration identifier remains `CREASE`, while the one for the new
`SIMVERT_CREASE` is `VCREASE` to follow the naming convention of other
enum values.

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D14037
This commit is contained in:
Kévin Dietrich 2022-02-08 06:10:13 +01:00
parent 7047bd41c6
commit 8abd8865d2
2 changed files with 46 additions and 0 deletions

View File

@ -93,6 +93,7 @@ enum {
SIMVERT_FACE,
SIMVERT_VGROUP,
SIMVERT_EDGE,
SIMVERT_CREASE,
};
/* Poke face center calculation */

View File

@ -68,6 +68,7 @@ static const EnumPropertyItem prop_similar_types[] = {
{SIMVERT_FACE, "FACE", 0, "Amount of Adjacent Faces", ""},
{SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""},
{SIMVERT_EDGE, "EDGE", 0, "Amount of Connecting Edges", ""},
{SIMVERT_CREASE, "VCREASE", 0, "Vertex Crease", ""},
{SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""},
{SIMEDGE_DIR, "DIR", 0, "Direction", ""},
@ -1009,12 +1010,16 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
}
KDTree_3d *tree_3d = NULL;
KDTree_1d *tree_1d = NULL;
GSet *gset = NULL;
switch (type) {
case SIMVERT_NORMAL:
tree_3d = BLI_kdtree_3d_new(tot_verts_selected_all);
break;
case SIMVERT_CREASE:
tree_1d = BLI_kdtree_1d_new(tot_verts_selected_all);
break;
case SIMVERT_EDGE:
case SIMVERT_FACE:
gset = BLI_gset_ptr_new("Select similar vertex: edge/face");
@ -1025,6 +1030,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
}
int normal_tree_index = 0;
int tree_1d_index = 0;
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
Object *ob = objects[ob_index];
BMEditMesh *em = BKE_editmesh_from_object(ob);
@ -1050,6 +1056,12 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
}
defbase_selected = BLI_BITMAP_NEW(defbase_len, __func__);
}
else if (type == SIMVERT_CREASE) {
if (!CustomData_has_layer(&bm->vdata, CD_CREASE)) {
BLI_kdtree_1d_insert(tree_1d, tree_1d_index++, (float[1]){0.0f});
continue;
}
}
BMVert *vert; /* Mesh vertex. */
BMIter iter; /* Selected verts iterator. */
@ -1085,6 +1097,11 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
}
break;
}
case SIMVERT_CREASE: {
const float *value = CustomData_bmesh_get(&bm->vdata, vert->head.data, CD_CREASE);
BLI_kdtree_1d_insert(tree_1d, tree_1d_index++, value);
break;
}
}
}
}
@ -1113,6 +1130,10 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
}
/* Remove duplicated entries. */
if (tree_1d != NULL) {
BLI_kdtree_1d_deduplicate(tree_1d);
BLI_kdtree_1d_balance(tree_1d);
}
if (tree_3d != NULL) {
BLI_kdtree_3d_deduplicate(tree_3d);
BLI_kdtree_3d_balance(tree_3d);
@ -1124,6 +1145,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(ob);
BMesh *bm = em->bm;
bool changed = false;
bool has_crease_layer = false;
int cd_dvert_offset = -1;
BLI_bitmap *defbase_selected = NULL;
int defbase_len = 0;
@ -1158,6 +1180,17 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
continue;
}
}
else if (type == SIMVERT_CREASE) {
has_crease_layer = CustomData_has_layer(&bm->vdata, CD_CREASE);
if (!has_crease_layer) {
/* Proceed only if we have to select all the vertices that have custom data value of 0.0f.
* In this case we will just select all the vertices.
* Otherwise continue the for loop. */
if (!ED_select_similar_compare_float_tree(tree_1d, 0.0f, thresh, compare)) {
continue;
}
}
}
BMVert *vert; /* Mesh vertex. */
BMIter iter; /* Selected verts iterator. */
@ -1224,6 +1257,17 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
}
break;
}
case SIMVERT_CREASE: {
if (!has_crease_layer) {
select = true;
break;
}
const float *value = CustomData_bmesh_get(&bm->vdata, vert->head.data, CD_CREASE);
if (ED_select_similar_compare_float_tree(tree_1d, *value, thresh, compare)) {
select = true;
}
break;
}
}
if (select) {
@ -1249,6 +1293,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
}
MEM_freeN(objects);
BLI_kdtree_1d_free(tree_1d);
BLI_kdtree_3d_free(tree_3d);
if (gset != NULL) {
BLI_gset_free(gset, NULL);