+bool
+restrict_blinevertex_duck(etl::handle<Duck> duck, WorkArea& w_area, synfig::Point *point)
+{
+ synfig::Point sub_trans_origin(duck->get_sub_trans_origin());
+ etl::handle<Duck> origin_duck = duck->get_origin_duck();
+ bool origin_changed = false;
+ if(origin_duck)
+ origin_changed = restrict_blinevertex_duck(origin_duck, w_area, &sub_trans_origin);
+
+ if( ValueNode_BLineCalcVertex::Handle bline_vertex =
+ ValueNode_BLineCalcVertex::Handle::cast_dynamic(duck->get_value_desc().get_value_node())
+ )
+ {
+ synfig::Point closest_point = duck->get_point();
+ synfig::Real radius = 0.0;
+ ValueNode_BLine::Handle bline = ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link(bline_vertex->get_link_index_from_name("bline")));
+ synfig::find_closest_point(
+ (*bline)(w_area.get_time()),
+ duck->get_point(),
+ radius,
+ bline->get_loop(),
+ &closest_point
+ );
+
+ if(closest_point != duck->get_point())
+ {
+ *point = closest_point * duck->get_scalar() + sub_trans_origin;
+ return true;
+ }
+ }
+
+ if(origin_changed)
+ {
+ *point = duck->get_point() * duck->get_scalar() + sub_trans_origin;
+ return true;
+ }
+
+ return false;
+}
+