38
38
#include < synfig/string.h>
39
39
#include < synfig/context.h>
40
40
#include < synfig/paramdesc.h>
41
- #include < synfig/renddesc.h>
42
- #include < synfig/surface.h>
41
+ #include < synfig/rendering/software/task/taskpaintpixelsw.h>
43
42
#include < synfig/value.h>
44
43
45
44
#include " metaballs.h"
@@ -60,9 +59,79 @@ SYNFIG_LAYER_SET_VERSION(Metaballs,"0.1");
60
59
61
60
/* === P R O C E D U R E S ================================================= */
62
61
63
- /* === M E T H O D S ======================================================= */
62
+ class TaskMetaballs : public rendering ::Task
63
+ {
64
+ public:
65
+ typedef etl::handle<TaskMetaballs> Handle ;
66
+ SYNFIG_EXPORT static Token token;
67
+ Token::Handle get_token () const override { return token.handle (); }
68
+
69
+ std::vector<synfig::Point > centers;
70
+ std::vector<synfig::Real> radii;
71
+ std::vector<synfig::Real> weights;
72
+ synfig::Real threshold;
73
+ synfig::Real threshold2;
74
+ bool positive;
75
+ Gradient gradient;
76
+ };
77
+
78
+
79
+ class TaskMetaballsSW : public TaskMetaballs , public rendering ::TaskPaintPixelSW
80
+ {
81
+ public:
82
+ typedef etl::handle<TaskMetaballs> Handle ;
83
+ SYNFIG_EXPORT static Token token;
84
+ Token::Handle get_token () const override { return token.handle (); }
85
+
86
+ Color get_color (const Vector& p) const override
87
+ {
88
+ return gradient (totaldensity (p));
89
+ }
90
+
91
+ bool run (RunParams&) const override {
92
+ return run_task ();
93
+ }
94
+
95
+ Real
96
+ densityfunc (const Point & p, const Point & c, Real R) const
97
+ {
98
+ const Real dx = p[0 ] - c[0 ];
99
+ const Real dy = p[1 ] - c[1 ];
100
+
101
+ const Real n = (1 - (dx*dx + dy*dy)/(R*R));
102
+ if (positive && n < 0 )
103
+ return 0 ;
104
+ return n*n*n;
105
+
106
+ /*
107
+ f(d) = (1 - d^2)^3
108
+ f'(d) = -6d * (1 - d^2)^2
109
+
110
+ could use this too...
111
+ f(d) = (1 - d^2)^2
112
+ f'(d) = -6d * (1 - d^2)
113
+ */
114
+ }
64
115
65
- /* === E N T R Y P O I N T ================================================= */
116
+ Real
117
+ totaldensity (const Point & pos) const
118
+ {
119
+ Real density = 0 ;
120
+
121
+ // sum up weighted functions
122
+ for (unsigned int i = 0 ; i < centers.size (); i++)
123
+ density += weights[i] * densityfunc (pos, centers[i], radii[i]);
124
+
125
+ return (density - threshold) / (threshold2 - threshold);
126
+ }
127
+ };
128
+
129
+ SYNFIG_EXPORT rendering::Task::Token TaskMetaballs::token (
130
+ DescAbstract<TaskMetaballs>(" Metaballs" ) );
131
+ SYNFIG_EXPORT rendering::Task::Token TaskMetaballsSW::token (
132
+ DescReal<TaskMetaballsSW, TaskMetaballs>(" MetaballsSW" ) );
133
+
134
+ /* === M E T H O D S ======================================================= */
66
135
67
136
Metaballs::Metaballs ():
68
137
Layer_Composite(1.0 ,Color::BLEND_COMPOSITE),
@@ -223,39 +292,17 @@ Metaballs::get_color(Context context, const Point &pos)const
223
292
}
224
293
225
294
226
-
227
- bool
228
- Metaballs::accelerated_render (Context context,Surface *surface,int quality, const RendDesc &renddesc, ProgressCallback *cb)const
295
+ rendering::Task::Handle
296
+ Metaballs::build_composite_task_vfunc (ContextParams /* context_params*/ ) const
229
297
{
230
- RENDER_TRANSFORMED_IF_NEED (__FILE__, __LINE__)
231
-
232
- Gradient gradient=param_gradient.get (Gradient ());
233
-
234
- // Width and Height of a pixel
235
- const Point /* br(renddesc.get_br()),*/ tl (renddesc.get_tl ());
236
- const int w (renddesc.get_w ()), h (renddesc.get_h ());
237
- const Real pw (renddesc.get_pw ()), ph (renddesc.get_ph ());
238
-
239
- SuperCallback supercb (cb,0 ,9000 ,10000 );
240
-
241
- Point pos (tl[0 ],tl[1 ]);
242
-
243
- if (!context.accelerated_render (surface,quality,renddesc,&supercb))
244
- {
245
- if (cb)cb->error (strprintf (__FILE__" %d: Accelerated Renderer Failure" ,__LINE__));
246
- return false ;
247
- }
248
-
249
- for (int y = 0 ; y < h; y++, pos[1 ] += ph)
250
- {
251
- pos[0 ] = tl[0 ];
252
- for (int x = 0 ; x < w; x++, pos[0 ] += pw)
253
- (*surface)[y][x] = Color::blend (gradient (totaldensity (pos)),(*surface)[y][x],get_amount (),get_blend_method ());
254
- }
255
-
256
- // Mark our progress as finished
257
- if (cb && !cb->amount_complete (10000 ,10000 ))
258
- return false ;
259
-
260
- return true ;
298
+ TaskMetaballs::Handle task (new TaskMetaballs ());
299
+ task->centers = param_centers.get_list_of (synfig::Point ());
300
+ task->radii = param_radii.get_list_of (synfig::Real ());
301
+ task->weights = param_weights.get_list_of (synfig::Real ());
302
+ task->threshold = param_threshold.get (Real ());
303
+ task->threshold2 = param_threshold2.get (Real ());
304
+ task->gradient = param_gradient.get (Gradient ());
305
+ task->positive = param_positive.get (bool ());
306
+
307
+ return task;
261
308
}
0 commit comments