+Molecule
+Beam::do_brew_molecule () const
+{
+ Molecule mol;
+ if (!stem_count ())
+ return mol;
+ Real x0,dx;
+ if (visible_stem_count ())
+ {
+ x0 = first_visible_stem ()->relative_coordinate (0, X_AXIS);
+ dx = last_visible_stem ()->relative_coordinate (0, X_AXIS) - x0;
+ }
+ else
+ {
+ x0 = stem (0)->relative_coordinate (0, X_AXIS);
+ dx = stem_top ()->relative_coordinate (0, X_AXIS) - x0;
+ }
+
+
+ Real dy = gh_scm2double (get_elt_property ("height"));
+ Real dydx = dy && dx ? dy/dx : 0;
+ Real y = gh_scm2double (get_elt_property ("y-position"));
+ for (int j=0; j <stem_count (); j++)
+ {
+ Stem *i = stem (j);
+ Stem * prev = (j > 0)? stem (j-1) : 0;
+ Stem * next = (j < stem_count ()-1) ? stem (j+1) :0;
+
+ Molecule sb = stem_beams (i, next, prev);
+ Real x = i->relative_coordinate (0, X_AXIS)-x0;
+ sb.translate (Offset (x, x * dydx + y));
+ mol.add_molecule (sb);
+ }
+ mol.translate_axis (x0
+ - get_bound (LEFT)->relative_coordinate (0, X_AXIS), X_AXIS);
+
+ return mol;
+}
+
+int
+Beam::forced_stem_count () const
+{
+ int f = 0;
+ for (int i=0; i < stem_count (); i++)
+ {
+ Stem *s = stem (i);
+
+ if (s->invisible_b ())
+ continue;
+
+ if (((int)s->chord_start_f ())
+ && (s->get_direction () != s->get_default_dir ()))
+ f++;
+ }
+ return f;
+}
+
+/*
+ TODO: Fix this class. This is wildly inefficient.
+ And it sux. Yet another array/list 'interface'.
+ */
+Stem *
+Beam::stem (int i) const
+{
+ return Group_interface__extract_elements ((Beam*) this, (Stem*) 0, "stems")[i];
+}
+
+int
+Beam::stem_count () const
+{
+ Group_interface gi (this, "stems");
+ return gi.count ();
+}
+
+Stem*
+Beam::stem_top () const
+{
+ SCM s = get_elt_property ("stems");
+
+ return gh_pair_p (s) ? dynamic_cast<Stem*> (unsmob_element (gh_car (s))) : 0;
+}
+
+/* burp */
+int
+Beam::visible_stem_count () const
+{
+ int c = 0;
+ for (int i = 0; i < stem_count (); i++)
+ {
+ if (!stem (i)->invisible_b ())
+ c++;
+ }
+ return c;
+}
+
+Stem*
+Beam::first_visible_stem () const
+{
+ for (int i = 0; i < stem_count (); i++)
+ {
+ Stem* s = stem (i);
+ if (!s->invisible_b ())
+ return s;
+ }
+ return 0;
+}
+
+Stem*
+Beam::last_visible_stem () const
+{
+ for (int i = stem_count (); i > 0; i--)
+ {
+ Stem* s = stem (i - 1);
+ if (!s->invisible_b ())
+ return s;
+ }
+ return 0;
+}