Code

Win32 post-GSoC fixups.
[inkscape.git] / src / live_effects / lpe-lattice.cpp
1 #define INKSCAPE_LPE_LATTICE_CPP
2 /** \file
3  * LPE <lattice> implementation
4  
5  */
6 /*
7  * Authors:
8  *   Johan Engelen <j.b.c.engelen@utwente.nl>
9  *   Steren Giannini
10  *   NoĆ© Falzon
11  *   Victor Navez
12 *
13 * Copyright (C) 2007-2008 Authors 
14  *
15  * Released under GNU GPL, read the file 'COPYING' for more information
16  */
18 #include "live_effects/lpe-lattice.h"
20 #include "sp-shape.h"
21 #include "sp-item.h"
22 #include "sp-path.h"
23 #include "display/curve.h"
24 #include "svg/svg.h"
26 #include <2geom/sbasis.h>
27 #include <2geom/sbasis-2d.h>
28 #include <2geom/sbasis-geometric.h>
29 #include <2geom/bezier-to-sbasis.h>
30 #include <2geom/sbasis-to-bezier.h>
31 #include <2geom/d2.h>
32 #include <2geom/piecewise.h>
33 #include <2geom/transforms.h>
35 #include "desktop.h" // TODO: should be factored out (see below)
37 using namespace Geom;
39 namespace Inkscape {
40 namespace LivePathEffect {
42 LPELattice::LPELattice(LivePathEffectObject *lpeobject) :
43     Effect(lpeobject),
44     
45     // initialise your parameters here:
46     grid_point0(_("Control handle 0"), _("Control handle 0"), "gridpoint0", &wr, this),
47     grid_point1(_("Control handle 1"), _("Control handle 1"), "gridpoint1", &wr, this),
48     grid_point2(_("Control handle 2"), _("Control handle 2"), "gridpoint2", &wr, this),
49     grid_point3(_("Control handle 3"), _("Control handle 3"), "gridpoint3", &wr, this),
50     grid_point4(_("Control handle 4"), _("Control handle 4"), "gridpoint4", &wr, this),
51     grid_point5(_("Control handle 5"), _("Control handle 5"), "gridpoint5", &wr, this),
52     grid_point6(_("Control handle 6"), _("Control handle 6"), "gridpoint6", &wr, this),
53     grid_point7(_("Control handle 7"), _("Control handle 7"), "gridpoint7", &wr, this),
54     grid_point8(_("Control handle 8"), _("Control handle 8"), "gridpoint8", &wr, this),
55     grid_point9(_("Control handle 9"), _("Control handle 9"), "gridpoint9", &wr, this),
56     grid_point10(_("Control handle 10"), _("Control handle 10"), "gridpoint10", &wr, this),
57     grid_point11(_("Control handle 11"), _("Control handle 11"), "gridpoint11", &wr, this),
58     grid_point12(_("Control handle 12"), _("Control handle 12"), "gridpoint12", &wr, this),
59     grid_point13(_("Control handle 13"), _("Control handle 13"), "gridpoint13", &wr, this),
60     grid_point14(_("Control handle 14"), _("Control handle 14"), "gridpoint14", &wr, this),
61     grid_point15(_("Control handle 15"), _("Control handle 15"), "gridpoint15", &wr, this)
62     
63 {
64     // register all your parameters here, so Inkscape knows which parameters this effect has:
65     registerParameter( dynamic_cast<Parameter *>(&grid_point0) );
66     registerParameter( dynamic_cast<Parameter *>(&grid_point1) );
67     registerParameter( dynamic_cast<Parameter *>(&grid_point2) );
68     registerParameter( dynamic_cast<Parameter *>(&grid_point3) );
69     registerParameter( dynamic_cast<Parameter *>(&grid_point4) );
70     registerParameter( dynamic_cast<Parameter *>(&grid_point5) );
71     registerParameter( dynamic_cast<Parameter *>(&grid_point6) );
72     registerParameter( dynamic_cast<Parameter *>(&grid_point7) );
73     registerParameter( dynamic_cast<Parameter *>(&grid_point8) );
74     registerParameter( dynamic_cast<Parameter *>(&grid_point9) );
75     registerParameter( dynamic_cast<Parameter *>(&grid_point10) );
76     registerParameter( dynamic_cast<Parameter *>(&grid_point11) );
77     registerParameter( dynamic_cast<Parameter *>(&grid_point12) );
78     registerParameter( dynamic_cast<Parameter *>(&grid_point13) );
79     registerParameter( dynamic_cast<Parameter *>(&grid_point14) );
80     registerParameter( dynamic_cast<Parameter *>(&grid_point15) );
82     
83 }
85 LPELattice::~LPELattice()
86 {
88 }
91 Geom::Piecewise<Geom::D2<Geom::SBasis> >
92 LPELattice::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
93 {
94     D2<SBasis2d> sb2;
95     
96     //Initialisation of the sb2
97     for(unsigned dim = 0; dim < 2; dim++) {
98         sb2[dim].us = 2;
99         sb2[dim].vs = 2;
100         const int depth = sb2[dim].us*sb2[dim].vs;
101         sb2[dim].resize(depth, Linear2d(0));
102     }
104     //Grouping the point params in a convenient vector
105     std::vector<Geom::Point *> handles(16);
106     
107     handles[0] = &grid_point0;
108     handles[1] = &grid_point1;
109     handles[2] = &grid_point2;
110     handles[3] = &grid_point3;
111     handles[4] = &grid_point4;
112     handles[5] = &grid_point5;
113     handles[6] = &grid_point6;
114     handles[7] = &grid_point7;
115     handles[8] = &grid_point8;
116     handles[9] = &grid_point9;
117     handles[10] = &grid_point10;
118     handles[11] = &grid_point11;
119     handles[12] = &grid_point12;
120     handles[13] = &grid_point13;
121     handles[14] = &grid_point14;
122     handles[15] = &grid_point15;
124     Geom::Point origin = Geom::Point(boundingbox_X.min(),boundingbox_Y.min());
125       
126     double width = boundingbox_X.extent();
127     double height = boundingbox_Y.extent();
129     //numbering is based on 4 rectangles.
130     for(unsigned dim = 0; dim < 2; dim++) {
131         Geom::Point dir(0,0);
132         dir[dim] = 1;
133         for(unsigned vi = 0; vi < sb2[dim].vs; vi++) {
134             for(unsigned ui = 0; ui < sb2[dim].us; ui++) {
135                 for(unsigned iv = 0; iv < 2; iv++) {
136                     for(unsigned iu = 0; iu < 2; iu++) {
137                         unsigned corner = iu + 2*iv;
138                         unsigned i = ui + vi*sb2[dim].us;
139                         
140                         //This is the offset from the Upperleft point
141                         Geom::Point base(   (ui + iu*(3-2*ui))*width/3.,
142                                             (vi + iv*(3-2*vi))*height/3.);
143                        
144                         //Special action for corners
145                         if(vi == 0 && ui == 0) {
146                             base = Geom::Point(0,0);
147                         }
148                         
149                         // i = Upperleft corner of the considerated rectangle
150                         // corner = actual corner of the rectangle
151                         // origin = Upperleft point
152                         double dl = dot((*handles[corner+4*i] - (base + origin)), dir)/dot(dir,dir);
153                         sb2[dim][i][corner] = dl/( dim ? height : width )*pow(4.0,ui+vi);
154                     }
155                 }
156             }
157         }
158     }
159    
160     Piecewise<D2<SBasis> >  output;
161     output.push_cut(0.);
162     for(unsigned i = 0; i < pwd2_in.size(); i++) {
163         D2<SBasis> B = pwd2_in[i];
164         B -= origin;   
165         B*= 1/width;
166         //Here comes the magic
167         D2<SBasis> tB = compose_each(sb2,B);
168         tB = tB * width + origin;
170         output.push(tB,i+1);
171     }
173     return output;
176 void
177 LPELattice::doBeforeEffect (SPLPEItem *lpeitem)
179     original_bbox(lpeitem);
182 void
183 LPELattice::resetDefaults(SPItem * item)
185     Effect::resetDefaults(item);
187     original_bbox(SP_LPE_ITEM(item), false);
188     
189     // place the 16 control points
190     grid_point0[Geom::X] = boundingbox_X.min();
191     grid_point0[Geom::Y] = boundingbox_Y.min();
192     
193     grid_point1[Geom::X] = boundingbox_X.max();
194     grid_point1[Geom::Y] = boundingbox_Y.min();
195     
196     grid_point2[Geom::X] = boundingbox_X.min();
197     grid_point2[Geom::Y] = boundingbox_Y.max();
198     
199     grid_point3[Geom::X] = boundingbox_X.max();
200     grid_point3[Geom::Y] = boundingbox_Y.max();
201     
202     grid_point4[Geom::X] = 1.0/3*boundingbox_X.max()+2.0/3*boundingbox_X.min();
203     grid_point4[Geom::Y] = boundingbox_Y.min();
204     
205     grid_point5[Geom::X] = 2.0/3*boundingbox_X.max()+1.0/3*boundingbox_X.min();
206     grid_point5[Geom::Y] = boundingbox_Y.min();
207     
208     grid_point6[Geom::X] = 1.0/3*boundingbox_X.max()+2.0/3*boundingbox_X.min();
209     grid_point6[Geom::Y] = boundingbox_Y.max();
210     
211     grid_point7[Geom::X] = 2.0/3*boundingbox_X.max()+1.0/3*boundingbox_X.min();
212     grid_point7[Geom::Y] = boundingbox_Y.max();
213     
214     grid_point8[Geom::X] = boundingbox_X.min();
215     grid_point8[Geom::Y] = 1.0/3*boundingbox_Y.max()+2.0/3*boundingbox_Y.min();     
217     grid_point9[Geom::X] = boundingbox_X.max();
218     grid_point9[Geom::Y] = 1.0/3*boundingbox_Y.max()+2.0/3*boundingbox_Y.min();
219         
220     grid_point10[Geom::X] = boundingbox_X.min();
221     grid_point10[Geom::Y] = 2.0/3*boundingbox_Y.max()+1.0/3*boundingbox_Y.min();  
222     
223     grid_point11[Geom::X] = boundingbox_X.max();
224     grid_point11[Geom::Y] = 2.0/3*boundingbox_Y.max()+1.0/3*boundingbox_Y.min();  
225     
226     grid_point12[Geom::X] = 1.0/3*boundingbox_X.max()+2.0/3*boundingbox_X.min();
227     grid_point12[Geom::Y] = 1.0/3*boundingbox_Y.max()+2.0/3*boundingbox_Y.min();
228     
229     grid_point13[Geom::X] = 2.0/3*boundingbox_X.max()+1.0/3*boundingbox_X.min();
230     grid_point13[Geom::Y] = 1.0/3*boundingbox_Y.max()+2.0/3*boundingbox_Y.min();
231     
232     grid_point14[Geom::X] = 1.0/3*boundingbox_X.max()+2.0/3*boundingbox_X.min();
233     grid_point14[Geom::Y] = 2.0/3*boundingbox_Y.max()+1.0/3*boundingbox_Y.min();
234     
235     grid_point15[Geom::X] = 2.0/3*boundingbox_X.max()+1.0/3*boundingbox_X.min();
236     grid_point15[Geom::Y] = 2.0/3*boundingbox_Y.max()+1.0/3*boundingbox_Y.min();
239 /**
240 void
241 LPELattice::addHelperPathsImpl(SPLPEItem *lpeitem, SPDesktop *desktop)
243     SPCurve *c = new SPCurve ();
244     c->moveto(grid_point0);
245     c->lineto(grid_point4);
246     c->lineto(grid_point5);
247     c->lineto(grid_point1);
249     c->moveto(grid_point8);
250     c->lineto(grid_point12);
251     c->lineto(grid_point13);
252     c->lineto(grid_point9);
254     c->moveto(grid_point10);
255     c->lineto(grid_point14);
256     c->lineto(grid_point15);
257     c->lineto(grid_point11);
259     c->moveto(grid_point2);
260     c->lineto(grid_point6);
261     c->lineto(grid_point7);
262     c->lineto(grid_point3);
265     c->moveto(grid_point0);
266     c->lineto(grid_point8);
267     c->lineto(grid_point10);
268     c->lineto(grid_point2);
270     c->moveto(grid_point4);
271     c->lineto(grid_point12);
272     c->lineto(grid_point14);
273     c->lineto(grid_point6);
275     c->moveto(grid_point5);
276     c->lineto(grid_point13);
277     c->lineto(grid_point15);
278     c->lineto(grid_point7);
280     c->moveto(grid_point1);
281     c->lineto(grid_point9);
282     c->lineto(grid_point11);
283     c->lineto(grid_point3);
285     // TODO: factor this out (and remove the #include of desktop.h above)
286     SPCanvasItem *canvasitem = sp_nodepath_generate_helperpath(desktop, c, SP_ITEM(lpeitem), 0x009000ff);
287     Inkscape::Display::TemporaryItem* tmpitem = desktop->add_temporary_canvasitem (canvasitem, 0);
288     lpeitem->lpe_helperpaths.push_back(tmpitem);
290     c->unref();
292 **/
294 /* ######################## */
296 } //namespace LivePathEffect
297 } /* namespace Inkscape */
299 /*
300   Local Variables:
301   mode:c++
302   c-file-style:"stroustrup"
303   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
304   indent-tabs-mode:nil
305   fill-column:99
306   End:
307 */
308 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :