+ Grob* stem = unsmob_grob (grobs[i]->get_object ("stem"));
+ if (stem && Stem::has_interface (stem) && Stem::is_normal_stem (stem))
+ {
+ stems.insert (stem);
+ }
+ }
+
+ for (set<Grob*>::const_iterator it(stems.begin ()); it != stems.end (); it++)
+ {
+ Grob *s = *it;
+ Real x = s->extent (common[X_AXIS], X_AXIS).center();
+
+ Direction stem_dir = get_grob_direction (*it);
+ Interval y;
+ y.set_full ();
+ y[-stem_dir] = Stem::chord_start_y (*it) + (*it)->relative_coordinate (common[Y_AXIS], Y_AXIS)
+ - beam->relative_coordinate (common[Y_AXIS], Y_AXIS);
+
+ Real factor = parameters.STEM_COLLISION_FACTOR;
+ if (!unsmob_grob (s->get_object ("beam"))
+ && !Stem::flag (s).is_empty ())
+ factor = 1.0;
+ add_collision (x, y, factor);
+ }
+}
+
+void Beam_scoring_problem::init_stems ()
+{
+ extract_grob_set (beam, "covered-grobs", collisions);
+ extract_grob_set (beam, "stems", stems);
+ for (int a = 2; a--;)
+ {
+ common[a] = common_refpoint_of_array (stems, beam, Axis (a));
+ common[a] = common_refpoint_of_array (collisions, common[a], Axis (a));
+ }
+
+ Drul_array<Grob *> edge_stems(Beam::first_normal_stem (beam),
+ Beam::last_normal_stem (beam));
+ Direction d = LEFT;
+ do
+ x_span[d] = edge_stems[d] ? edge_stems[d]->relative_coordinate (common[X_AXIS], X_AXIS) : 0.0;
+ while (flip (&d) != LEFT);
+
+ Drul_array<bool> dirs_found (0, 0);