Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_05 / synfig-core / src / modules / mod_geometry / region.cpp
1 /*! ========================================================================
2 ** Synfig
3 ** Template File
4 ** $Id: region.cpp,v 1.1.1.1 2005/01/04 01:23:10 darco Exp $
5 **
6 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
7 **
8 **      This package is free software; you can redistribute it and/or
9 **      modify it under the terms of the GNU General Public License as
10 **      published by the Free Software Foundation; either version 2 of
11 **      the License, or (at your option) any later version.
12 **
13 **      This package is distributed in the hope that it will be useful,
14 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
15 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 **      General Public License for more details.
17 **
18 ** === N O T E S ===========================================================
19 **
20 ** ========================================================================= */
21
22 /* === H E A D E R S ======================================================= */
23
24 #ifdef USING_PCH
25 #       include "pch.h"
26 #else
27 #ifdef HAVE_CONFIG_H
28 #       include <config.h>
29 #endif
30
31 #include "region.h"
32 #include <ETL/stringf>
33 #include <ETL/bezier>
34 #include <ETL/hermite>
35
36 #include <synfig/string.h>
37 #include <synfig/time.h>
38 #include <synfig/context.h>
39 #include <synfig/paramdesc.h>
40 #include <synfig/renddesc.h>
41 #include <synfig/surface.h>
42 #include <synfig/value.h>
43 #include <synfig/valuenode.h>
44 #include <synfig/segment.h>
45 #include <synfig/valuenode_bline.h>
46
47 #endif
48
49 using namespace etl;
50
51 /* === M A C R O S ========================================================= */
52
53 #define SAMPLES         75
54
55 /* === G L O B A L S ======================================================= */
56
57 SYNFIG_LAYER_INIT(Region);
58 SYNFIG_LAYER_SET_NAME(Region,"region");
59 SYNFIG_LAYER_SET_LOCAL_NAME(Region,_("Region"));
60 SYNFIG_LAYER_SET_CATEGORY(Region,_("Geometry"));
61 SYNFIG_LAYER_SET_VERSION(Region,"0.1");
62 SYNFIG_LAYER_SET_CVS_ID(Region,"$Id: region.cpp,v 1.1.1.1 2005/01/04 01:23:10 darco Exp $");
63
64 /* === P R O C E D U R E S ================================================= */
65
66 /* === M E T H O D S ======================================================= */
67
68 /* === E N T R Y P O I N T ================================================= */
69
70 Region::Region()
71 {
72         clear();
73         vector<BLinePoint> bline_point_list;
74         bline_point_list.push_back(BLinePoint());
75         bline_point_list.push_back(BLinePoint());
76         bline_point_list.push_back(BLinePoint());
77         bline_point_list[0].set_vertex(Point(0,1));     
78         bline_point_list[1].set_vertex(Point(0,-1));    
79         bline_point_list[2].set_vertex(Point(1,0));
80         bline_point_list[0].set_tangent(bline_point_list[1].get_vertex()-bline_point_list[2].get_vertex()*0.5f);        
81         bline_point_list[1].set_tangent(bline_point_list[2].get_vertex()-bline_point_list[0].get_vertex()*0.5f);        
82         bline_point_list[2].set_tangent(bline_point_list[0].get_vertex()-bline_point_list[1].get_vertex()*0.5f);        
83         bline_point_list[0].set_width(1.0f);    
84         bline_point_list[1].set_width(1.0f);    
85         bline_point_list[2].set_width(1.0f);    
86         bline=bline_point_list;
87 }
88
89 void
90 Region::sync()
91 {
92         if(bline.get_contained_type()==ValueBase::TYPE_BLINEPOINT)
93         {
94                 segment_list=convert_bline_to_segment_list(bline);
95         }
96         else
97         {
98                 synfig::warning("Region: incorrect type on bline, layer disabled");
99                 clear();
100                 return;
101         }
102
103         if(segment_list.empty())
104         {
105                 synfig::warning("Region: segment_list is empty, layer disabled");
106                 clear();
107                 return;
108         }
109         
110         bool looped = bline.get_loop();
111
112         Vector::value_type n;
113         etl::hermite<Vector> curve;
114         vector<Point> vector_list;
115
116         vector<Segment>::const_iterator iter=segment_list.begin();
117         //Vector                                                        last = iter->p1;
118         
119         //make sure the shape has a clean slate for writing
120         //clear();
121         
122         //and start off at the first point
123         //move_to(last[0],last[1]);
124         
125         for(;iter!=segment_list.end();++iter)
126         {
127                 //connect them with a line if they aren't already joined
128                 /*if(iter->p1 != last)
129                 {
130                         line_to(iter->p1[0],iter->p1[1]);
131                 }
132                 
133                 //curve to the next end point
134                 curve_to(iter->p1[0] + iter->t1[0]/3.0,iter->p1[1] + iter->t1[1]/3.0,
135                                  iter->p2[0] - iter->t2[0]/3.0,iter->p2[1] - iter->t2[1]/3.0,
136                                  iter->p2[0],iter->p2[1]);
137                 
138                 last = iter->p2;*/
139                 
140                 if(iter->t1.is_equal_to(Vector(0,0)) && iter->t2.is_equal_to(Vector(0,0)))
141                 {
142                         vector_list.push_back(iter->p2);
143                 }
144                 else
145                 {
146                         curve.p1()=iter->p1;
147                         curve.t1()=iter->t1;
148                         curve.p2()=iter->p2;
149                         curve.t2()=iter->t2;
150                         curve.sync();
151
152                         for(n=0.0;n<1.0;n+=1.0/SAMPLES)
153                                 vector_list.push_back(curve(n));
154                 }
155         }
156         
157         //add a single point onto the end so it actually fits the shape, so we can be awesome...
158         if(!looped)
159         {
160                 vector_list.push_back(curve.p2());
161         }
162
163         clear();
164         add_polygon(vector_list);
165         
166         /*close();
167         endpath();*/
168 }
169
170 bool
171 Region::set_param(const String & param, const ValueBase &value)
172 {
173         if(param=="segment_list")
174         {
175                 if(dynamic_param_list().count("segment_list"))
176                 {
177                         connect_dynamic_param("bline",dynamic_param_list().find("segment_list")->second);
178                         disconnect_dynamic_param("segment_list");
179                         synfig::warning("Region::set_param(): Updated valuenode connection to use the new \"bline\" parameter.");
180                 }
181                 else
182                         synfig::warning("Region::set_param(): The parameter \"segment_list\" is deprecated. Use \"bline\" instead.");
183         }
184         
185         if(     (param=="segment_list" || param=="bline") && value.get_type()==ValueBase::TYPE_LIST)
186         {
187                 //if(value.get_contained_type()!=ValueBase::TYPE_BLINEPOINT)
188                 //      return false;
189                         
190                 bline=value;
191
192                 return true;
193         }
194
195 /*      if(     param=="segment_list" && value.get_type()==ValueBase::TYPE_LIST)
196         {
197                 if(value.get_contained_type()==ValueBase::TYPE_BLINEPOINT)
198                         segment_list=convert_bline_to_segment_list(value);
199                 else
200                 if(value.get_contained_type()==ValueBase::TYPE_SEGMENT)
201                         segment_list=value;
202                 else
203                 if(value.empty())
204                         segment_list.clear();
205                 else
206                         return false;
207                 sync();
208                 return true;
209         }
210         */
211         return Layer_Shape::set_param(param,value);
212 }
213
214 ValueBase
215 Region::get_param(const String& param)const
216 {
217         EXPORT(bline);
218         EXPORT_NAME();
219         EXPORT_VERSION();
220
221         return Layer_Shape::get_param(param);
222 }
223
224 Layer::Vocab
225 Region::get_param_vocab()const
226 {
227         Layer::Vocab ret(Layer_Shape::get_param_vocab());
228
229         ret.push_back(ParamDesc("bline")
230                 .set_local_name(_("Vertices"))
231                 .set_origin("offset")
232         );
233
234         return ret;
235 }
236
237 void
238 Region::set_time(Context context, Time time)const
239 {
240         const_cast<Region*>(this)->sync();
241         context.set_time(time);
242 }
243
244 void
245 Region::set_time(Context context, Time time, Vector pos)const
246 {
247         const_cast<Region*>(this)->sync();
248         context.set_time(time,pos);
249 }