lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Allows users to request that beam collision occur on the Voice level. (i


From: mtsolo
Subject: Allows users to request that beam collision occur on the Voice level. (issue4367042)
Date: Thu, 07 Apr 2011 01:32:25 +0000

Reviewers: ,

Message:
Before pushing the stem patch (thanks to Trevor and Han Wen for the
LGTMs), I'd like to push this one.  It allows for beam collision to
happen momentarily on the Voice level via an override.  I will
subsequently integrate this into the quote.ly and quote-during.ly
regtests.

Please reply with any and all comments!

Cheers,
Mike

Description:
Allows users to request that beam collision occur on the Voice level.

Normally, automatic collision resolution applies at the Staff level.
This allows for users to override this behavoir to only apply to Voice
contexts.

Please review this at http://codereview.appspot.com/4367042/

Affected files:
  A input/regression/beam-collision-voice-only.ly
  M lily/beam-collision-engraver.cc
  M lily/beam.cc
  M scm/define-grob-properties.scm
  M scm/define-grobs.scm


Index: input/regression/beam-collision-voice-only.ly
diff --git a/input/regression/beam-collision-voice-only.ly b/input/regression/beam-collision-voice-only.ly
new file mode 100644
index 0000000000000000000000000000000000000000..8a7fbbd6f5906dd424b7167c29b238049562f33d
--- /dev/null
+++ b/input/regression/beam-collision-voice-only.ly
@@ -0,0 +1,14 @@
+\version "2.13.58"
+\header {
+  texidoc = "Beam collision can be tweaked to only apply to the grobs
+within the beam's original voice."
+}
+
+\relative c' {
+  \time 5/4
+  << { c8 [s c ] } \\ { s8 c' s8 } >>
+  c, [des' ]
+  \override Staff . Beam #'collision-voice-only = ##t
+  << { c,8 [s c ] } \\ { s8 c' s8 } >>
+  c, [des'! ]
+}
Index: lily/beam-collision-engraver.cc
diff --git a/lily/beam-collision-engraver.cc b/lily/beam-collision-engraver.cc index 5e9006f9b6f62ee1a2420d0e950caaaf5682593b..55e9272b40bd9bc4f279e3f140c83dfd7965d9d0 100644
--- a/lily/beam-collision-engraver.cc
+++ b/lily/beam-collision-engraver.cc
@@ -26,8 +26,8 @@
 class Beam_collision_engraver : public Engraver
 {
 protected:
-  vector<Grob *> beams_;
-  vector<Grob *> covered_grobs_;
+  vector<Grob_info> beams_;
+  vector<Grob_info> covered_grobs_;

   DECLARE_ACKNOWLEDGER (note_head);
   DECLARE_ACKNOWLEDGER (accidental);
@@ -40,6 +40,7 @@ protected:

 private:
   bool covered_grob_has_interface (Grob *covered_grob, Grob *beam);
+  static bool less (Grob_info i, Grob_info j);

 public:
   TRANSLATOR_DECLARATIONS (Beam_collision_engraver);
@@ -48,13 +49,19 @@ public:
 Beam_collision_engraver::Beam_collision_engraver () {}

 bool
+Beam_collision_engraver::less (Grob_info i, Grob_info j)
+{
+  return Grob::less (i.grob (), j.grob ());
+}
+
+bool
Beam_collision_engraver::covered_grob_has_interface (Grob *covered_grob, Grob *beam)
 {
   SCM interfaces = beam->get_property ("collision-interfaces");

   for (SCM l = interfaces; scm_is_pair (l); l = scm_cdr (l))
     {
-      if (covered_grob->internal_has_interface (scm_car (l)));
+      if (covered_grob->internal_has_interface (scm_car (l)))
         return true;
     }

@@ -67,41 +74,51 @@ Beam_collision_engraver::finalize ()
   if (!covered_grobs_.size ())
     return;

-  vector_sort (covered_grobs_, Grob::less);
-  vector_sort (beams_, Grob::less);
+  vector_sort (covered_grobs_, less);
+  vector_sort (beams_, less);
   vsize start = 0;

   for (vsize i = 0; i < beams_.size (); i++)
     {
- Interval_t<int> beam_spanned_rank_ = beams_[i]->spanned_rank_interval ();
+      Grob *beam_grob = beams_[i].grob ();
+      Context *beam_context = beams_[i].context ();
+
+ Interval_t<int> beam_spanned_rank_ = beam_grob->spanned_rank_interval (); // Start considering grobs at the first grob whose end falls at or after the beam's beginning. - while (covered_grobs_[start]->spanned_rank_interval ()[RIGHT] < beam_spanned_rank_[LEFT]) + while (covered_grobs_[start].grob ()->spanned_rank_interval ()[RIGHT] < beam_spanned_rank_[LEFT])
         start++;

       // Stop when the grob's beginning comes after the beam's end.
       for (vsize j = start; j < covered_grobs_.size (); j++)
         {
- Interval_t<int> covered_grob_spanned_rank = covered_grobs_[j]->spanned_rank_interval ();
+          Grob *covered_grob = covered_grobs_[j].grob ();
+          Context *covered_grob_context = covered_grobs_[j].context ();
+
+ Interval_t<int> covered_grob_spanned_rank = covered_grob->spanned_rank_interval ();
           if ((covered_grob_spanned_rank[LEFT] > beam_spanned_rank_[RIGHT]
- || !covered_grob_has_interface (covered_grobs_[j], beams_[i])))
+              || !covered_grob_has_interface (covered_grob, beam_grob)))
             break;
           /*
Only consider grobs whose end falls at or after the beam's beginning.
-             If the grob is a beam, it cannot start before beams_[i]
+             If the grob is a beam, it cannot start before beams_[i].
+ Also, if the user wants to check for collisions only in the beam's voice, + then make sure the beam and the covered_grob are in the same voice.
           */
if ((covered_grob_spanned_rank[RIGHT] >= beam_spanned_rank_[LEFT])
-              && !(Beam::has_interface (covered_grobs_[j])
+ && !(to_boolean (beam_grob->get_property ("collision-voice-only"))
+                   && (covered_grob_context != beam_context))
+              && !(Beam::has_interface (covered_grob)
&& (covered_grob_spanned_rank[LEFT] <= beam_spanned_rank_[LEFT])))
             {
               // Do not consider note heads attached to the beam.
               bool my_beam = false;
- if (Grob *stem = unsmob_grob (covered_grobs_[j]->get_object ("stem"))) + if (Grob *stem = unsmob_grob (covered_grob->get_object ("stem")))
                 if (Grob *beam = unsmob_grob (stem->get_object ("beam")))
-                  if (beam == beams_[i])
+                  if (beam == beam_grob)
                     my_beam = true;

               if (!my_beam)
- Pointer_group_interface::add_grob (beams_[i], ly_symbol2scm ("covered-grobs"), covered_grobs_[j]); + Pointer_group_interface::add_grob (beam_grob, ly_symbol2scm ("covered-grobs"), covered_grob);
             }
         }
     }
@@ -110,39 +127,39 @@ Beam_collision_engraver::finalize ()
 void
 Beam_collision_engraver::acknowledge_note_head (Grob_info i)
 {
-  covered_grobs_.push_back (i.grob ());
+  covered_grobs_.push_back (i);
 }

 void
 Beam_collision_engraver::acknowledge_accidental (Grob_info i)
 {
if (i.grob ()->internal_has_interface (ly_symbol2scm ("inline-accidental-interface")))
-    covered_grobs_.push_back (i.grob ());
+    covered_grobs_.push_back (i);
 }

 void
 Beam_collision_engraver::acknowledge_clef (Grob_info i)
 {
-  covered_grobs_.push_back (i.grob ());
+  covered_grobs_.push_back (i);
 }

 void
 Beam_collision_engraver::acknowledge_key_signature (Grob_info i)
 {
-  covered_grobs_.push_back (i.grob ());
+  covered_grobs_.push_back (i);
 }

 void
 Beam_collision_engraver::acknowledge_time_signature (Grob_info i)
 {
-  covered_grobs_.push_back (i.grob ());
+  covered_grobs_.push_back (i);
 }

 void
 Beam_collision_engraver::acknowledge_beam (Grob_info i)
 {
-  beams_.push_back (i.grob ());
-  covered_grobs_.push_back (i.grob ());
+  beams_.push_back (i);
+  covered_grobs_.push_back (i);
 }

 #include "translator.icc"
Index: lily/beam.cc
diff --git a/lily/beam.cc b/lily/beam.cc
index 6ae2ed4819bd43d75c03869a5be7085abf56b9ee..f39bf9f62c06e55f0914bf5e83004ad775b96bde 100644
--- a/lily/beam.cc
+++ b/lily/beam.cc
@@ -1819,6 +1819,7 @@ ADD_INTERFACE (Beam,
               "clip-edges "
               "concaveness "
               "collision-interfaces "
+              "collision-voice-only "
               "covered-grobs "
               "damping "
               "details "
Index: scm/define-grob-properties.scm
diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm
index 62d7cf070c14fab3791b193a90c262c266a17c21..3381cb9e27ed2858ea1decc3e88b31e4c1d5b97f 100644
--- a/scm/define-grob-properties.scm
+++ b/scm/define-grob-properties.scm
@@ -172,6 +172,8 @@ edges of beams?")
 delimiter.  If equal or smaller, the bracket/brace/line is removed.")
      (collision-interfaces ,list? "A list of interfaces for which
 automatic beam-collision resolution is run.")
+     (collision-voice-only ,boolean? "Does automatic beam collsion apply
+only to the voice in which the beam was created?")
      (color ,color? "The color of this grob.")
      (common-shortest-duration ,ly:moment? "The most common shortest
 note length.  This is used in spacing.  Enlarging this sets the score
Index: scm/define-grobs.scm
diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm
index 83336748509f9849e574e2735a3a96b13023c86d..708bd46293fa74309783c8d186b162486c04c9b7 100644
--- a/scm/define-grobs.scm
+++ b/scm/define-grobs.scm
@@ -355,6 +355,7 @@
                                 key-signature-interface
                                 note-head-interface
                                 time-signature-interface))
+       (collision-voice-only . #f)
        (concaveness . ,ly:beam::calc-concaveness)
        (cross-staff . ,ly:beam::calc-cross-staff)
        (damping . 1)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]