diff --git a/source/blender/editors/mesh/editmesh_select_similar.c b/source/blender/editors/mesh/editmesh_select_similar.c index 317111dde75..5e8e36c578a 100644 --- a/source/blender/editors/mesh/editmesh_select_similar.c +++ b/source/blender/editors/mesh/editmesh_select_similar.c @@ -123,6 +123,8 @@ bool select_similar_operator_has_data_mode(wmOperator *op) switch (type) { case SIMFACE_AREA: case SIMFACE_PERIMETER: + case SIMEDGE_LENGTH: + case SIMEDGE_DIR: return true; default: return false; @@ -197,7 +199,11 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) const float thresh_radians = thresh * (float)M_PI; const int compare = RNA_enum_get(op->ptr, "compare"); const int selection_mode = RNA_enum_get(op->ptr, "selection_mode"); - const int data_mode = RNA_enum_get(op->ptr, "data_mode"); + int data_mode = RNA_enum_get(op->ptr, "data_mode"); + + if (!select_similar_operator_has_data_mode(op)) { + data_mode = SIM_DATA_MODE_MESH; + } int tot_faces_selected_all = 0; uint objects_len = 0; @@ -343,7 +349,8 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) area = BM_face_calc_area_with_mat3(face, ob_m3); } else { - area = BM_face_calc_area_uv(face, cd_loop_uv_offset);} + area = BM_face_calc_area_uv(face, cd_loop_uv_offset); + } BLI_kdtree_1d_insert(tree_1d, tree_index++, &area); break; } @@ -602,7 +609,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) BM_face_select_set(bm, face, true); } else { - uvedit_face_select_enable(scene, em, face, true, cd_loop_uv_offset); + uvedit_face_select_enable(scene, em, face, false, cd_loop_uv_offset); } changed = true; } @@ -637,7 +644,7 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) } else { if (!uvedit_face_select_test(scene, face, cd_loop_uv_offset)) { - uvedit_face_select_enable(scene, em, face, true, cd_loop_uv_offset); + uvedit_face_select_enable(scene, em, face, false, cd_loop_uv_offset); } } } @@ -765,6 +772,7 @@ static bool edge_data_value_set(BMEdge *edge, const int hflag, int *r_value) static int similar_edge_select_exec(bContext *C, wmOperator *op) { ViewLayer *view_layer = CTX_data_view_layer(C); + Image *ima = CTX_data_edit_image(C); Scene *scene = CTX_data_scene(C); const int type = RNA_enum_get(op->ptr, "type"); @@ -772,7 +780,11 @@ static int similar_edge_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"); const int selection_mode = RNA_enum_get(op->ptr, "selection_mode"); - const int data_mode = RNA_enum_get(op->ptr, "data_mode"); + int data_mode = RNA_enum_get(op->ptr, "data_mode"); + + if (!select_similar_operator_has_data_mode(op)) { + data_mode = SIM_DATA_MODE_MESH; + } int custom_data_type = -1; @@ -794,16 +806,46 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *ob = objects[ob_index]; BMEditMesh *em = BKE_editmesh_from_object(ob); - if (selection_mode == SIM_DATA_MODE_MESH) { + if (selection_mode == SIM_DATA_MODE_MESH && data_mode == SIM_DATA_MODE_MESH) { tot_edges_selected_all += em->bm->totedgesel; } + else if (selection_mode == SIM_DATA_MODE_MESH && data_mode == SIM_DATA_MODE_UV) { + /* Counting loops of selected edges. */ + BMEdge *edge; + BMLoop *loop; + BMIter iter, iter2; + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + BM_ITER_MESH (edge, &iter, em->bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(edge, BM_ELEM_SELECT)) { + BM_ITER_ELEM (loop, &iter2, edge, BM_LOOPS_OF_EDGE) { + tot_edges_selected_all++; + } + } + } + } + else if (selection_mode == SIM_DATA_MODE_UV && data_mode == SIM_DATA_MODE_MESH) { + /* Counting edges with at least one selected loop. */ + BMEdge *edge; + BMLoop *loop; + BMIter iter, iter2; + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + BM_ITER_MESH (edge, &iter, em->bm, BM_EDGES_OF_MESH) { + BM_ITER_ELEM (loop, &iter2, edge, BM_LOOPS_OF_EDGE) { + if (uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { + tot_edges_selected_all++; + break; + } + } + } + } else { - BMFace *face; + /* Counting selected loops. */ + BMEdge *edge; BMLoop *loop; - BMIter iter1, iter2; + BMIter iter, iter2; const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); - BM_ITER_MESH (face, &iter1, em->bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM (loop, &iter2, face, BM_LOOPS_OF_FACE) { + BM_ITER_MESH (edge, &iter, em->bm, BM_EDGES_OF_MESH) { + BM_ITER_ELEM (loop, &iter2, edge, BM_LOOPS_OF_EDGE) { if (uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { tot_edges_selected_all++; } @@ -831,7 +873,7 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) tree_1d = BLI_kdtree_1d_new(tot_edges_selected_all); break; case SIMEDGE_DIR: - if (selection_mode == SIM_DATA_MODE_MESH && data_mode == SIM_DATA_MODE_MESH) + if (data_mode == SIM_DATA_MODE_MESH) tree_3d = BLI_kdtree_3d_new(tot_edges_selected_all); else tree_1d = BLI_kdtree_1d_new(tot_edges_selected_all); @@ -884,127 +926,107 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - if (selection_mode == SIM_DATA_MODE_MESH) { - 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)) { - switch (type) { - case SIMEDGE_FACE: - BLI_gset_add(gset, POINTER_FROM_INT(BM_edge_face_count(edge))); - break; - case SIMEDGE_DIR: { + BMEdge *edge; /* Mesh edge. */ + BMIter iter; /* Selected edges iterator. */ + BM_ITER_MESH (edge, &iter, bm, BM_EDGES_OF_MESH) { + BMLoop *loop; + BMIter iter2; + if (selection_mode == SIM_DATA_MODE_MESH) { + if (!BM_elem_flag_test(edge, BM_ELEM_SELECT)) { + continue; + } + } + else if (data_mode == SIM_DATA_MODE_MESH) { + bool selected = false; + BM_ITER_ELEM (loop, &iter2, edge, BM_LOOPS_OF_EDGE) { + if (uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { + /* One selected uv edge is enough, others share the same data anyway. */ + selected = true; + break; + } + } + if (!selected) { + continue; + } + } + else { + /* Testing each uv edge individually. */ + } + { + switch (type) { + case SIMEDGE_FACE: + BLI_gset_add(gset, POINTER_FROM_INT(BM_edge_face_count(edge))); + break; + case SIMEDGE_DIR: { + if (data_mode == SIM_DATA_MODE_MESH) { float dir[3]; edge_pos_direction_worldspace_get(ob, edge, dir); BLI_kdtree_3d_insert(tree_3d, tree_index++, dir); - break; } - case SIMEDGE_LENGTH: { + else { + BM_ITER_ELEM (loop, &iter2, edge, BM_LOOPS_OF_EDGE) { + if (selection_mode == SIM_DATA_MODE_MESH || + uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { + const float dir = (edge_direction_uvspace_get(loop, cd_loop_uv_offset)); + BLI_kdtree_1d_insert(tree_1d, tree_index++, &dir); + } + } + } + break; + } + case SIMEDGE_LENGTH: { + if (data_mode == SIM_DATA_MODE_MESH) { float length = edge_length_squared_worldspace_get(ob, edge); BLI_kdtree_1d_insert(tree_1d, tree_index++, &length); - break; - } - case SIMEDGE_FACE_ANGLE: { - if (BM_edge_face_count_at_most(edge, 2) == 2) { - float angle = BM_edge_calc_face_angle_with_imat3(edge, ob_m3_inv); - BLI_kdtree_1d_insert(tree_1d, tree_index++, &angle); - } - break; } - case SIMEDGE_SEAM: - if (!edge_data_value_set(edge, BM_ELEM_SEAM, &edge_data_value)) { - goto edge_select_all; - } - break; - case SIMEDGE_SHARP: - if (!edge_data_value_set(edge, BM_ELEM_SMOOTH, &edge_data_value)) { - goto edge_select_all; - } - break; - case SIMEDGE_FREESTYLE: { - FreestyleEdge *fedge; - fedge = CustomData_bmesh_get(&bm->edata, edge->head.data, CD_FREESTYLE_EDGE); - if ((fedge == NULL) || ((fedge->flag & FREESTYLE_EDGE_MARK) == 0)) { - edge_data_value |= SIMEDGE_DATA_FALSE; - } - else { - edge_data_value |= SIMEDGE_DATA_TRUE; - } - if (edge_data_value == SIMEDGE_DATA_ALL) { - goto edge_select_all; + else { + BM_ITER_ELEM (loop, &iter2, edge, BM_LOOPS_OF_EDGE) { + if (selection_mode == SIM_DATA_MODE_MESH || + uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { + const float length = edge_length_uvspace_get(loop, cd_loop_uv_offset); + BLI_kdtree_1d_insert(tree_1d, tree_index++, &length); + } } - break; } - case SIMEDGE_CREASE: - case SIMEDGE_BEVEL: { - const float *value = CustomData_bmesh_get( - &bm->edata, edge->head.data, custom_data_type); - BLI_kdtree_1d_insert(tree_1d, tree_index++, value); - break; + break; + } + case SIMEDGE_FACE_ANGLE: { + if (BM_edge_face_count_at_most(edge, 2) == 2) { + float angle = BM_edge_calc_face_angle_with_imat3(edge, ob_m3_inv); + BLI_kdtree_1d_insert(tree_1d, tree_index++, &angle); } + break; } - } - } - } else { - BMFace *face; - BMLoop *loop; - BMIter iter1, iter2; - BM_ITER_MESH (face, &iter1, em->bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM(loop, &iter2, face, BM_LOOPS_OF_FACE) { - if (uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { - switch (type) { - case SIMEDGE_FACE: -// BLI_gset_add(gset, POINTER_FROM_INT(BM_edge_face_count(edge))); - break; - case SIMEDGE_DIR: { - const float dir = (edge_direction_uvspace_get(loop, cd_loop_uv_offset)); - BLI_kdtree_1d_insert(tree_1d, tree_index++, &dir); - break; - } - case SIMEDGE_LENGTH: { - const float length = edge_length_uvspace_get(loop, cd_loop_uv_offset); - BLI_kdtree_1d_insert(tree_1d, tree_index++, &length); - break; - } - case SIMEDGE_FACE_ANGLE: { -// (BM_edge_face_count_at_most(edge, 2) == 2) { -// float angle = BM_edge_calc_face_angle_with_imat3(edge, ob_m3_inv); -// BLI_kdtree_1d_insert(tree_1d, tree_index++, &angle); -// } - break; - } - case SIMEDGE_SEAM: - if (!edge_data_value_set(loop->e, BM_ELEM_SEAM, &edge_data_value)) { - goto edge_select_all; - } - break; - case SIMEDGE_SHARP: - if (!edge_data_value_set(loop->e, BM_ELEM_SMOOTH, &edge_data_value)) { - goto edge_select_all; - } - break; - case SIMEDGE_FREESTYLE: { - FreestyleEdge *fedge; - fedge = CustomData_bmesh_get(&bm->edata, loop->e->head.data, CD_FREESTYLE_EDGE); - if ((fedge == NULL) || ((fedge->flag & FREESTYLE_EDGE_MARK) == 0)) { - edge_data_value |= SIMEDGE_DATA_FALSE; - } - else { - edge_data_value |= SIMEDGE_DATA_TRUE; - } - if (edge_data_value == SIMEDGE_DATA_ALL) { - goto edge_select_all; - } - break; - } - case SIMEDGE_CREASE: - case SIMEDGE_BEVEL: { -// const float *value = CustomData_bmesh_get( -// &bm->edata, edge->head.data, custom_data_type); -// BLI_kdtree_1d_insert(tree_1d, tree_index++, value); - break; - } + case SIMEDGE_SEAM: + if (!edge_data_value_set(edge, BM_ELEM_SEAM, &edge_data_value)) { + goto edge_select_all; + } + break; + case SIMEDGE_SHARP: + if (!edge_data_value_set(edge, BM_ELEM_SMOOTH, &edge_data_value)) { + goto edge_select_all; } + break; + case SIMEDGE_FREESTYLE: { + FreestyleEdge *fedge; + fedge = CustomData_bmesh_get(&bm->edata, edge->head.data, CD_FREESTYLE_EDGE); + if ((fedge == NULL) || ((fedge->flag & FREESTYLE_EDGE_MARK) == 0)) { + edge_data_value |= SIMEDGE_DATA_FALSE; + } + else { + edge_data_value |= SIMEDGE_DATA_TRUE; + } + if (edge_data_value == SIMEDGE_DATA_ALL) { + goto edge_select_all; + } + break; + } + case SIMEDGE_CREASE: + case SIMEDGE_BEVEL: { + const float *value = CustomData_bmesh_get( + &bm->edata, edge->head.data, custom_data_type); + BLI_kdtree_1d_insert(tree_1d, tree_index++, value); + break; } } } @@ -1057,27 +1079,35 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - if (data_mode == SIM_DATA_MODE_MESH && selection_mode == SIM_DATA_MODE_MESH) { - 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_elem_flag_test(edge, BM_ELEM_HIDDEN)) { - bool select = false; - switch (type) { - case SIMEDGE_FACE: { - const int num_faces = BM_edge_face_count(edge); - GSetIterator gs_iter; - GSET_ITER (gs_iter, gset) { - const int num_faces_iter = POINTER_AS_INT(BLI_gsetIterator_getKey(&gs_iter)); - const int delta_i = num_faces - num_faces_iter; - if (mesh_select_similar_compare_int(delta_i, compare)) { - select = true; - break; - } + BMEdge *edge; /* Mesh edge. */ + BMLoop *loop; + BMIter iter; /* Selected edges iterator. */ + BMIter iter2; + + BM_ITER_MESH (edge, &iter, bm, BM_EDGES_OF_MESH) { + if (selection_mode == SIM_DATA_MODE_MESH) { + if (BM_elem_flag_test(edge, BM_ELEM_SELECT) || BM_elem_flag_test(edge, BM_ELEM_HIDDEN)) { + continue; + } + } + { + bool select = false; + switch (type) { + case SIMEDGE_FACE: { + const int num_faces = BM_edge_face_count(edge); + GSetIterator gs_iter; + GSET_ITER (gs_iter, gset) { + const int num_faces_iter = POINTER_AS_INT(BLI_gsetIterator_getKey(&gs_iter)); + const int delta_i = num_faces - num_faces_iter; + if (mesh_select_similar_compare_int(delta_i, compare)) { + select = true; + break; } - break; } - case SIMEDGE_DIR: { + break; + } + case SIMEDGE_DIR: { + if (data_mode == SIM_DATA_MODE_MESH) { float dir[3]; edge_pos_direction_worldspace_get(ob, edge, dir); @@ -1089,168 +1119,123 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) select = true; } } - break; } - case SIMEDGE_LENGTH: { + else { + BM_ITER_ELEM (loop, &iter2, edge, BM_LOOPS_OF_EDGE) { + /* An uv edge has the same visibility as its face. */ + if (uvedit_face_visible_test(scene, ob, ima, loop->f) && + !uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { + const float dir = (edge_direction_uvspace_get(loop, cd_loop_uv_offset)); + if (ED_select_similar_compare_float_tree( + tree_1d, dir, thresh_radians, compare)) { + if (selection_mode == SIM_DATA_MODE_MESH) { + select = true; + break; + } + else { + uvedit_edge_select_enable(em, scene, loop, false, cd_loop_uv_offset); + changed = true; + } + } + } + } + } + break; + } + case SIMEDGE_LENGTH: { + if (data_mode == SIM_DATA_MODE_MESH) { float length = edge_length_squared_worldspace_get(ob, edge); if (ED_select_similar_compare_float_tree(tree_1d, length, thresh, compare)) { select = true; } - break; } - case SIMEDGE_FACE_ANGLE: { - if (BM_edge_face_count_at_most(edge, 2) == 2) { - float angle = BM_edge_calc_face_angle_with_imat3(edge, ob_m3_inv); - if (ED_select_similar_compare_float_tree(tree_1d, angle, thresh, SIM_CMP_EQ)) { - select = true; + else { + BM_ITER_ELEM (loop, &iter2, edge, BM_LOOPS_OF_EDGE) { + if (uvedit_face_visible_test(scene, ob, ima, loop->f) && + !uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { + const float length = edge_length_uvspace_get(loop, cd_loop_uv_offset); + if (ED_select_similar_compare_float_tree(tree_1d, length, thresh, compare)) { + if (selection_mode == SIM_DATA_MODE_MESH) { + select = true; + break; + } + else { + uvedit_edge_select_enable(em, scene, loop, false, cd_loop_uv_offset); + changed = true; + } + } } } - 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; - case SIMEDGE_FREESTYLE: { - FreestyleEdge *fedge; - - if (!has_custom_data_layer) { - BLI_assert(edge_data_value == SIMEDGE_DATA_FALSE); + break; + } + case SIMEDGE_FACE_ANGLE: { + if (BM_edge_face_count_at_most(edge, 2) == 2) { + float angle = BM_edge_calc_face_angle_with_imat3(edge, ob_m3_inv); + if (ED_select_similar_compare_float_tree(tree_1d, angle, thresh, SIM_CMP_EQ)) { select = true; - break; } + } + 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; + case SIMEDGE_FREESTYLE: { + FreestyleEdge *fedge; - fedge = CustomData_bmesh_get(&bm->edata, edge->head.data, CD_FREESTYLE_EDGE); - if (((fedge != NULL) && (fedge->flag & FREESTYLE_EDGE_MARK)) == - ((edge_data_value & SIMEDGE_DATA_TRUE) != 0)) { - select = true; - } + if (!has_custom_data_layer) { + BLI_assert(edge_data_value == SIMEDGE_DATA_FALSE); + select = true; break; } - case SIMEDGE_CREASE: - case SIMEDGE_BEVEL: { - if (!has_custom_data_layer) { - select = true; - break; - } - const float *value = CustomData_bmesh_get( - &bm->edata, edge->head.data, custom_data_type); - if (ED_select_similar_compare_float_tree(tree_1d, *value, thresh, compare)) { - select = true; - } + fedge = CustomData_bmesh_get(&bm->edata, edge->head.data, CD_FREESTYLE_EDGE); + if (((fedge != NULL) && (fedge->flag & FREESTYLE_EDGE_MARK)) == + ((edge_data_value & SIMEDGE_DATA_TRUE) != 0)) { + select = true; + } + break; + } + case SIMEDGE_CREASE: + case SIMEDGE_BEVEL: { + if (!has_custom_data_layer) { + select = true; break; } + + const float *value = CustomData_bmesh_get( + &bm->edata, edge->head.data, custom_data_type); + if (ED_select_similar_compare_float_tree(tree_1d, *value, thresh, compare)) { + select = true; + } + break; } + } - if (select) { + if (select) { + if (selection_mode == SIM_DATA_MODE_MESH) { BM_edge_select_set(bm, edge, true); changed = true; } - } - } - } else { - BMFace *face; - BMLoop *loop; - BMIter iter1, iter2; - BM_ITER_MESH (face, &iter1, em->bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM(loop, &iter2, face, BM_LOOPS_OF_FACE) { - if (!uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { - bool select = false; - switch (type) { - case SIMEDGE_FACE: { -// const int num_faces = BM_edge_face_count(edge); -// GSetIterator gs_iter; -// GSET_ITER (gs_iter, gset) { -// const int num_faces_iter = POINTER_AS_INT(BLI_gsetIterator_getKey(&gs_iter)); -// const int delta_i = num_faces - num_faces_iter; -// if (mesh_select_similar_compare_int(delta_i, compare)) { -// select = true; -// break; -// } -// } - break; - } - case SIMEDGE_DIR: { - const float dir = (edge_direction_uvspace_get(loop, cd_loop_uv_offset)); - if (ED_select_similar_compare_float_tree(tree_1d, dir, thresh_radians, compare)) { - select = true; - } - break; - } - case SIMEDGE_LENGTH: { - const float length = edge_length_uvspace_get(loop, cd_loop_uv_offset); - if (ED_select_similar_compare_float_tree(tree_1d, length, thresh, compare)) { - select = true; - } - break; - } - case SIMEDGE_FACE_ANGLE: { -// if (BM_edge_face_count_at_most(edge, 2) == 2) { -// float angle = BM_edge_calc_face_angle_with_imat3(edge, ob_m3_inv); -// if (ED_select_similar_compare_float_tree(tree_1d, angle, thresh, SIM_CMP_EQ)) { -// select = true; -// } -// } - 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; - case SIMEDGE_FREESTYLE: { -// FreestyleEdge *fedge; -// -// if (!has_custom_data_layer) { -// BLI_assert(edge_data_value == SIMEDGE_DATA_FALSE); -// select = true; -// break; -// } -// -// fedge = CustomData_bmesh_get(&bm->edata, edge->head.data, CD_FREESTYLE_EDGE); -// if (((fedge != NULL) && (fedge->flag & FREESTYLE_EDGE_MARK)) == -// ((edge_data_value & SIMEDGE_DATA_TRUE) != 0)) { -// select = true; -// } - break; - } - case SIMEDGE_CREASE: - case SIMEDGE_BEVEL: { -// if (!has_custom_data_layer) { -// select = true; -// break; -// } -// -// const float *value = CustomData_bmesh_get( -// &bm->edata, edge->head.data, custom_data_type); -// if (ED_select_similar_compare_float_tree(tree_1d, *value, thresh, compare)) { -// select = true; -// } - break; + else { + BLI_assert(selection_mode == SIM_DATA_MODE_UV && data_mode == SIM_DATA_MODE_MESH); + BM_ITER_ELEM (loop, &iter2, edge, BM_LOOPS_OF_EDGE) { + if (uvedit_face_visible_test(scene, ob, ima, loop->f) && + !uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { + uvedit_edge_select_enable(em, scene, loop, false, cd_loop_uv_offset); + changed = true; } } - - if (select) { - uvedit_edge_select_enable(em, scene, loop, true, cd_loop_uv_offset); - } - - changed = true; } } } @@ -1280,16 +1265,17 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) BM_edge_select_set(bm, edge, true); } } - } else { - BMFace *face; + } + else { + BMEdge *edge; BMLoop *loop; BMIter iter1, iter2; const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); - BM_ITER_MESH (face, &iter1, bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM(loop, &iter2, face, BM_LOOPS_OF_FACE) { + BM_ITER_MESH (edge, &iter1, bm, BM_EDGES_OF_MESH) { + BM_ITER_ELEM (loop, &iter2, edge, BM_LOOPS_OF_EDGE) { if (!uvedit_edge_select_test(scene, loop, cd_loop_uv_offset)) { - uvedit_edge_select_enable(em, scene, loop, true, cd_loop_uv_offset); + uvedit_edge_select_enable(em, scene, loop, false, cd_loop_uv_offset); } } } @@ -1687,6 +1673,12 @@ void MESH_OT_select_similar(wmOperatorType *ot) RNA_def_float(ot->srna, "threshold", 0.0f, 0.0f, 1.0f, "Threshold", "", 0.0f, 1.0f); + RNA_def_float(ot->srna, + "threshold_multiplier", + 0.001f, 0.0f, 1.0f, + "Threshold Multiplier", + "", 0.0f, 1.0f); + prop = RNA_def_enum( ot->srna, "data_mode", prop_similar_data_mode_types, SIM_DATA_MODE_MESH, "Data Source", "");