예제 #1
0
void
Dialog_Waypoint::set_value_desc(synfigapp::ValueDesc value_desc)
{
	value_desc_=value_desc;
	if(value_desc.get_value_node() && value_desc.get_value_node()->get_parent_canvas())
		waypointwidget->set_canvas(value_desc.get_value_node()->get_parent_canvas());
}
예제 #2
0
	static bool is_not_supported(const synfigapp::ValueDesc& x)
	{
		return x.get_value_type() == type_string
			|| x.get_value_type() == type_canvas
			|| x.get_value_type() == type_gradient
			|| x.get_value_type() == type_list
			|| x.get_value_type() == type_segment;
	}
예제 #3
0
int
Action::KeyframeSet::scale_activepoints(const synfigapp::ValueDesc& value_desc,const synfig::Time& old_begin,const synfig::Time& old_end,const synfig::Time& new_begin,const synfig::Time& new_end)
{
	ValueNode_DynamicList::Handle value_node(ValueNode_DynamicList::Handle::cast_static(value_desc.get_parent_value_node()));
	ValueNode_DynamicList::ListEntry& list_entry(value_node->list[value_desc.get_index()]);

	std::vector<Activepoint*> selected;
	std::vector<Activepoint*>::iterator iter;

	if(list_entry.find(old_begin,old_end,selected))
	{
		// check to make sure this operation is OK
		for(iter=selected.begin();iter!=selected.end();++iter)
		{
			try
			{
				Time new_time(old_2_new((*iter)->get_time()));
				if(new_time>=old_begin && new_time<old_end)
					continue;
				list_entry.find(new_time);
				// If we found a activepoint already at that time, then
				// we need to abort
				//throw Exception::BadTime(_("Activepoint Conflict"));
			}
			catch(Exception::NotFound&) { }
		}

		int ret(0);
		while(!selected.empty())
		{
			if(selected.back()->get_time()!=old_2_new(selected.back()->get_time()))
			{
				Action::Handle action(Action::create("ActivepointSet"));

				action->set_param("canvas",get_canvas());
				action->set_param("canvas_interface",get_canvas_interface());
				action->set_param("value_desc",value_desc);

				Activepoint activepoint(*selected.back());
				activepoint.set_time(old_2_new(selected.back()->get_time()));

				action->set_param("activepoint",activepoint);

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

				add_action_front(action);

				ret++;
			}
			selected.pop_back();
		}
		return ret;
	}
	return 0;
}
예제 #4
0
void
Action::KeyframeDuplicate::process_value_desc(const synfigapp::ValueDesc& value_desc)
{
	const synfig::Time old_time=keyframe.get_time();
	const synfig::Time new_time=new_keyframe.get_time();

	if(value_desc.is_value_node())
	{
		ValueNode::Handle value_node(value_desc.get_value_node());

		// If we are a dynamic list, then we need to update the ActivePoints
		if(ValueNode_DynamicList::Handle::cast_dynamic(value_node))
		{
			ValueNode_DynamicList::Handle value_node_dynamic(ValueNode_DynamicList::Handle::cast_dynamic(value_node));
			int i;

			for(i=0;i<value_node_dynamic->link_count();i++)
			{
				synfigapp::ValueDesc value_desc(value_node_dynamic,i);
				Activepoint activepoint(value_node_dynamic->list[i].new_activepoint_at_time(old_time));
				activepoint.set_time(new_time);

				Action::Handle action(ActivepointSetSmart::create());

				action->set_param("canvas",get_canvas());
				action->set_param("canvas_interface",get_canvas_interface());
				action->set_param("value_desc",value_desc);
				action->set_param("activepoint",activepoint);

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

				add_action_front(action);
			}
		}
		else if(ValueNode_Animated::Handle::cast_dynamic(value_node))
		{
			ValueNode_Animated::Handle value_node_animated(ValueNode_Animated::Handle::cast_dynamic(value_node));
			Waypoint waypoint(value_node_animated->new_waypoint_at_time(old_time));
			waypoint.set_time(new_time);

			Action::Handle action(WaypointSetSmart::create());

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

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

			add_action_front(action);
		}
	}
}
예제 #5
0
//kind of a hack... pointer is ugly
void get_change_times_from_vdesc(const synfigapp::ValueDesc &v, std::set<synfig::Time> &times)
{
	if (v.is_value_node())
	{
		if ( v.get_value_type() == type_string
		  || v.get_value_type() == type_bool
		  || v.get_value_type() == type_canvas )
		{
			std::map<Time, ValueBase> x;
			v.get_value_node()->get_values(x);
			for(std::map<Time, ValueBase>::const_iterator i = x.begin(); i != x.end(); ++i)
				times.insert(i->first);
		}
	}
}
예제 #6
0
int
Action::KeyframeSet::scale_waypoints(const synfigapp::ValueDesc& value_desc,const synfig::Time& old_begin,const synfig::Time& old_end,const synfig::Time& new_begin,const synfig::Time& new_end)
{
	ValueNode_Animated::Handle value_node(ValueNode_Animated::Handle::cast_static(value_desc.get_value_node()));

	std::vector<Waypoint*> selected;
	std::vector<Waypoint*>::iterator iter;

	if(value_node->find(old_begin,old_end,selected))
	{
		// check to make sure this operation is OK
		for(iter=selected.begin();iter!=selected.end();++iter)
		{
			try
			{
				Time new_time(old_2_new((*iter)->get_time()));
				if(new_time>=old_begin && new_time<old_end)
					continue;
				value_node->find(new_time);
				// If we found a waypoint point already at that time, then
				// we need to abort
				//synfig::info(_("old_begin: %s, old_end: %s"),old_begin.get_string().c_str(),old_end.get_string().c_str());
				//synfig::info(_("new_begin: %s, new_end: %s"),new_begin.get_string().c_str(),new_end.get_string().c_str());
				//throw Exception::BadTime(strprintf(_("Waypoint Conflict, old: %s, new: %s"),(*iter)->get_time().get_string().c_str(),new_time.get_string().c_str()));
			}
			catch(Exception::NotFound&) { }
		}

		int ret(0);
		while(!selected.empty())
		{
			if(selected.back()->get_time()!=old_2_new(selected.back()->get_time()))
			{
				Action::Handle action(Action::create("WaypointSet"));

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

				Waypoint waypoint(*selected.back());
				waypoint.set_time(old_2_new(selected.back()->get_time()));

				action->set_param("waypoint",waypoint);

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

				add_action_front(action);

				ret++;
			}
			selected.pop_back();
		}
		return ret;
	}
	return 0;
}
예제 #7
0
void
Action::KeyframeWaypointSet::process_value_desc(const synfigapp::ValueDesc& value_desc)
{
	if(value_desc.is_value_node())
	{
		ValueNode_Animated::Handle value_node(ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node()));

		if(value_node)
		{
			Action::Handle action(WaypointSetSmart::create());

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

			Waypoint waypoint;
			try
			{
				waypoint=*value_node->find(keyframe.get_time());
			}
			catch(...)
			{
				waypoint.set_time(keyframe.get_time());
				waypoint.set_value((*value_node)(keyframe.get_time()));
			}

			keyframe.apply_model(waypoint_model);
			//*get_canvas()->keyframe_list().find(keyframe)=keyframe;
			KeyframeList::iterator iter;
			if (get_canvas()->keyframe_list().find(keyframe, iter)) *iter = keyframe;

			waypoint.apply_model(waypoint_model);

			action->set_param("waypoint",waypoint);

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

			add_action_front(action);
		}
	}
}
예제 #8
0
const synfig::Time get_time_offset_from_vdesc(const synfigapp::ValueDesc &v)
{
#ifdef ADJUST_WAYPOINTS_FOR_TIME_OFFSET
	if(getenv("SYNFIG_SHOW_CANVAS_PARAM_WAYPOINTS") ||
	   v.get_value_type() != synfig::type_canvas)
		return synfig::Time::zero();

	synfig::Canvas::Handle canvasparam = v.get_value().get(Canvas::Handle());
	if(!canvasparam)
		return synfig::Time::zero();

	if (!v.parent_is_layer())
		return synfig::Time::zero();

	synfig::Layer::Handle layer = v.get_layer();

	if (etl::handle<Layer_PasteCanvas>::cast_dynamic(layer))
		return synfig::Time::zero();

	return layer->get_param("time_offset").get(Time());
#else // ADJUST_WAYPOINTS_FOR_TIME_OFFSET
	return synfig::Time::zero();
#endif
}
예제 #9
0
	CurveStruct(const synfigapp::ValueDesc& x):
		value_desc(x)
	{
		Type &type(value_desc.get_value_type());
		if (type == type_real)
		{
			channels.push_back(Channel());
			channels.back().name="real";
			channels.back().color=Gdk::Color("#007f7f");
		}
		else
		if (type == type_time)
		{
			channels.push_back(Channel());
			channels.back().name="time";
			channels.back().color=Gdk::Color("#7f7f00");
		}
		else
		if (type == type_integer)
		{
			channels.push_back(Channel());
			channels.back().name="int";
			channels.back().color=Gdk::Color("#7f0000");
		}
		else
		if (type == type_bool)
		{
			channels.push_back(Channel());
			channels.back().name="bool";
			channels.back().color=Gdk::Color("#ff7f00");
		}
		else
		if (type == type_angle)
		{
			channels.push_back(Channel());
			channels.back().name="theta";
			channels.back().color=Gdk::Color("#004f4f");
		}
		else
		if (type == type_color)
		{
			channels.push_back(Channel());
			channels.back().name="red";
			channels.back().color=Gdk::Color("#7f0000");
			channels.push_back(Channel());
			channels.back().name="green";
			channels.back().color=Gdk::Color("#007f00");
			channels.push_back(Channel());
			channels.back().name="blue";
			channels.back().color=Gdk::Color("#00007f");
			channels.push_back(Channel());
			channels.back().name="alpha";
			channels.back().color=Gdk::Color("#000000");
		}
		else
		if (type == type_vector)
		{
			channels.push_back(Channel());
			channels.back().name="x";
			channels.back().color=Gdk::Color("#7f007f");
			channels.push_back(Channel());
			channels.back().name="y";
			channels.back().color=Gdk::Color("#007f7f");
		}
		else
		if (type == type_bline_point)
		{
			channels.push_back(Channel());
			channels.back().name="v.x";
			channels.back().color=Gdk::Color("#ff7f00");
			channels.push_back(Channel());
			channels.back().name="v.y";
			channels.back().color=Gdk::Color("#7f3f00");

			channels.push_back(Channel());
			channels.back().name="width";
			channels.back().color=Gdk::Color("#000000");

			channels.push_back(Channel());
			channels.back().name="origin";
			channels.back().color=Gdk::Color("#ffffff");

			channels.push_back(Channel());
			channels.back().name="tsplit";
			channels.back().color=Gdk::Color("#ff00ff");

			channels.push_back(Channel());
			channels.back().name="t1.x";
			channels.back().color=Gdk::Color("#ff0000");
			channels.push_back(Channel());
			channels.back().name="t1.y";
			channels.back().color=Gdk::Color("#7f0000");

			channels.push_back(Channel());
			channels.back().name="t2.x";
			channels.back().color=Gdk::Color("#ffff00");
			channels.push_back(Channel());
			channels.back().name="t2.y";
			channels.back().color=Gdk::Color("#7f7f00");

			channels.push_back(Channel());
			channels.back().name="rsplit";
			channels.back().color=Gdk::Color("#ff00ff");
			channels.push_back(Channel());
			channels.back().name="asplit";
			channels.back().color=Gdk::Color("#ff00ff");
		}
		else
		if (type == type_width_point)
		{
			channels.push_back(Channel());
			channels.back().name="position";
			channels.back().color=Gdk::Color("#ff0000");
			channels.push_back(Channel());
			channels.back().name="width";
			channels.back().color=Gdk::Color("#00ff00");
		}
		else
		if (type == type_dash_item)
		{
			channels.push_back(Channel());
			channels.back().name="offset";
			channels.back().color=Gdk::Color("#ff0000");
			channels.push_back(Channel());
			channels.back().name="length";
			channels.back().color=Gdk::Color("#00ff00");
		}
		else
		{
			throw synfig::Exception::BadType("Bad type for curves");
		}
	}
