void ValueAverage::set_average_value_weighted(ValueBase &weighted_list, const ValueBase &value)
{
	if (weighted_list.get_type() != type_list) return;

	ValueBase::List list = weighted_list.get_list();
	if (list.empty()) return;
	types_namespace::TypeWeightedValueBase *t =
		dynamic_cast<types_namespace::TypeWeightedValueBase *>(&(list.front().get_type()));
	if (t == NULL) return;
	if (!check_weighted_type(*t)) return;

	ValueBase::List values_list;
	values_list.reserve(list.size());
	std::vector<Real> weights_list;
	weights_list.reserve(list.size());
	for(ValueBase::List::const_iterator i = list.begin(); i != list.end(); ++i) {
		if (i->get_type() != *t) return;
		weights_list.push_back( t->extract_weight(*i) );
		values_list.push_back( t->extract_value(*i) );
	}
	set_average_value_generic(
		values_list.begin(), values_list.end(),
		weights_list.begin(), weights_list.end(),
		value );

	std::vector<Real>::const_iterator j = weights_list.begin();
	for(ValueBase::List::const_iterator i = values_list.begin(); i != values_list.end(); ++i, ++j)
		list[i - values_list.begin()] = t->create_weighted_value(*j, *i);
	weighted_list = list;
}
ValueBase ValueAverage::average_weighted(const ValueBase &weighted_list, const ValueBase &default_value)
{
	if (weighted_list.get_type() != type_list) return default_value;

	const ValueBase::List &list = weighted_list.get_list();
	ValueBase::List values_list;
	values_list.reserve(list.size());
	std::vector<Real> weights_list;
	weights_list.reserve(list.size());
	for(ValueBase::List::const_iterator i = list.begin(); i != list.end(); ++i) {
		types_namespace::TypeWeightedValueBase *t =
			dynamic_cast<types_namespace::TypeWeightedValueBase *>(&(i->get_type()));
		if (t == NULL) continue;
		if (!check_weighted_type(*t)) continue;
		weights_list.push_back( t->extract_weight(*i) );
		values_list.push_back( t->extract_value(*i) );
	}
	return average_generic(
		values_list.begin(), values_list.end(),
		weights_list.begin(), weights_list.end(),
		default_value );
}
예제 #3
0
void
Region::sync_vfunc()
{
	clear();

	const Real k = 1.0/3.0;
	const BLinePoint blank_point;
	const Segment blank_segment;

	// build splines
	bool first = true;
	bool first_warning = true;
	Vector prev;
	Vector prev_tangent;
	const ValueBase::List &list = param_bline.get_list();
	for(ValueBase::List::const_iterator i = list.begin(); i != list.end(); ++i) {
		if (i->get_type() == type_bline_point) {
			// process BLinePoint
			const BLinePoint &point = i->get(blank_point);
			const Vector &p = point.get_vertex();

			if (first)
				{ first = false; move_to(p); }
			else
			if (prev_tangent.is_equal_to(Vector::zero()) && point.get_tangent1().is_equal_to(Vector::zero()))
				line_to(p);
			else
				cubic_to(p, prev + prev_tangent*k, p - point.get_tangent1()*k);

			prev = point.get_vertex();
			prev_tangent = point.get_tangent2();
		} else
		if (i->get_type() == type_segment) {
			// process Segment
			const Segment &segment = i->get(blank_segment);

			if (first)
				{ first = false; move_to(segment.p1); }
			else
			if (!segment.p1.is_equal_to(prev))
				line_to(segment.p1);

			if (segment.t1.is_equal_to(Vector::zero()) && segment.t2.is_equal_to(Vector::zero()))
				line_to(segment.p2);
			else
				cubic_to(segment.p2, segment.p1 + segment.t1*k, segment.p2 - segment.t2*k);

			prev = segment.p2;
			prev_tangent = Vector();
		} else
		if (first_warning) {
			// warning
			first_warning = false;
			synfig::warning("Region: incorrect type on bline");
		}
	}

	// close loop
	if ( !first
	  && param_bline.get_loop()
	  && list.front().get_type() == type_bline_point )
	{
		const BLinePoint &point = list.front().get(blank_point);
		const Vector &p = point.get_vertex();
		if ( !prev_tangent.is_equal_to(Vector::zero())
		  || !point.get_tangent1().is_equal_to(Vector::zero()) )
			cubic_to(p, prev + prev_tangent*k, p - point.get_tangent1()*k);
	}

	close();
}