]> git.donarmstrong.com Git - lilypond.git/blobdiff - lily/beam-collision-engraver.cc
Midi: start test suite.
[lilypond.git] / lily / beam-collision-engraver.cc
index 00e6494652417491de7c404d5dc2fed5df0005ab..39e614c2a15dea10f3b72f88110959c35dc389a1 100644 (file)
@@ -47,12 +47,22 @@ public:
 void
 Beam_collision_engraver::stop_translation_timestep ()
 {
+  /* 
+     First, for all grobs that fall to the left of a beam during
+     a timestep (i.e. clefs, time signatures), add these to
+     the beams that are currently active.
+  */
   for (vsize i = 0; i < covered_interior_grobs_.size (); i++)
     for (vsize j = 0; j < active_beams_.size (); j++)
       Pointer_group_interface::add_grob (active_beams_[j], ly_symbol2scm ("covered-grobs"), covered_interior_grobs_[i]);
 
   covered_interior_grobs_.clear ();
 
+  /*
+     If a signaled beam is already in active_beams_, we erase it so as
+     not to have a beam represented in active_beams_ more than once.
+   */
+  
   for (vsize i = 0; i < active_beams_.size (); i++)
     for (vsize j = 0; j < signaled_beams_.size (); j++)
       if (active_beams_[i] == signaled_beams_[j])
@@ -62,9 +72,11 @@ Beam_collision_engraver::stop_translation_timestep ()
         }
 
   /*
-    hack.
-    in auto beaming, end beams are signaled with their beams at a later timestep.
-    we need to scrub these.
+     In auto beaming, beams both begin and end during the same timestep.
+     This means that if there is a beam that is both in signaled_beams_ and
+     end_beams_, it must either be an auto beam (likely) or a beam that
+     has no notes under it (highly unlikely).  In either case, we cannot account
+     for the grobs under this beam, and we erase it from signaled beams.
   */
   for (vsize i = 0; i < end_beams_.size (); i++)
     for (vsize j = 0; j < signaled_beams_.size (); j++)
@@ -74,9 +86,25 @@ Beam_collision_engraver::stop_translation_timestep ()
           break;
         }
 
+  /*
+     We want to know how big active beams was originally so that we do not
+     get any cyclical dependencies (see below).
+  */
+  vsize orig_size = active_beams_.size ();
+
+  /*
+     All signaled beams that are left now become active beams that are fair
+     game to collect covered grobs.
+  */
   for (vsize i=0; i < signaled_beams_.size (); i++)
     active_beams_.push_back (signaled_beams_[i]);
 
+  /*
+     Add all covered grobs that fall to the right of a beam (like noteheads)
+     as to covered-grobs of the beam.  Note that noteheads that part of a beam
+     are not added to that list, as note heads should not never collide with
+     their own beams due to minimum stem length penalties in beam-quanting.cc.
+  */
   for (vsize i = 0; i < covered_grobs_.size (); i++)
     for (vsize j = 0; j < active_beams_.size (); j++)
       {
@@ -91,18 +119,25 @@ Beam_collision_engraver::stop_translation_timestep ()
 
   covered_grobs_.clear ();
 
+  /*
+     This is where cyclical dependencies are avoided.  In beam collision avoidance,
+     beams often need to avoid other beams.  To do this, they need to know the beam's
+     position.  But, if that second beam needs to know the first beam's position, we
+     have a cyclical dependency.  So, we only ever add signaled beams to active_beams_
+     that existed BEFORE this time step.  This is controlled by the orig_size variable.
+     The for loop stops before it gets to the signaled beams added above so that beams
+     added during this timestep are never dependent on each other for positioning.
+  */
   for (vsize i = 0; i < signaled_beams_.size (); i++)
-    for (vsize j = 0; j < active_beams_.size (); j++)
-      {
-        Grob *g = signaled_beams_[i];
-        if (g == active_beams_[j])
-          continue;
-
-        Pointer_group_interface::add_grob (active_beams_[j], ly_symbol2scm ("covered-grobs"), g);
-      }
+    for (vsize j = 0; j < orig_size; j++)
+      Pointer_group_interface::add_grob (active_beams_[j], ly_symbol2scm ("covered-grobs"), signaled_beams_[i]);
 
   signaled_beams_.clear ();
 
+  /*
+     If the end of a beam has been announced, it is no longer active.  So, remove this beam
+     from active_beams_.
+  */
   for (vsize i = 0; i < end_beams_.size (); i++)
     for (vsize j = 0; j < active_beams_.size (); j++)
       if (end_beams_[i] == active_beams_[j])