예제 #10
0
	synfig::Real get_value(int chan, synfig::Real time, synfig::Real tolerance)
	{
		std::map<synfig::Real,synfig::Real>::iterator iter;

		// First check to see if we have a value
		// that is "close enough" to the time
		// we are looking for
		iter=channels[chan].values.lower_bound(time);
		if(iter!=channels[chan].values.end() && iter->first-time<=tolerance)
			return -iter->second;

		// Since that didn't work, we now need
		// to go ahead and figure out what the
		// actual value is at that time.
		ValueBase value(value_desc.get_value(time));
		Type &type(value.get_type());
		if (type == type_real)
			channels[0].values[time]=value.get(Real());
		else
		if (type == type_time)
			channels[0].values[time]=value.get(Time());
		else
		if (type == type_integer)
			channels[0].values[time]=value.get(int());
		else
		if (type == type_bool)
			channels[0].values[time]=value.get(bool());
		else
		if (type == type_angle)
			channels[0].values[time]=Angle::rad(value.get(Angle())).get();
		else
		if (type == type_color)
		{
			channels[0].values[time]=value.get(Color()).get_r();
			channels[1].values[time]=value.get(Color()).get_g();
			channels[2].values[time]=value.get(Color()).get_b();
			channels[3].values[time]=value.get(Color()).get_a();
		}
		else
		if (type == type_vector)
		{
			channels[0].values[time]=value.get(Vector())[0];
			channels[1].values[time]=value.get(Vector())[1];
		}
		else
		if (type == type_bline_point)
		{
			channels[0].values[time]=value.get(BLinePoint()).get_vertex()[0];
			channels[1].values[time]=value.get(BLinePoint()).get_vertex()[1];
			channels[2].values[time]=value.get(BLinePoint()).get_width();
			channels[3].values[time]=value.get(BLinePoint()).get_origin();
			channels[4].values[time]=value.get(BLinePoint()).get_split_tangent_both();
			channels[5].values[time]=value.get(BLinePoint()).get_tangent1()[0];
			channels[6].values[time]=value.get(BLinePoint()).get_tangent1()[1];
			channels[7].values[time]=value.get(BLinePoint()).get_tangent2()[0];
			channels[8].values[time]=value.get(BLinePoint()).get_tangent2()[1];
			channels[9].values[time]=value.get(BLinePoint()).get_split_tangent_radius();
			channels[10].values[time]=value.get(BLinePoint()).get_split_tangent_angle();
		}
		else
		if (type == type_width_point)
		{
			channels[0].values[time]=value.get(WidthPoint()).get_position();
			channels[1].values[time]=value.get(WidthPoint()).get_width();
		}
		else
		{
			return 0;
		}

		return -channels[chan].values[time];
	}
