Example #1
0
void
Duck::set_sub_trans_point(const synfig::Point &x, const synfig::Time &time)
{
	set_sub_trans_point(x);

	if(get_type() == Duck::TYPE_VERTEX
	|| get_type() == Duck::TYPE_POSITION
	|| get_type() == Duck::TYPE_WIDTHPOINT_POSITION)
	{
		ValueNode_BLineCalcVertex::Handle bline_vertex;
		ValueNode_Composite::Handle composite;

		if ((bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(get_value_desc().get_value_node())) ||
			((composite = ValueNode_Composite::Handle::cast_dynamic(get_value_desc().get_value_node())) &&
			 composite->get_type() == ValueBase::TYPE_BLINEPOINT &&
			 (bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(composite->get_link("point")))))
		{
			synfig::Point closest_point = get_point();
			synfig::Real radius = 0.0;
			ValueNode_BLine::Handle bline = ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link("bline"));
			synfig::find_closest_point(
				(*bline)(time),
				get_point(),
				radius,
				bline->get_loop(),
				&closest_point);
			set_point(closest_point);
		}
		ValueNode_Composite::Handle wpoint_composite;
		ValueNode_WPList::Handle wplist;
		wpoint_composite=ValueNode_Composite::Handle::cast_dynamic(get_value_desc().get_value_node());
		if(wpoint_composite && wpoint_composite->get_type() == ValueBase::TYPE_WIDTHPOINT)
			if(get_value_desc().parent_is_value_node())
			{
				wplist=ValueNode_WPList::Handle::cast_dynamic(get_value_desc().get_parent_value_node());
				if(wplist)
				{
					ValueNode_BLine::Handle bline(ValueNode_BLine::Handle::cast_dynamic(wplist->get_bline()));
					synfig::Point closest_point = get_point();
					synfig::Real radius = 0.0;
					synfig::find_closest_point(
						(*bline)(time),
						get_point(),
						radius,
						bline->get_loop(),
						&closest_point);
					set_point(closest_point);
				}
			}
	}
}
bool
Action::BLinePointTangentSplitAngle::set_param(const synfig::String& name, const Action::Param &param)
{
    if(name=="value_node" && param.get_type()==Param::TYPE_VALUENODE)
    {
        value_node=value_node.cast_dynamic(param.get_value_node());
        if(value_node && value_node->get_type()==ValueBase::TYPE_BLINEPOINT)
            return true;
        ValueNode_RadialComposite::Handle radial_value_node;
        radial_value_node=ValueNode_RadialComposite::Handle::cast_dynamic(param.get_value_node());
        if(radial_value_node && radial_value_node->get_type()==ValueBase::TYPE_VECTOR)
            // value_node is radial composite and vector (user rigth click on a tangent)
        {
            ValueNode_Composite::Handle blinepoint;
            std::set<Node*>::iterator iter;
            // now check if the parent of value_node is a blinepoint type
            for(iter=radial_value_node->parent_set.begin(); iter!=radial_value_node->parent_set.end(); ++iter)
            {
                blinepoint=ValueNode_Composite::Handle::cast_dynamic(*iter);
                if(blinepoint && blinepoint->get_type()==ValueBase::TYPE_BLINEPOINT)
                {
                    value_node=blinepoint;
                    return true;
                }
            }
            return false;
        }
        return false;
    }
    if(name=="time" && param.get_type()==Param::TYPE_TIME)
    {
        time=param.get_time();
        return true;
    }
    return Action::CanvasSpecific::set_param(name,param);
}
void
Action::ValueDescBLineLink::prepare()
{
	if (value_desc_list.empty())
		throw Error(Error::TYPE_NOTREADY);

	clear();

	ValueNode_DynamicList::Handle bline_value_node(ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_parent_value_node()));
	bool loop(bline_value_node->get_loop());
	int loop_adjust(loop ? 0 : -1);
	const std::vector<ValueBase> bline((*bline_value_node)(time).get_list());
	int size = bline.size();
	Real amount = (index + origin + loop_adjust) / (size + loop_adjust);
	// This is the standard amount, let's calculate the homogeneous amount
	// since by default, homogeneous is 'on' for new BLineLink
	// Note: if bline is looped, then consider the loop option of
	// BLineLink looped too.
	amount=std_to_hom(ValueBase(bline), amount, loop, loop);
	LinkableValueNode::Handle calculated_value_node;
	Action::Handle action;

	ValueNode::Handle loop_value_node(ValueNode_Const::create(loop));
	ValueNode::Handle amount_value_node(ValueNode_Const::create(amount));
	ValueNode::Handle homogeneous_value_node(ValueNode_Const::create(true));

	for (std::list<ValueDesc>::iterator iter = value_desc_list.begin(); iter != value_desc_list.end(); ++iter)
	{
		ValueDesc& value_desc(*iter);

		// parent is BLINEPOINT ValueNode
		if (value_desc.parent_is_linkable_value_node() &&
			value_desc.get_parent_value_node()->get_type() == type_bline_point &&
			ValueNode_Composite::Handle::cast_dynamic(value_desc.get_parent_value_node()))
		{
			ValueNode_Composite::Handle composite = ValueNode_Composite::Handle::cast_dynamic(value_desc.get_parent_value_node());
			String link_name(composite->link_name(value_desc.get_index()));

			if (link_name == "t1" || link_name == "t2")
			{
				action = ValueDescSet::create();
				action->set_param("canvas",get_canvas());
				action->set_param("canvas_interface",get_canvas_interface());
				action->set_param("value_desc",ValueDesc(composite,composite->get_link_index_from_name("split_radius")));
				action->set_param("time",time);
				action->set_param("new_value",synfig::ValueBase(true));
				assert(action->is_ready());
				if(!action->is_ready()) throw Error(Error::TYPE_NOTREADY);
				add_action(action);

				action = ValueDescSet::create();
				action->set_param("canvas",get_canvas());
				action->set_param("canvas_interface",get_canvas_interface());
				action->set_param("value_desc",ValueDesc(composite,composite->get_link_index_from_name("split_angle")));
				action->set_param("time",time);
				action->set_param("new_value",synfig::ValueBase(true));
				assert(action->is_ready());
				if(!action->is_ready()) throw Error(Error::TYPE_NOTREADY);
				add_action(action);

				calculated_value_node = ValueNode_BLineCalcTangent::create(type_vector);
			}
			else
			if (link_name == "width")
				calculated_value_node = ValueNode_BLineCalcWidth::create(type_real);
			else
			if (link_name == "point")
				calculated_value_node = ValueNode_BLineCalcVertex::create(type_vector);
			else
			{
				synfig::warning("can't link '%s'", link_name.c_str());
				continue;
			}

			action = ValueNodeLinkConnect::create();
			action->set_param("parent_value_node", value_desc.get_parent_value_node());
			action->set_param("index", value_desc.get_index());
		}
		// BLINEPOINT ValueNode - link its vertex
		else if (value_desc.is_value_node() &&
				 value_desc.get_value_type() == type_bline_point &&
				 ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node()))
		{
			ValueNode_Composite::Handle composite = ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node());
			String link_name(value_desc.get_sub_name());
			int index = composite->get_link_index_from_name(link_name);
			calculated_value_node.reset();

			if (link_name == "t1" || link_name == "t2")
			{
				action = ValueDescSet::create();
				action->set_param("canvas",get_canvas());
				action->set_param("canvas_interface",get_canvas_interface());
				action->set_param("value_desc",ValueDesc(composite,composite->get_link_index_from_name("split_radius")));
				action->set_param("time",time);
				action->set_param("new_value",synfig::ValueBase(true));
				assert(action->is_ready());
				if(!action->is_ready()) throw Error(Error::TYPE_NOTREADY);
				add_action(action);

				action = ValueDescSet::create();
				action->set_param("canvas",get_canvas());
				action->set_param("canvas_interface",get_canvas_interface());
				action->set_param("value_desc",ValueDesc(composite,composite->get_link_index_from_name("split_angle")));
				action->set_param("time",time);
				action->set_param("new_value",synfig::ValueBase(true));
				assert(action->is_ready());
				if(!action->is_ready()) throw Error(Error::TYPE_NOTREADY);
				add_action(action);

				calculated_value_node = ValueNode_BLineCalcTangent::create(type_vector);
			}
			else
			if (link_name == "width")
				calculated_value_node = ValueNode_BLineCalcWidth::create(type_real);
			else
			if (link_name == "point")
				calculated_value_node = ValueNode_BLineCalcVertex::create(type_vector);

			if (index < 0 || !calculated_value_node)
			{
				synfig::warning("can't link '%s'", link_name.c_str());
				continue;
			}

			action = ValueNodeLinkConnect::create();
			action->set_param("parent_value_node", value_desc.get_value_node());
			action->set_param("index", index);
		}
		// exported ValueNode
		else if (value_desc.parent_is_canvas())
		{
			if (value_desc.get_value_type() == type_vector)
				calculated_value_node = ValueNode_BLineCalcVertex::create(type_vector);
			else if (value_desc.get_value_type() == type_real)
				calculated_value_node = ValueNode_BLineCalcWidth::create(type_real);
			else
				continue;

			calculated_value_node->set_link("bline",  bline_value_node);
			calculated_value_node->set_link("loop",   ValueNode_Const::create(loop));
			calculated_value_node->set_link("amount", ValueNode_Const::create(amount));
			calculated_value_node->set_link("homogeneous", ValueNode_Const::create(true));

			action = ValueNodeReplace::create();
			action->set_param("canvas", get_canvas());
			action->set_param("canvas_interface", get_canvas_interface());
			action->set_param("src", ValueNode::Handle(calculated_value_node));
			action->set_param("dest", value_desc.get_value_node());

			assert(action->is_ready());
			if (!action->is_ready()) throw Error(Error::TYPE_NOTREADY);
			add_action_front(action);

			continue;
		}
		else if (value_desc.parent_is_layer())
		{
			// VECTOR layer parameter
			if (value_desc.get_value_type() == type_vector)
				calculated_value_node = ValueNode_BLineCalcVertex::create(type_vector);
			// REAL layer parameter
			else if (value_desc.get_value_type() == type_real)
				calculated_value_node = ValueNode_BLineCalcWidth::create(type_real);
			// ANGLE layer parameter
			else if (value_desc.get_value_type() == type_angle)
				calculated_value_node = ValueNode_BLineCalcTangent::create(type_angle);
			// TRANSFORMATION layer parameter
			else if (value_desc.get_value_type() == type_transformation)
			{
				LinkableValueNode::Handle composite_node = ValueNode_Composite::create(value_desc.get_value(time), get_canvas());
				LinkableValueNode::Handle offset_node = ValueNode_BLineCalcVertex::create(type_vector);
				LinkableValueNode::Handle angle_node = ValueNode_BLineCalcTangent::create(type_angle);
				composite_node->set_link("offset", offset_node);
				composite_node->set_link("angle", angle_node);

				offset_node->set_link("bline",  bline_value_node );
				offset_node->set_link("loop",   loop_value_node  );
				offset_node->set_link("amount", amount_value_node);
				offset_node->set_link("homogeneous", homogeneous_value_node);

				angle_node->set_link("bline",  bline_value_node );
				angle_node->set_link("loop",   loop_value_node  );
				angle_node->set_link("amount", amount_value_node);
				angle_node->set_link("homogeneous", homogeneous_value_node);

				action = LayerParamConnect::create();
				action->set_param("layer", value_desc.get_layer());
				action->set_param("param", value_desc.get_param_name());
				action->set_param("canvas", get_canvas());
				action->set_param("canvas_interface", get_canvas_interface());
				action->set_param("value_node", ValueNode::Handle(composite_node));

				assert(action->is_ready());
				if (!action->is_ready()) throw Error(Error::TYPE_NOTREADY);
				add_action_front(action);

				continue;
			}
			else
				continue;

			action = LayerParamConnect::create();
			action->set_param("layer", value_desc.get_layer());
			action->set_param("param", value_desc.get_param_name());
		}
		else
			continue;

		calculated_value_node->set_link("bline",  bline_value_node );
		calculated_value_node->set_link("loop",   loop_value_node  );
		calculated_value_node->set_link("amount", amount_value_node);
		calculated_value_node->set_link("homogeneous", homogeneous_value_node);

		action->set_param("canvas", get_canvas());
		action->set_param("canvas_interface", get_canvas_interface());
		action->set_param("value_node", ValueNode::Handle(calculated_value_node));

		assert(action->is_ready());
		if (!action->is_ready()) throw Error(Error::TYPE_NOTREADY);
		add_action(action);
	}
}
Example #4
0
void
Duck::set_sub_trans_point(const synfig::Point &x, const synfig::Time &time)
{
	if (get_type() == Duck::TYPE_TANGENT ||
		get_type() == Duck::TYPE_ANGLE)
	{
		Angle old_angle = get_point().angle();
		set_point((x-get_sub_trans_origin())/get_scalar());
		Angle change = get_point().angle() - old_angle;
		while (change < Angle::deg(-180)) change += Angle::deg(360);
		while (change > Angle::deg(180)) change -= Angle::deg(360);
		//int old_halves = round_to_int(Angle::deg(rotations).get()/180);
		rotations += change;
		//int new_halves = round_to_int(Angle::deg(rotations).get()/180);
		/*if (old_halves != new_halves &&
			(new_halves > 1 || new_halves < -1 ||
			 old_halves > 1 || old_halves < -1))
			synfig::info("rotation: %.2f turns", new_halves/2.0)*/;
	} else if(get_type() == Duck::TYPE_VERTEX || get_type() == Duck::TYPE_POSITION || get_type() == Duck::TYPE_WIDTHPOINT_POSITION)
	{
		set_point((x-get_sub_trans_origin())/get_scalar());

		ValueNode_BLineCalcVertex::Handle bline_vertex;
		ValueNode_Composite::Handle composite;

		if ((bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(get_value_desc().get_value_node())) ||
			((composite = ValueNode_Composite::Handle::cast_dynamic(get_value_desc().get_value_node())) &&
			 composite->get_type() == ValueBase::TYPE_BLINEPOINT &&
			 (bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(composite->get_link("point")))))
		{
			synfig::Point closest_point = get_point();
			synfig::Real radius = 0.0;
			ValueNode_BLine::Handle bline = ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link("bline"));
			synfig::find_closest_point(
				(*bline)(time),
				get_point(),
				radius,
				bline->get_loop(),
				&closest_point);
			set_point(closest_point);
		}
		ValueNode_Composite::Handle wpoint_composite;
		ValueNode_WPList::Handle wplist;
		wpoint_composite=ValueNode_Composite::Handle::cast_dynamic(get_value_desc().get_value_node());
		if(wpoint_composite && wpoint_composite->get_type() == ValueBase::TYPE_WIDTHPOINT)
			if(get_value_desc().parent_is_value_node())
			{
				wplist=ValueNode_WPList::Handle::cast_dynamic(get_value_desc().get_parent_value_node());
				if(wplist)
				{
					ValueNode_BLine::Handle bline(ValueNode_BLine::Handle::cast_dynamic(wplist->get_bline()));
					synfig::Point closest_point = get_point();
					synfig::Real radius = 0.0;
					synfig::find_closest_point(
						(*bline)(time),
						get_point(),
						radius,
						bline->get_loop(),
						&closest_point);
					set_point(closest_point);
				}
			}
	}
	else set_point((x-get_sub_trans_origin())/get_scalar());
}