1 /* === S Y N F I G ========================================================= */
2 /*! \file timegather.cpp
3 ** \brief Time Gather File
8 ** Copyright (c) 2004 Adrian Bentley
9 ** Copyright (c) 2007 Chris Moore
11 ** This package is free software; you can redistribute it and/or
12 ** modify it under the terms of the GNU General Public License as
13 ** published by the Free Software Foundation; either version 2 of
14 ** the License, or (at your option) any later version.
16 ** This package is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 ** General Public License for more details.
22 /* ========================================================================= */
24 /* === H E A D E R S ======================================================= */
33 #include "timegather.h"
34 #include "value_desc.h"
36 #include <synfig/layer_pastecanvas.h>
42 /* === U S I N G =========================================================== */
46 using namespace synfig;
47 using namespace synfigapp;
49 /* === M A C R O S ========================================================= */
51 /* === G L O B A L S ======================================================= */
53 /* === P R O C E D U R E S ================================================= */
55 /* === M E T H O D S ======================================================= */
57 /* === E N T R Y P O I N T ================================================= */
59 //! Definitions for build a list of accurate valuenode references
61 void synfigapp::timepoints_ref::insert(synfig::ValueNode_Animated::Handle v, synfig::Waypoint w)
66 waytracker::iterator i = waypointbiglist.find(vt);
68 if(i != waypointbiglist.end())
70 i->waypoints.insert(w);
73 vt.waypoints.insert(w);
74 waypointbiglist.insert(vt);
78 void synfigapp::timepoints_ref::insert(synfigapp::ValueDesc v, synfig::Activepoint a)
83 acttracker::iterator i = actpointbiglist.find(vt);
85 if(i != actpointbiglist.end())
87 i->activepoints.insert(a);
89 synfig::info("!!!!For some reason it wasn't able to insert the activepoint in the list (%s,%.4lg)",
90 a.state?"true":"false", (double)a.time);
94 vt.activepoints.insert(a);
95 actpointbiglist.insert(vt);
96 //synfig::info("Insert new activept list for valdesc");
100 //recursion functions
101 void synfigapp::recurse_canvas(synfig::Canvas::Handle h, const std::set<Time> &tlist,
102 timepoints_ref &vals, synfig::Time time_offset)
105 //synfig::info("Canvas...\n Recurse through layers");
106 // iterate through the layers
108 synfig::Canvas::iterator i = h->begin(), end = h->end();
112 const Node::time_set &tset = (*i)->get_times();
113 if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset))
115 recurse_layer(*i,tlist,vals,time_offset);
120 void synfigapp::recurse_layer(synfig::Layer::Handle h, const std::set<Time> &tlist,
121 timepoints_ref &vals, synfig::Time time_offset)
123 // iterate through the layers
124 //check for special case of paste canvas
125 etl::handle<synfig::Layer_PasteCanvas> p = etl::handle<synfig::Layer_PasteCanvas>::cast_dynamic(h);
127 //synfig::info("Layer...");
131 //synfig::info("We are a paste canvas so go into that");
132 //recurse into the canvas
133 const synfig::Node::time_set &tset = p->get_sub_canvas()->get_times();
134 synfig::Time subcanvas_time_offset(time_offset + p->get_time_offset());
136 if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),subcanvas_time_offset))
137 recurse_canvas(p->get_sub_canvas(),tlist,vals,subcanvas_time_offset);
140 //check all the valuenodes regardless...
141 //synfig::info("Recurse all valuenodes");
142 synfig::Layer::DynamicParamList::const_iterator i = h->dynamic_param_list().begin(),
143 end = h->dynamic_param_list().end();
146 const synfig::Node::time_set &tset = i->second->get_times();
148 if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset))
150 recurse_valuedesc(ValueDesc(h,i->first),tlist,vals,time_offset);
155 template < typename IT, typename CMP >
156 static bool sorted(IT i,IT end, const CMP &cmp = CMP())
158 if(i == end) return true;
160 for(IT last = i++; i != end; last = i++)
169 void synfigapp::recurse_valuedesc(synfigapp::ValueDesc h, const std::set<Time> &tlist,
170 timepoints_ref &vals, synfig::Time time_offset)
172 //special cases for Animated, DynamicList, and Linkable
174 //synfig::info("ValueBasenode... %p, %s", h.get_value_node().get(),typeid(*h.get_value_node()).name());
179 synfig::ValueNode_Animated::Handle p = synfig::ValueNode_Animated::Handle::cast_dynamic(h.get_value_node());
183 //loop through and determine which waypoint we will need to reference
184 const synfig::WaypointList &w = p->waypoint_list();
186 synfig::WaypointList::const_iterator i = w.begin(),
189 std::set<Time>::const_iterator j = tlist.begin(),
191 for(; i != end && j != jend;)
193 //synfig::info("tpair t(%.3f) = %.3f", (float)*j, (float)(i->get_time()));
195 if((*j+time_offset).is_equal(i->get_time()))
199 }else if(*i < *j+time_offset)
208 //parent dynamiclist case - just for active points for that object...
209 if(h.parent_is_value_node())
211 synfig::ValueNode_DynamicList::Handle p = synfig::ValueNode_DynamicList::Handle::cast_dynamic(h.get_parent_value_node());
215 int index = h.get_index();
217 //check all the active points in each list...
218 const synfig::ActivepointList &a = p->list[index].timing_info;
220 //synfig::info("Our parent = dynamic list, searching in %d activepts",a.size());
222 std::set<Time>::const_iterator i = tlist.begin(),
225 synfig::ActivepointList::const_iterator j = a.begin(),
228 for(; j != jend && i != end;)
230 double it = *i+time_offset;
231 double jt = j->get_time();
232 double diff = (double)(it - jt);
234 //synfig::info("\ttpair match(%.4lg) - %.4lg (diff = %lg",it,jt,diff);
237 if(abs(diff) < (double)Time::epsilon())
239 //synfig::info("\tActivepoint to add being referenced (%x,%s,%.4lg)",
240 // (int)j->get_uid(),j->state?"true":"false", (double)j->time);
241 vals.insert(ValueDesc(p,index),*j);
246 //synfig::info("\tIncrementing time");
251 //synfig::info("\tIncrementing actpt");
257 //dynamiclist case - we must still make sure that we read from the list entries the time values
258 // because just the linked valuenodes will not do that
260 synfig::ValueNode_DynamicList::Handle p = synfig::ValueNode_DynamicList::Handle::cast_dynamic(h.get_value_node());
264 //synfig::info("Process dynamic list valuenode");
267 std::vector<synfig::ValueNode_DynamicList::ListEntry>::const_iterator
271 for(; i != end; ++i, ++index)
273 const Node::time_set &tset = i->get_times();
275 if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset))
277 recurse_valuedesc(ValueDesc(p,index),tlist,vals,time_offset);
284 //the linkable case...
286 etl::handle<synfig::LinkableValueNode> p = etl::handle<synfig::LinkableValueNode>::cast_dynamic(h.get_value_node());
290 //synfig::info("Process Linkable ValueBasenode");
291 int i = 0, size = p->link_count();
295 ValueNode::Handle v = p->get_link(i);
296 const Node::time_set &tset = v->get_times();
298 if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset))
300 recurse_valuedesc(ValueDesc(p,i),tlist,vals,time_offset);