예제 #11
0
void
Action::KeyframeRemove::process_value_desc(const synfigapp::ValueDesc& value_desc)
{
	const synfig::Time time(keyframe.get_time());

	if(value_desc.is_value_node())
	{
		ValueNode::Handle value_node(value_desc.get_value_node());

		// If we are a dynamic list, then we need to update the ActivePoints
		if(ValueNode_DynamicList::Handle::cast_dynamic(value_node))
		{
			ValueNode_DynamicList::Handle value_node_dynamic(ValueNode_DynamicList::Handle::cast_dynamic(value_node));
			int i;
			for(i=0;i<value_node_dynamic->link_count();i++)
			try
			{
				Activepoint activepoint;
				activepoint=*value_node_dynamic->list[i].find(time);

				synfigapp::ValueDesc value_desc(value_node_dynamic,i);

				Action::Handle action(ActivepointRemove::create());

				action->set_param("canvas",get_canvas());
				action->set_param("canvas_interface",get_canvas_interface());
				action->set_param("value_desc",value_desc);
				action->set_param("activepoint",activepoint);

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

				add_action_front(action);
			}
			catch(...)
			{
			}
		}
		else if(ValueNode_Animated::Handle::cast_dynamic(value_node))
		try
		{
			ValueNode_Animated::Handle value_node_animated(ValueNode_Animated::Handle::cast_dynamic(value_node));
			Waypoint waypoint;
			waypoint=*value_node_animated->find(time);
			assert(waypoint.get_time()==time);

			Action::Handle action(WaypointRemove::create());

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

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

			add_action_front(action);
		}
		catch(...)
		{
		}
	}
}
예제 #12
0
void
Action::KeyframeSet::process_value_desc(const synfigapp::ValueDesc& value_desc)
{
	if(value_desc.is_value_node())
	{
		ValueNode::Handle value_node(value_desc.get_value_node());

		//if(guid_set.count(value_node->get_guid()))
		//	return;
		//guid_set.insert(value_node->get_guid());

		// If we are a dynamic list, then we need to update the ActivePoints
		if(ValueNode_DynamicList::Handle::cast_dynamic(value_node))
		{
			ValueNode_DynamicList::Handle value_node_dynamic(ValueNode_DynamicList::Handle::cast_dynamic(value_node));
			int i;
			for(i=0;i<value_node_dynamic->link_count();i++)
			{
				synfigapp::ValueDesc value_desc(value_node_dynamic,i);
				if(new_time>keyframe_prev && new_time<keyframe_next)
				{
					// In this circumstance, we need to adjust any
					// activepoints between the previous and next
					// keyframes
					scale_activepoints(value_desc,keyframe_prev,old_time,keyframe_prev,new_time);
					scale_activepoints(value_desc,old_time,keyframe_next,new_time,keyframe_next);
				}
				//else
				{
					Action::Handle action(ActivepointSetSmart::create());

					action->set_param("canvas",get_canvas());
					action->set_param("canvas_interface",get_canvas_interface());
					action->set_param("value_desc",value_desc);

					Activepoint activepoint;
					try
					{
						activepoint=*value_node_dynamic->list[i].find(old_time);
						activepoint.set_time(new_time);
					}
					catch(...)
					{
						activepoint.set_time(new_time);
						activepoint.set_state(value_node_dynamic->list[i].status_at_time(old_time));
						activepoint.set_priority(0);
					}
					action->set_param("activepoint",activepoint);

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

					add_action_front(action);
				}
			}
		}
		else if(ValueNode_Animated::Handle::cast_dynamic(value_node))
		{
			if(new_time>keyframe_prev && new_time<keyframe_next)
			{
					// In this circumstance, we need to adjust any
					// waypoints between the previous and next
					// keyframes
					scale_waypoints(value_desc,keyframe_prev,old_time,keyframe_prev,new_time);
					scale_waypoints(value_desc,old_time,keyframe_next,new_time,keyframe_next);
			}
			//else
			{
				ValueNode_Animated::Handle value_node_animated(ValueNode_Animated::Handle::cast_dynamic(value_node));

				Action::Handle action(WaypointSetSmart::create());

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

				Waypoint waypoint;
				try
				{
					waypoint=*value_node_animated->find(old_time);
					waypoint.set_time(new_time);
				}
				catch(...)
				{
					waypoint.set_time(new_time);
					waypoint.set_value((*value_node_animated)(old_time));
					waypoint.set_before(synfigapp::Main::get_interpolation());
					waypoint.set_after(synfigapp::Main::get_interpolation());
				}
				action->set_param("waypoint",waypoint);

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

				add_action_front(action);
			}
		}
	}
}
예제 #13
0
void
CanvasTreeStore::set_row(Gtk::TreeRow row,synfigapp::ValueDesc value_desc, bool do_children)
{
	Gtk::TreeModel::Children children = row.children();
	while(!children.empty() && erase(children.begin()))
		;

	row[model.value_desc]=value_desc;
	try
	{
		//row[model.icon] = get_tree_pixbuf(value_desc.get_value_type());

		if(value_desc.is_value_node())
		{
			ValueNode::Handle value_node=value_desc.get_value_node();

			// todo: if the parent is animated and expanded, and we drag the time slider so that it changes,
			// it's not updated.  it still shows the previous bone valuenode.

			// maybe replace the ValueNode_Const or ValueNode_Animated with the contained ValueNode_Bone
			value_node = expandable_bone_parent(value_node);

			assert(value_node);

			row[model.value_node] = value_node;
			//row[model.is_canvas] = false;
			//row[model.is_value_node] = true;
			//row[model.is_editable] = synfigapp::is_editable(value_node);
			//row[model.id]=value_node->get_id();

			// Set the canvas
			if(value_desc.parent_is_canvas())
				row[model.canvas]=value_desc.get_canvas();
			else
				row[model.canvas]=canvas_interface()->get_canvas();

			LinkableValueNode::Handle linkable;
			// printf("%s:%d value_node = %s\n", __FILE__, __LINE__, value_node->get_description().c_str());
			linkable=LinkableValueNode::Handle::cast_dynamic(value_node);

			// printf("linkable: %d; do_children: %d\n", bool(linkable), bool(do_children));
			if(linkable && do_children)
			{
				row[model.link_count] = linkable->link_count();
				LinkableValueNode::Vocab vocab(linkable->get_children_vocab());
				LinkableValueNode::Vocab::iterator iter(vocab.begin());
				for(int i=0;i<linkable->link_count();i++, iter++)
				{
					if(iter->get_hidden())
						continue;
					Gtk::TreeRow child_row=*(append(row.children()));
					child_row[model.link_id] = i;
					child_row[model.canvas] = static_cast<Canvas::Handle>(row[model.canvas]);
					child_row[model.name] = linkable->link_local_name(i);
					child_row[model.tooltip] = iter->get_description();
					child_row[model.child_param_desc] = *iter;
					set_row(child_row,synfigapp::ValueDesc(linkable,i));
				}
			}
			return;
		}
		else
		{
			//row[model.is_value_node] = false;
			//row[model.is_editable] = true;
			//row[model.label] = Glib::ustring(row[model.name]);
			return;
		}
	}
	catch(synfig::Exception::IDNotFound x)
	{
		synfig::error(__FILE__":%d: IDNotFound thrown",__LINE__);
		erase(row);
		return;
	}

	// We should never get to this point
	assert(0);
}
예제 #14
0
void synfigapp::recurse_valuedesc(synfigapp::ValueDesc h, const std::set<Time> &tlist,
								timepoints_ref &vals, synfig::Time time_offset, synfig::Real time_dilation)
{
	//special cases for Animated, DynamicList, and Linkable

	//synfig::info("ValueBasenode... %p, %s", h.get_value_node().get(),typeid(*h.get_value_node()).name());


	//animated case
	{
		synfig::ValueNode_Animated::Handle p = synfig::ValueNode_Animated::Handle::cast_dynamic(h.get_value_node());

		if(p)
		{
			//loop through and determine which waypoint we will need to reference
			const synfig::WaypointList &w = p->waypoint_list();

			synfig::WaypointList::const_iterator i = w.begin(),
												end = w.end();

			std::set<Time>::const_iterator		j = tlist.begin(),
												jend = tlist.end();
			for(; i != end && j != jend;)
			{
				//synfig::info("tpair t(%.3f) = %.3f", (float)*j, (float)(i->get_time()));

				if((*j*time_dilation+time_offset).is_equal(i->get_time()))
				{
					vals.insert(p,*i,time_dilation);
					++i,++j;
				}else if(*i < *j*time_dilation+time_offset)
				{
					++i;
				}else ++j;
			}
			return;
		}
	}

	//parent dynamiclist case - just for active points for that object...
	if(h.parent_is_value_node())
	{
		synfig::ValueNode_DynamicList::Handle p = synfig::ValueNode_DynamicList::Handle::cast_dynamic(h.get_parent_value_node());

		if(p)
		{
			int index = h.get_index();

			//check all the active points in each list...
			const synfig::ActivepointList &a = p->list[index].timing_info;

			//synfig::info("Our parent = dynamic list, searching in %d activepts",a.size());

			std::set<Time>::const_iterator			i = tlist.begin(),
													end = tlist.end();

			synfig::ActivepointList::const_iterator 	j = a.begin(),
													jend = a.end();

			for(; j != jend && i != end;)
			{
				double it = *i*time_dilation+time_offset;
				double jt = j->get_time();
				double diff = (double)(it - jt);

				//synfig::info("\ttpair match(%.4lg) - %.4lg (diff = %lg",it,jt,diff);

				//
				if(abs(diff) < (double)Time::epsilon())
				{
					//synfig::info("\tActivepoint to add being referenced (%x,%s,%.4lg)",
					//				(int)j->get_uid(),j->state?"true":"false", (double)j->time);
					vals.insert(ValueDesc(p,index),*j,time_dilation);
					++i,++j;
				}else if(it < jt)
				{
					++i;
					//synfig::info("\tIncrementing time");
				}
				else
				{
					++j;
					//synfig::info("\tIncrementing actpt");
				}
			}
		}
	}

	//dynamiclist case - we must still make sure that we read from the list entries the time values
	//						because just the linked valuenodes will not do that
	{
		synfig::ValueNode_DynamicList::Handle p = synfig::ValueNode_DynamicList::Handle::cast_dynamic(h.get_value_node());

		if(p)
		{
			//synfig::info("Process dynamic list valuenode");
			int index = 0;

			std::vector<synfig::ValueNode_DynamicList::ListEntry>::const_iterator
							i = p->list.begin(),
							end = p->list.end();

			for(; i != end; ++i, ++index)
			{
				const Node::time_set &tset = i->get_times();

				if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset,time_dilation))
				{
					recurse_valuedesc(ValueDesc(p,index),tlist,vals,time_offset,time_dilation);
				}
			}
			return;
		}
	}

	//the linkable case...
	{
		etl::handle<synfig::LinkableValueNode> p = etl::handle<synfig::LinkableValueNode>::cast_dynamic(h.get_value_node());

		if(p)
		{
			//synfig::info("Process Linkable ValueBasenode");
			int i = 0, size = p->link_count();

			for(; i < size; ++i)
			{
				ValueNode::Handle v = p->get_link(i);
				const Node::time_set &tset = v->get_times();

				if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset,time_dilation))
				{
					recurse_valuedesc(ValueDesc(p,i),tlist,vals,time_offset,time_dilation);
				}
			}
		}
	}
}