diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2018-09-21 21:31:05 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2018-09-21 21:33:09 +0300 |
commit | e8ec01dbb5ddb6dd1abc1293b2337add7dee8806 (patch) | |
tree | af1853ea9588aae6d98d5161b6c1f60aacf2dd5d /source/blender/editors | |
parent | d5f94b49bd988665b4070e02664851fd5339c73a (diff) |
Multi-Objects: Select similar edge SIMEDGE_SEAM/SIMEDGE_SHARP
I'm not sure why we may want to sample both a sharp and an unsharp edges at the
same time, maybe to see if the selected edges all have the same values?
Either way, implemented as in 2.79. I also believe we may have a faster way to
select all the edges, but let's file this under optimizations to be done later.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/mesh/editmesh_select_similar.c | 77 |
1 files changed, 73 insertions, 4 deletions
diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c index 47cb5770197..2cb432cd61b 100644 --- a/source/blender/editors/mesh/editmesh_select_similar.c +++ b/source/blender/editors/mesh/editmesh_select_similar.c @@ -258,6 +258,30 @@ static float edge_length_squared_worldspace_get(Object *ob, BMEdge *edge) { return len_squared_v3v3(v1, v2); } +enum { + SIMEDGE_DATA_NONE = 0, + SIMEDGE_DATA_TRUE = (1 << 0), + SIMEDGE_DATA_FALSE = (1 << 1), + SIMEDGE_DATA_ALL = (SIMEDGE_DATA_TRUE | SIMEDGE_DATA_FALSE), +}; + +/** + * Return true if we still don't know the final value for this edge data. + * In other words, if we need to keep iterating over the objects or we can + * just go ahead and select all the objects. + */ +static bool edge_data_value_set(BMEdge *edge, const int hflag, int *r_value) +{ + if (BM_elem_flag_test(edge, hflag)) { + *r_value |= SIMEDGE_DATA_TRUE; + } + else { + *r_value |= SIMEDGE_DATA_FALSE; + } + + return *r_value != SIMEDGE_DATA_ALL; +} + /* Note/TODO(dfelinto) technically SIMEDGE_FACE_ANGLE should compare the angles in world space. * Although doable this is overkill - at least for the initial multi-objects implementation. */ static int similar_edge_select_exec(bContext *C, wmOperator *op) @@ -271,13 +295,11 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) const int compare = RNA_enum_get(op->ptr, "compare"); if (ELEM(type, - SIMEDGE_CREASE, - SIMEDGE_BEVEL, - SIMEDGE_SEAM, #ifdef WITH_FREESTYLE SIMEDGE_FREESTYLE, #endif - SIMEDGE_SHARP)) + SIMEDGE_CREASE, + SIMEDGE_BEVEL)) { /* TODO (dfelinto) port the edge modes to multi-object. */ BKE_report(op->reports, RPT_ERROR, "Select similar edge mode not supported at the moment"); @@ -302,6 +324,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) KDTree *tree = NULL; GSet *gset = NULL; + int edge_data_value = SIMEDGE_DATA_NONE; switch (type) { case SIMEDGE_FACE_ANGLE: @@ -356,6 +379,16 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) } break; } + case SIMEDGE_SEAM: + if (!edge_data_value_set(edge, BM_ELEM_SEAM, &edge_data_value)) { + goto selectall; + } + break; + case SIMEDGE_SHARP: + if (!edge_data_value_set(edge, BM_ELEM_SMOOTH, &edge_data_value)) { + goto selectall; + } + break; } } } @@ -426,6 +459,20 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) } break; } + case SIMEDGE_SEAM: + if ((BM_elem_flag_test(edge, BM_ELEM_SEAM) != 0) == + ((edge_data_value & SIMEDGE_DATA_TRUE) != 0)) + { + select = true; + } + break; + case SIMEDGE_SHARP: + if ((BM_elem_flag_test(edge, BM_ELEM_SMOOTH) != 0) == + ((edge_data_value & SIMEDGE_DATA_TRUE) != 0)) + { + select = true; + } + break; } if (select) { @@ -441,6 +488,28 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) } } + if (false) { +selectall: + BLI_assert(ELEM(type, SIMEDGE_SEAM, SIMEDGE_SHARP)); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *ob = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(ob); + BMesh *bm = em->bm; + + BMEdge *edge; /* Mesh edge. */ + BMIter iter; /* Selected edges iterator. */ + + BM_ITER_MESH (edge, &iter, bm, BM_EDGES_OF_MESH) { + if (!BM_elem_flag_test(edge, BM_ELEM_SELECT)) { + BM_edge_select_set(bm, edge, true); + } + } + EDBM_selectmode_flush(em); + EDBM_update_generic(em, false, false); + } + } + MEM_freeN(objects); BLI_kdtree_free(tree); if (gset != NULL) { |