Code

New LPE: Text label
[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 "libnr/n-art-bpath-2geom.h"
25 #include "svg/svg.h"
26 #include "nodepath.h"
28 #include <2geom/sbasis.h>
29 #include <2geom/sbasis-2d.h>
30 #include <2geom/sbasis-geometric.h>
31 #include <2geom/bezier-to-sbasis.h>
32 #include <2geom/sbasis-to-bezier.h>
33 #include <2geom/d2.h>
34 #include <2geom/piecewise.h>
35 #include <2geom/transforms.h>
37 #include "desktop.h" // TODO: should be factored out (see below)
39 using namespace Geom;
41 namespace Inkscape {
42 namespace LivePathEffect {
44 LPELattice::LPELattice(LivePathEffectObject *lpeobject) :
45     Effect(lpeobject),
46     
47     // initialise your parameters here:
48     grid_point0(_("Control handle 0"), _("Control handle 0"), "gridpoint0", &wr, this),
49     grid_point1(_("Control handle 1"), _("Control handle 1"), "gridpoint1", &wr, this),
50     grid_point2(_("Control handle 2"), _("Control handle 2"), "gridpoint2", &wr, this),
51     grid_point3(_("Control handle 3"), _("Control handle 3"), "gridpoint3", &wr, this),
52     grid_point4(_("Control handle 4"), _("Control handle 4"), "gridpoint4", &wr, this),
53     grid_point5(_("Control handle 5"), _("Control handle 5"), "gridpoint5", &wr, this),
54     grid_point6(_("Control handle 6"), _("Control handle 6"), "gridpoint6", &wr, this),
55     grid_point7(_("Control handle 7"), _("Control handle 7"), "gridpoint7", &wr, this),
56     grid_point8(_("Control handle 8"), _("Control handle 8"), "gridpoint8", &wr, this),
57     grid_point9(_("Control handle 9"), _("Control handle 9"), "gridpoint9", &wr, this),
58     grid_point10(_("Control handle 10"), _("Control handle 10"), "gridpoint10", &wr, this),
59     grid_point11(_("Control handle 11"), _("Control handle 11"), "gridpoint11", &wr, this),
60     grid_point12(_("Control handle 12"), _("Control handle 12"), "gridpoint12", &wr, this),
61     grid_point13(_("Control handle 13"), _("Control handle 13"), "gridpoint13", &wr, this),
62     grid_point14(_("Control handle 14"), _("Control handle 14"), "gridpoint14", &wr, this),
63     grid_point15(_("Control handle 15"), _("Control handle 15"), "gridpoint15", &wr, this)
64     
65 {
66     // register all your parameters here, so Inkscape knows which parameters this effect has:
67     registerParameter( dynamic_cast<Parameter *>(&grid_point0) );
68     registerParameter( dynamic_cast<Parameter *>(&grid_point1) );
69     registerParameter( dynamic_cast<Parameter *>(&grid_point2) );
70     registerParameter( dynamic_cast<Parameter *>(&grid_point3) );
71     registerParameter( dynamic_cast<Parameter *>(&grid_point4) );
72     registerParameter( dynamic_cast<Parameter *>(&grid_point5) );
73     registerParameter( dynamic_cast<Parameter *>(&grid_point6) );
74     registerParameter( dynamic_cast<Parameter *>(&grid_point7) );
75     registerParameter( dynamic_cast<Parameter *>(&grid_point8) );
76     registerParameter( dynamic_cast<Parameter *>(&grid_point9) );
77     registerParameter( dynamic_cast<Parameter *>(&grid_point10) );
78     registerParameter( dynamic_cast<Parameter *>(&grid_point11) );
79     registerParameter( dynamic_cast<Parameter *>(&grid_point12) );
80     registerParameter( dynamic_cast<Parameter *>(&grid_point13) );
81     registerParameter( dynamic_cast<Parameter *>(&grid_point14) );
82     registerParameter( dynamic_cast<Parameter *>(&grid_point15) );
84     
85 }
87 LPELattice::~LPELattice()
88 {
90 }
93 Geom::Piecewise<Geom::D2<Geom::SBasis> >
94 LPELattice::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
95 {
96     D2<SBasis2d> sb2;
97     
98     //Initialisation of the sb2
99     for(unsigned dim = 0; dim < 2; dim++) {
100         sb2[dim].us = 2;
101         sb2[dim].vs = 2;
102         const int depth = sb2[dim].us*sb2[dim].vs;
103         sb2[dim].resize(depth, Linear2d(0));
104     }
106     //Grouping the point params in a convenient vector
107     std::vector<Geom::Point *> handles(16);
108     
109     handles[0] = &grid_point0;
110     handles[1] = &grid_point1;
111     handles[2] = &grid_point2;
112     handles[3] = &grid_point3;
113     handles[4] = &grid_point4;
114     handles[5] = &grid_point5;
115     handles[6] = &grid_point6;
116     handles[7] = &grid_point7;
117     handles[8] = &grid_point8;
118     handles[9] = &grid_point9;
119     handles[10] = &grid_point10;
120     handles[11] = &grid_point11;
121     handles[12] = &grid_point12;
122     handles[13] = &grid_point13;
123     handles[14] = &grid_point14;
124     handles[15] = &grid_point15;
126     Geom::Point origin = Geom::Point(boundingbox_X.min(),boundingbox_Y.min());
127       
128     double width = boundingbox_X.extent();
129     double height = boundingbox_Y.extent();
131     //numbering is based on 4 rectangles.
132     for(unsigned dim = 0; dim < 2; dim++) {
133         Geom::Point dir(0,0);
134         dir[dim] = 1;
135         for(unsigned vi = 0; vi < sb2[dim].vs; vi++) {
136             for(unsigned ui = 0; ui < sb2[dim].us; ui++) {
137                 for(unsigned iv = 0; iv < 2; iv++) {
138                     for(unsigned iu = 0; iu < 2; iu++) {
139                         unsigned corner = iu + 2*iv;
140                         unsigned i = ui + vi*sb2[dim].us;
141                         
142                         //This is the offset from the Upperleft point
143                         Geom::Point base(   (ui + iu*(3-2*ui))*width/3.,
144                                             (vi + iv*(3-2*vi))*height/3.);
145                        
146                         //Special action for corners
147                         if(vi == 0 && ui == 0) {
148                             base = Geom::Point(0,0);
149                         }
150                         
151                         // i = Upperleft corner of the considerated rectangle
152                         // corner = actual corner of the rectangle
153                         // origin = Upperleft point
154                         double dl = dot((*handles[corner+4*i] - (base + origin)), dir)/dot(dir,dir);
155                         sb2[dim][i][corner] = dl/( dim ? height : width )*pow(4.0,ui+vi);
156                     }
157                 }
158             }
159         }
160     }
161    
162     Piecewise<D2<SBasis> >  output;
163     output.push_cut(0.);
164     for(unsigned i = 0; i < pwd2_in.size(); i++) {
165         D2<SBasis> B = pwd2_in[i];
166         B -= origin;   
167         B*= 1/width;
168         //Here comes the magic
169         D2<SBasis> tB = compose_each(sb2,B);
170         tB = tB * width + origin;
172         output.push(tB,i+1);
173     }
175     return output;
178 void
179 LPELattice::doBeforeEffect (SPLPEItem *lpeitem)
181     original_bbox(lpeitem);
184 void
185 LPELattice::resetDefaults(SPItem * 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 :