Commit: 3b9b324bf619a2c2d3cd8d25d5a0f95b7b0c476c
Author: Campbell Barton
Date:   Wed Mar 20 00:34:40 2019 +1100
Branches: master
https://developer.blender.org/rB3b9b324bf619a2c2d3cd8d25d5a0f95b7b0c476c

Fix T62595: Select co-planar faces fails

===================================================================

M       source/blender/editors/mesh/editmesh_select_similar.c

===================================================================

diff --git a/source/blender/editors/mesh/editmesh_select_similar.c 
b/source/blender/editors/mesh/editmesh_select_similar.c
index c9dea33dc78..299db63eca3 100644
--- a/source/blender/editors/mesh/editmesh_select_similar.c
+++ b/source/blender/editors/mesh/editmesh_select_similar.c
@@ -143,35 +143,15 @@ static bool face_data_value_set(BMFace *face, const int 
hflag, int *r_value)
  * Also, unlike edge_pos_direction_worldspace_get we don't normalize the 
direction.
  * In fact we scale the direction by the distance of the face center to the 
origin.
  */
-static void face_pos_direction_worldspace_scaled_get(Object *ob, BMFace *face, 
float *r_dir)
+static void face_to_plane(const Object *ob, BMFace *face, float r_plane[4])
 {
-       float distance;
-       float center[3];
+       float normal[3], co[3];
+       copy_v3_v3(normal, face->no);
+       mul_transposed_mat3_m4_v3(ob->imat, normal);
+       normalize_v3(normal);
+       mul_v3_m4v3(co, ob->obmat, BM_FACE_FIRST_LOOP(face)->v->co);
+       plane_from_point_normal_v3(r_plane, co, normal);
 
-       copy_v3_v3(r_dir, face->no);
-       normalize_v3(r_dir);
-
-       BM_face_calc_center_median(face, center);
-       mul_m4_v3(ob->obmat, center);
-
-       distance = dot_v3v3(r_dir, center);
-       mul_v3_fl(r_dir, distance);
-
-       /* Make sure we have a consistent direction regardless of the face 
orientation.
-        * This spares us from storing dir and -dir in the tree. */
-       if (fabs(r_dir[2]) < FLT_EPSILON) {
-               if (fabs(r_dir[1]) < FLT_EPSILON) {
-                       if (r_dir[0] < 0.0f) {
-                               mul_v3_fl(r_dir, -1.0f);
-                       }
-               }
-               else if (r_dir[1] < 0.0f) {
-                       mul_v3_fl(r_dir, -1.0f);
-               }
-       }
-       else if (r_dir[2] < 0.0f) {
-               mul_v3_fl(r_dir, -1.0f);
-       }
 }
 
 /* TODO(dfelinto): `types` that should technically be compared in world space 
but are not:
@@ -204,6 +184,7 @@ static int similar_face_select_exec(bContext *C, wmOperator 
*op)
        }
 
        KDTree *tree = NULL;
+       KDTree_4d *tree_plane = NULL;
        GSet *gset = NULL;
        GSet **gset_array = NULL;
        int face_data_value = SIMFACE_DATA_NONE;
@@ -212,9 +193,11 @@ static int similar_face_select_exec(bContext *C, 
wmOperator *op)
                case SIMFACE_AREA:
                case SIMFACE_PERIMETER:
                case SIMFACE_NORMAL:
-               case SIMFACE_COPLANAR:
                        tree = BLI_kdtree_new(tot_faces_selected_all);
                        break;
+               case SIMFACE_COPLANAR:
+                       tree_plane = BLI_kdtree_4d_new(tot_faces_selected_all);
+                       break;
                case SIMFACE_SIDES:
                case SIMFACE_MATERIAL:
                        gset = BLI_gset_ptr_new("Select similar face");
@@ -312,9 +295,9 @@ static int similar_face_select_exec(bContext *C, wmOperator 
*op)
                                        }
                                        case SIMFACE_COPLANAR:
                                        {
-                                               float dir[3];
-                                               
face_pos_direction_worldspace_scaled_get(ob, face, dir);
-                                               BLI_kdtree_insert(tree, 
tree_index++, dir);
+                                               float plane[4];
+                                               face_to_plane(ob, face, plane);
+                                               
BLI_kdtree_4d_insert(tree_plane, tree_index++, plane);
                                                break;
                                        }
                                        case SIMFACE_SMOOTH:
@@ -356,6 +339,9 @@ static int similar_face_select_exec(bContext *C, wmOperator 
*op)
        if (tree != NULL) {
                BLI_kdtree_balance(tree);
        }
+       if (tree_plane != NULL) {
+               BLI_kdtree_4d_balance(tree_plane);
+       }
 
        for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
                Object *ob = objects[ob_index];
@@ -470,19 +456,15 @@ static int similar_face_select_exec(bContext *C, 
wmOperator *op)
                                        }
                                        case SIMFACE_COPLANAR:
                                        {
-                                               float diff[3];
-                                               float dir[3];
-                                               
face_pos_direction_worldspace_scaled_get(ob, face, dir);
-
-                                               /* We are treating the 
direction as coordinates, the "nearest" one will
-                                                * also be the one closest to 
the angle.
-                                                * And since the direction is 
scaled by the face center distance to the origin,
-                                                * the nearest point will also 
be the closest between the planes. */
-                                               KDTreeNearest nearest;
-                                               if 
(BLI_kdtree_find_nearest(tree, dir, &nearest) != -1) {
-                                                       sub_v3_v3v3(diff, dir, 
nearest.co);
-                                                       if (len_v3(diff) <= 
thresh) {
-                                                               if 
(angle_v3v3(dir, nearest.co) <= thresh_radians) {
+                                               float plane[4];
+                                               face_to_plane(ob, face, plane);
+
+                                               KDTreeNearest_4d nearest;
+                                               if 
(BLI_kdtree_4d_find_nearest(tree_plane, plane, &nearest) != -1) {
+                                                       if (nearest.dist <= 
thresh) {
+                                                               if 
((fabsf(plane[3] - nearest.co[3]) <= thresh) &&
+                                                                   
(angle_v3v3(plane, nearest.co) <= thresh_radians))
+                                                               {
                                                                        select 
= true;
                                                                }
                                                        }
@@ -569,6 +551,7 @@ face_select_all:
 
        MEM_freeN(objects);
        BLI_kdtree_free(tree);
+       BLI_kdtree_4d_free(tree_plane);
        if (gset != NULL) {
                BLI_gset_free(gset, NULL);
        }

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to