From: Joe Neeman Date: Sun, 7 Jan 2007 17:45:05 +0000 (+0200) Subject: optimise skylines. X-Git-Tag: release/2.11.11-1~45^2~6 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=a69eb3b3dfed77344ffd4d54580fa8985c27568e;p=lilypond.git optimise skylines. cleaner solution for accidental::pure-height --- diff --git a/buildscripts/build-profile.sh b/buildscripts/build-profile.sh index ee85ec7773..4c53c644e4 100755 --- a/buildscripts/build-profile.sh +++ b/buildscripts/build-profile.sh @@ -29,12 +29,15 @@ mkdir $resultdir cd $resultdir -echo 'foo = \new Staff \new Voice \repeat unfold 50 \relative { c4 d8[ d16( e]~ e16[ e e) f] g8 } +cat > long-score.ly << EOF +\version "2.10.0" +foo = \new Staff \new Voice \repeat unfold 50 \relative { c4 d8[ d16( e]~ e16[ e e) f] g8 } \new ChoirStaff << \foo \foo \foo \foo \foo \foo \foo \foo ->>' > long-score.ly +>> +EOF rm gmon.sum diff --git a/lily/accidental.cc b/lily/accidental.cc index ba352e5b84..1486c3f2cc 100644 --- a/lily/accidental.cc +++ b/lily/accidental.cc @@ -50,6 +50,15 @@ Accidental_interface::after_line_breaking (SCM smob) return SCM_UNSPECIFIED; } +/* This callback exists for the sole purpose of allowing us to override + its pure equivalent to accidental-interface::pure-height */ +MAKE_SCHEME_CALLBACK (Accidental_interface, height, 1); +SCM +Accidental_interface::height (SCM smob) +{ + return Grob::stencil_height (smob); +} + MAKE_SCHEME_CALLBACK (Accidental_interface, pure_height, 3); SCM Accidental_interface::pure_height (SCM smob, SCM start_scm, SCM) diff --git a/lily/grob.cc b/lily/grob.cc index 0738e80869..0d6898a121 100644 --- a/lily/grob.cc +++ b/lily/grob.cc @@ -430,19 +430,9 @@ Interval Grob::pure_height (Grob *refp, int start, int end) { SCM proc = get_property_data (ly_symbol2scm ("Y-extent")); - SCM pure_proc = get_property_data (ly_symbol2scm ("pure-Y-extent")); - SCM iv_scm; - - if (ly_is_procedure (pure_proc)) - iv_scm = scm_apply_3 (pure_proc, - self_scm (), - scm_from_int (start), - scm_from_int (end), SCM_EOL); - else - iv_scm = call_pure_function (proc, - scm_list_1 (self_scm ()), - start, end); - + SCM iv_scm = call_pure_function (proc, + scm_list_1 (self_scm ()), + start, end); Interval iv = robust_scm2interval (iv_scm, Interval (0, 0)); Real offset = pure_relative_y_coordinate (refp, start, end); @@ -645,7 +635,6 @@ ADD_INTERFACE (Grob, "outside-staff-horizontal-padding " "outside-staff-padding " "outside-staff-priority " - "pure-Y-extent " "rotation " "springs-and-rods " "staff-symbol " diff --git a/lily/include/accidental-interface.hh b/lily/include/accidental-interface.hh index 2a2888c20a..daa4483a20 100644 --- a/lily/include/accidental-interface.hh +++ b/lily/include/accidental-interface.hh @@ -21,6 +21,7 @@ public: DECLARE_SCHEME_CALLBACK (print, (SCM)); DECLARE_SCHEME_CALLBACK (calc_stencils, (SCM)); DECLARE_SCHEME_CALLBACK (after_line_breaking, (SCM)); + DECLARE_SCHEME_CALLBACK (height, (SCM)); DECLARE_SCHEME_CALLBACK (pure_height, (SCM, SCM, SCM)); DECLARE_GROB_INTERFACE(); diff --git a/lily/include/skyline.hh b/lily/include/skyline.hh index ab8fe30c65..c793927c82 100644 --- a/lily/include/skyline.hh +++ b/lily/include/skyline.hh @@ -38,6 +38,11 @@ struct Building bool conceals (Building const &other) const; bool sane () const; Building sloped_neighbour (Real horizon_padding, Direction d) const; + + bool operator< (Building const &other) + { + return iv_[LEFT] < other.iv_[LEFT]; + } }; class Skyline @@ -48,8 +53,7 @@ private: void internal_merge_skyline (list*, list*, list *const result); - void internal_build_skyline (list*, list *const result); - bool is_legal_skyline () const; + list internal_build_skyline (list*); DECLARE_SIMPLE_SMOBS(Skyline); public: diff --git a/lily/skyline.cc b/lily/skyline.cc index e61abbaea6..c009608fc9 100644 --- a/lily/skyline.cc +++ b/lily/skyline.cc @@ -6,6 +6,7 @@ */ #include "skyline.hh" +#include #include "ly-smobs.icc" @@ -108,12 +109,12 @@ Skyline::print () const } } -bool -Skyline::is_legal_skyline () const +static bool +is_legal_skyline (list const &buildings) { list::const_iterator i; Real last_x = -infinity_f; - for (i = buildings_.begin (); i != buildings_.end (); i++) + for (i = buildings.begin (); i != buildings.end (); i++) { if (i->iv_[LEFT] != last_x) return false; @@ -325,34 +326,78 @@ single_skyline (Building b, Real horizon_padding, list *const ret) -infinity_f, b.iv_[LEFT])); } -void -Skyline::internal_build_skyline (list *buildings, list *const result) +/* remove a non-overlapping set of buildings from BUILDINGS and build a skyline + out of them */ +static list +non_overlapping_skyline (list *const buildings) +{ + list result; + Real last_end = -infinity_f; + list::iterator i = buildings->begin (); + while (i != buildings->end ()) + { + if (approx_less_than (i->iv_[LEFT], last_end)) + { + i++; + continue; + } + + if (approx_greater_than (i->iv_[LEFT], last_end)) + result.push_back (Building (last_end, -infinity_f, -infinity_f, i->iv_[LEFT])); + else + i->iv_[LEFT] = last_end; + + last_end = i->iv_[RIGHT]; + list::iterator j = i; + i++; + result.splice (result.end (), *buildings, j); + } + if (last_end < infinity_f) + result.push_back (Building (last_end, -infinity_f, -infinity_f, infinity_f)); + assert (is_legal_skyline (result)); + return result; +} + +list +Skyline::internal_build_skyline (list *buildings) { vsize size = buildings->size (); if (size == 0) { - empty_skyline (result); - return; + list result; + empty_skyline (&result); + return result; } else if (size == 1) { - single_skyline (buildings->front (), 0, result); - return; + list result; + single_skyline (buildings->front (), 0, &result); + return result; } - list right_half; - list::iterator i = buildings->begin (); + deque > partials; + buildings->sort (); + while (!buildings->empty ()) + partials.push_back (non_overlapping_skyline (buildings)); - for (vsize s = 0; s < size/2; s++) - i++; - right_half.splice (right_half.end (), *buildings, i, buildings->end ()); - - list right; - list left; - internal_build_skyline (&right_half, &right); - internal_build_skyline (buildings, &left); - internal_merge_skyline (&right, &left, result); + /* we'd like to say while (partials->size () > 1) but that's O(n). + Instead, we exit in the middle of the loop */ + while (!partials.empty ()) + { + list merged; + list one = partials.front (); + partials.pop_front (); + if (partials.empty ()) + return one; + + list two = partials.front (); + partials.pop_front (); + internal_merge_skyline (&one, &two, &merged); + partials.push_back (merged); + } + assert (0); + return list (); } Skyline::Skyline () @@ -406,8 +451,8 @@ Skyline::Skyline (vector const &boxes, Real horizon_padding, Axis horizon_a } } - internal_build_skyline (&bldgs, &buildings_); - assert (is_legal_skyline ()); + buildings_ = internal_build_skyline (&bldgs); + assert (is_legal_skyline (buildings_)); } Skyline::Skyline (Box const &b, Real horizon_padding, Axis horizon_axis, Direction sky) @@ -426,7 +471,7 @@ Skyline::merge (Skyline const &other) list my_bld; my_bld.splice (my_bld.begin (), buildings_); internal_merge_skyline (&other_bld, &my_bld, &buildings_); - assert (is_legal_skyline ()); + assert (is_legal_skyline (buildings_)); } void @@ -438,7 +483,7 @@ Skyline::insert (Box const &b, Real horizon_padding, Axis a) my_bld.splice (my_bld.begin (), buildings_); single_skyline (Building (b, 0, a, sky_), horizon_padding, &other_bld); internal_merge_skyline (&other_bld, &my_bld, &buildings_); - assert (is_legal_skyline ()); + assert (is_legal_skyline (buildings_)); } void @@ -451,7 +496,7 @@ Skyline::raise (Real r) i->height_[RIGHT] += sky_ * r; i->y_intercept_ += sky_ * r; } - assert (is_legal_skyline ()); + assert (is_legal_skyline (buildings_)); } void diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index d3270748bb..64f32c6272 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -23,7 +23,7 @@ (glyph-name-alist . ,standard-alteration-glyph-name-alist) (alteration . ,accidental-interface::calc-alteration) (stencil . ,ly:accidental-interface::print) - (pure-Y-extent . ,ly:accidental-interface::pure-height) + (Y-extent . ,ly:accidental-interface::height) (after-line-breaking . ,ly:accidental-interface::after-line-breaking) (meta . ((class . Item) @@ -36,7 +36,7 @@ (glyph-name-alist . ,standard-alteration-glyph-name-alist) (alteration . ,accidental-interface::calc-alteration) (stencil . ,ly:accidental-interface::print) - (pure-Y-extent . ,ly:accidental-interface::pure-height) + (Y-extent . ,ly:accidental-interface::height) (after-line-breaking . ,ly:accidental-interface::after-line-breaking) (meta . ((class . Item) @@ -47,6 +47,7 @@ (AccidentalSuggestion . ( (stencil . ,ly:accidental-interface::print) + (Y-extent . ,ly:accidental-interface::height) (X-offset . ,(ly:make-simple-closure `(,+ ,(ly:make-simple-closure (list ly:self-alignment-interface::centered-on-x-parent)) @@ -122,7 +123,7 @@ (X-offset . ,ly:side-position-interface::x-aligned-side) (direction . ,LEFT) (stencil . ,ly:accidental-interface::print) - (pure-Y-extent . ,ly:accidental-interface::pure-height) + (Y-extent . ,ly:accidental-interface::height) (glyph-name-alist . ,standard-alteration-glyph-name-alist) (after-line-breaking . ,ly:accidental-interface::after-line-breaking) (side-axis . ,X) @@ -1891,6 +1892,7 @@ (font-size . -4) (side-axis . ,X) (stencil . ,ly:accidental-interface::print) + (Y-extent . ,ly:accidental-interface::height) (glyph-name-alist . ,standard-alteration-glyph-name-alist) (meta . ((class . Item) (interfaces . (trill-pitch-accidental-interface @@ -2116,7 +2118,6 @@ (list ly:bar-line::print ly:note-head::print - ly:accidental-interface::print ly:dots::print ly:clef::print ly:text-interface::print @@ -2132,16 +2133,17 @@ '(0 . 0)))) (define pure-conversions-alist - (list - `(,ly:slur::outside-slur-callback . ,ly:slur::pure-outside-slur-callback) - `(,ly:stem::height . ,ly:stem::pure-height) - `(,ly:rest::height . ,ly:rest::pure-height) - `(,ly:grob::stencil-height . ,pure-stencil-height) - `(,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side) - `(,ly:axis-group-interface::height . ,ly:axis-group-interface::pure-height) - `(,ly:hara-kiri-group-spanner::y-extent . ,ly:hara-kiri-group-spanner::pure-height) - `(,ly:slur::height . ,ly:slur::pure-height) - `(,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side))) + `( + (,ly:accidental-interface::height . ,ly:accidental-interface::pure-height) + (,ly:slur::outside-slur-callback . ,ly:slur::pure-outside-slur-callback) + (,ly:stem::height . ,ly:stem::pure-height) + (,ly:rest::height . ,ly:rest::pure-height) + (,ly:grob::stencil-height . ,pure-stencil-height) + (,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side) + (,ly:axis-group-interface::height . ,ly:axis-group-interface::pure-height) + (,ly:hara-kiri-group-spanner::y-extent . ,ly:hara-kiri-group-spanner::pure-height) + (,ly:slur::height . ,ly:slur::pure-height) + (,ly:side-position-interface::y-aligned-side . ,ly:side-position-interface::pure-y-aligned-side))) (define pure-functions (list