Commit: 2b4bafeac68ea6fbb7b42760c9fc864d094d67f8 Author: Chris Blackbourn Date: Fri Jan 27 17:52:31 2023 +1300 Branches: master https://developer.blender.org/rB2b4bafeac68ea6fbb7b42760c9fc864d094d67f8
UV: add "similar object" and "similar winding" to uv "select similar" Adds new options to UV Face selection in the UV Editor, with UV > Select > Select Similar In multi object edit mode, "Similar Object" selects faces which have the same object. "Similar Winding" will select faces which have the same winding, i.e. are they facing upwards or downwards. Resolves: T103975 Differential Revision: https://developer.blender.org/D17125 =================================================================== M source/blender/bmesh/intern/bmesh_polygon.c M source/blender/bmesh/intern/bmesh_polygon.h M source/blender/editors/uvedit/uvedit_select.c =================================================================== diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index a2aecf80456..8b185b17a3a 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -225,20 +225,26 @@ float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3]) return len_v3(n) * 0.5f; } -float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset) +float BM_face_calc_area_uv_signed(const BMFace *f, int cd_loop_uv_offset) { /* inline 'area_poly_v2' logic, avoid creating a temp array */ const BMLoop *l_iter, *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(f); - /* The Trapezium Area Rule */ + /* Green's theorem applied to area of a polygon. + * TODO: `cross` should be of type `double` to reduce rounding error. */ float cross = 0.0f; do { const float *luv = BM_ELEM_CD_GET_FLOAT_P(l_iter, cd_loop_uv_offset); const float *luv_next = BM_ELEM_CD_GET_FLOAT_P(l_iter->next, cd_loop_uv_offset); cross += (luv_next[0] - luv[0]) * (luv_next[1] + luv[1]); } while ((l_iter = l_iter->next) != l_first); - return fabsf(cross * 0.5f); + return cross * 0.5f; +} + +float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset) +{ + return fabsf(BM_face_calc_area_uv_signed(f, cd_loop_uv_offset)); } float BM_face_calc_perimeter(const BMFace *f) diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index 6262f185eca..bff1d1d587d 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -73,7 +73,12 @@ float BM_face_calc_area(const BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); /** - * get the area of UV face + * Calculate the signed area of UV face. + */ +float BM_face_calc_area_uv_signed(const BMFace *f, int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT + ATTR_NONNULL(); +/** + * Calculate the area of UV face. */ float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(); diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index 50185049fe1..99ee1ca0002 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -87,9 +87,11 @@ typedef enum { UV_SSIM_FACE, UV_SSIM_LENGTH_UV, UV_SSIM_LENGTH_3D, - UV_SSIM_SIDES, - UV_SSIM_PIN, UV_SSIM_MATERIAL, + UV_SSIM_OBJECT, + UV_SSIM_PIN, + UV_SSIM_SIDES, + UV_SSIM_WINDING, } eUVSelectSimilar; /* -------------------------------------------------------------------- */ @@ -4633,6 +4635,7 @@ static float get_uv_edge_needle(const eUVSelectSimilar type, static float get_uv_face_needle(const eUVSelectSimilar type, BMFace *face, + int ob_index, const float ob_m3[3][3], const BMUVOffsets offsets) { @@ -4646,6 +4649,8 @@ static float get_uv_face_needle(const eUVSelectSimilar type, return BM_face_calc_area_with_mat3(face, ob_m3); case UV_SSIM_SIDES: return face->len; + case UV_SSIM_OBJECT: + return ob_index; case UV_SSIM_PIN: { BMLoop *l; BMIter liter; @@ -4657,6 +4662,8 @@ static float get_uv_face_needle(const eUVSelectSimilar type, } break; case UV_SSIM_MATERIAL: return face->mat_nr; + case UV_SSIM_WINDING: + return signum_i(BM_face_calc_area_uv_signed(face, offsets.uv)); default: BLI_assert_unreachable(); return false; @@ -4966,7 +4973,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op) continue; } - float needle = get_uv_face_needle(type, face, ob_m3, offsets); + float needle = get_uv_face_needle(type, face, ob_index, ob_m3, offsets); if (tree_1d) { BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle); } @@ -5000,7 +5007,7 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op) continue; } - float needle = get_uv_face_needle(type, face, ob_m3, offsets); + float needle = get_uv_face_needle(type, face, ob_index, ob_m3, offsets); bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare); if (select) { @@ -5180,8 +5187,10 @@ static EnumPropertyItem prop_edge_similar_types[] = { static EnumPropertyItem prop_face_similar_types[] = { {UV_SSIM_AREA_UV, "AREA", 0, "Area", ""}, {UV_SSIM_AREA_3D, "AREA_3D", 0, "Area 3D", ""}, - {UV_SSIM_SIDES, "SIDES", 0, "Polygon Sides", ""}, {UV_SSIM_MATERIAL, "MATERIAL", 0, "Material", ""}, + {UV_SSIM_OBJECT, "OBJECT", 0, "Object", ""}, + {UV_SSIM_SIDES, "SIDES", 0, "Polygon Sides", ""}, + {UV_SSIM_WINDING, "WINDING", 0, "Winding", ""}, {0}}; static EnumPropertyItem prop_island_similar_types[] = { _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs