[Bf-blender-cvs] [06e62adfb8f] master: UI: Improved "Area Close" Neighbor Selection

Harley Acheson noreply at git.blender.org
Thu May 13 01:53:58 CEST 2021


Commit: 06e62adfb8f2270f1d742ceebcd2d9fd830a528e
Author: Harley Acheson
Date:   Wed May 12 16:52:43 2021 -0700
Branches: master
https://developer.blender.org/rB06e62adfb8f2270f1d742ceebcd2d9fd830a528e

UI: Improved "Area Close" Neighbor Selection

The new "Close Area" operator can let any neighbor replace the area to
be closed. This patch improves the selection of the best, and most-
aligned, neighbor.  It maximizes the ratio of the shared edge lengths,
rather than minimize the absolute amount of misalignment. This follows
our expectations closer because it takes into account the relative
sizes of the areas and their edges.

see D11143 for details and examples.

Differential Revision: https://developer.blender.org/D11143

Reviewed by Campbell Barton

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

M	source/blender/editors/screen/screen_edit.c

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

diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 75aa709a5d1..554bfa6fd3f 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -534,7 +534,7 @@ int screen_area_join(bContext *C, bScreen *screen, ScrArea *sa1, ScrArea *sa2)
   return screen_area_join_ex(C, screen, sa1, sa2, false);
 }
 
-/* Close a screen area, allowing any neighbor to take its place. */
+/* Close a screen area, allowing most-aligned neighbor to take its place. */
 bool screen_area_close(struct bContext *C, bScreen *screen, ScrArea *area)
 {
   if (area == NULL) {
@@ -542,32 +542,27 @@ bool screen_area_close(struct bContext *C, bScreen *screen, ScrArea *area)
   }
 
   ScrArea *sa2 = NULL;
-
-  /* Find the most-aligned joinable area. Larger size breaks ties. */
-  int min_alignment = INT_MAX;
-  int max_size = 0;
-  LISTBASE_FOREACH (ScrArea *, ar, &screen->areabase) {
-    int dir = area_getorientation(area, ar);
-    if (dir != -1) {
-      int offset1;
-      int offset2;
-      area_getoffsets(area, ar, dir, &offset1, &offset2);
-      int area_alignment = abs(offset1) + abs(offset2);
-      if (area_alignment < min_alignment) {
-        min_alignment = area_alignment;
-        max_size = ar->winx * ar->winy;
-        sa2 = ar;
-      }
-      else if (area_alignment == min_alignment) {
-        int area_size = ar->winx * ar->winy;
-        if (area_size > max_size) {
-          max_size = area_size;
-          sa2 = ar;
-        }
+  float best_alignment = 0.0f;
+
+  LISTBASE_FOREACH (ScrArea *, neighbor, &screen->areabase) {
+    int dir = area_getorientation(area, neighbor);
+    /* Must at least partially share an edge and not be a global area. */
+    if (dir != -1 && !neighbor->global) {
+      /* Winx/Winy might not be updated yet, so get lengths from verts. */
+      int area_length = ELEM(dir, 1, 3) ? area->v3->vec.x - area->v1->vec.x :
+                                          area->v3->vec.y - area->v1->vec.y;
+      int ar_length = ELEM(dir, 1, 3) ? neighbor->v3->vec.x - neighbor->v1->vec.x :
+                                        neighbor->v3->vec.y - neighbor->v1->vec.y;
+      /* Calculate the ratio of the lengths of the shared edges. */
+      float alignment = MIN2(area_length, ar_length) / (float)MAX2(area_length, ar_length);
+      if (alignment > best_alignment) {
+        best_alignment = alignment;
+        sa2 = neighbor;
       }
     }
   }
 
+  /* Join from neighbor into this area to close it. */
   return screen_area_join_ex(C, screen, sa2, area, true);
 }



More information about the Bf-blender-cvs mailing list