]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/beam.cc
Fixes cross staff issue with beam collision avoidance.
[lilypond.git] / lily / beam.cc
index 6fbd71d7d6a6d4ddcda0a7fbd7782f8e6eef43c4..c6cd26143e124fe2e0ca7eecce967cd1284576ed 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "beam.hh"
 
+#include "align-interface.hh"
 #include "beam-scoring-problem.hh"
 #include "beaming-pattern.hh"
 #include "directional-element-interface.hh"
@@ -1204,7 +1205,15 @@ Beam::shift_region_to_valid (SCM grob, SCM posns)
     {
       if (!covered[i]->is_live())
         continue;
-      
+
+      // TODO - use this logic in is_cross_staff.
+      if (is_cross_staff (me)
+          && Align_interface::has_interface (common_refpoint_of_array (stems, me, Y_AXIS)))
+        continue;
+
+      if (Beam::has_interface (covered[i]) && is_cross_staff (covered[i]))
+        continue;
+
       Box b;
       for (Axis a = X_AXIS; a < NO_AXES; incr (a))
         b[a] = covered[i]->extent (common[a], a);
@@ -1299,13 +1308,24 @@ Beam::shift_region_to_valid (SCM grob, SCM posns)
     {
       // We're good to go. Do nothing.
     }
+  else if (collision_free[DOWN].is_empty() != collision_free[UP].is_empty())
+    {
+      // Only one of them offers is feasible solution. Pick that one.
+      Interval v =
+        (!collision_free[DOWN].is_empty()) ?
+        collision_free[DOWN] : 
+        collision_free[UP];
+
+      beam_left_y = point_in_interval (v, 2.0);
+    }
   else if (!collision_free[DOWN].is_empty ()
-           || !collision_free[UP].is_empty ())
+           && !collision_free[UP].is_empty ())
     {
-      // We have space above or below collisions (or, no collisions at
-      // all).
+      // Above and below are candidates, take the one closest to the
+      // starting solution.
       Interval best =  
-        (collision_free[DOWN].length () > collision_free[UP].length ()) ?
+        (collision_free[DOWN].distance (beam_left_y)
+         < collision_free[UP].distance (beam_left_y)) ?
         collision_free[DOWN] : collision_free[UP];
 
       beam_left_y = point_in_interval (best, 2.0);
@@ -1818,6 +1838,8 @@ ADD_INTERFACE (Beam,
               "break-overshoot "
               "clip-edges "
               "concaveness "
+              "collision-interfaces "
+              "collision-voice-only "
               "covered-grobs "
               "damping "
               "details "