OSDN Git Service

2056fb544272a7293eecb478daff510c0de513fa
[mypaint-anime/master.git] / brushlib / brush.hpp
1 /* brushlib - The MyPaint Brush Library
2  * Copyright (C) 2007-2011 Martin Renold <martinxyz@gmx.ch>
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <stdio.h>
18 #include <string.h>
19 #include <glib.h>
20 #include <math.h>
21 #include "Python.h"
22
23 #include "brushsettings.hpp"
24 #include "mapping.hpp"
25
26 #define ACTUAL_RADIUS_MIN 0.2
27 #define ACTUAL_RADIUS_MAX 800 // safety guard against radius like 1e20 and against rendering overload with unexpected brush dynamics
28
29 /* The Brush class stores two things:
30    b) settings: constant during a stroke (eg. size, spacing, dynamics, color selected by the user)
31    a) states: modified during a stroke (eg. speed, smudge colors, time/distance to next dab, position filter states)
32
33    FIXME: Actually those are two orthogonal things. Should separate them:
34           a) brush settings class that is saved/loaded/selected  (without states)
35           b) brush core class to draw the dabs (using an instance of the above)
36
37    In python, there are two kinds of instances from this: a "global
38    brush" which does the cursor tracking, and the "brushlist" where
39    the states are ignored. When a brush is selected, its settings are
40    copied into the global one, leaving the state intact.
41  */
42
43
44 class Brush {
45 public:
46   bool print_inputs; // debug menu
47   // for stroke splitting (undo/redo)
48   double stroke_total_painting_time;
49   double stroke_current_idling_time; 
50
51 private:
52   // see also brushsettings.py
53
54   // the states (get_state, set_state, reset) that change during a stroke
55   float states[STATE_COUNT];
56   GRand * rng;
57
58   // Those mappings describe how to calculate the current value for each setting.
59   // Most of settings will be constant (eg. only their base_value is used).
60   Mapping * settings[BRUSH_SETTINGS_COUNT];
61
62   // the current value of all settings (calculated using the current state)
63   float settings_value[BRUSH_SETTINGS_COUNT];
64
65   // cached calculation results
66   float speed_mapping_gamma[2], speed_mapping_m[2], speed_mapping_q[2];
67
68   bool reset_requested;
69
70 public:
71   Brush() {
72     for (int i=0; i<BRUSH_SETTINGS_COUNT; i++) {
73       settings[i] = new Mapping(INPUT_COUNT);
74     }
75     rng = g_rand_new();
76     print_inputs = false;
77     
78     for (int i=0; i<STATE_COUNT; i++) {
79       states[i] = 0;
80     }
81     new_stroke();
82
83     settings_base_values_have_changed();
84
85     reset_requested = true;
86   }
87
88   ~Brush() {
89     for (int i=0; i<BRUSH_SETTINGS_COUNT; i++) {
90       delete settings[i];
91     }
92     g_rand_free (rng); rng = NULL;
93   }
94
95   void reset()
96   {
97     reset_requested = true;
98   }
99
100   void new_stroke()
101   {
102     stroke_current_idling_time = 0;
103     stroke_total_painting_time = 0;
104   }
105
106   void set_base_value (int id, float value) {
107     g_assert (id >= 0 && id < BRUSH_SETTINGS_COUNT);
108     settings[id]->base_value = value;
109
110     settings_base_values_have_changed ();
111   }
112
113   void set_mapping_n (int id, int input, int n) {
114     g_assert (id >= 0 && id < BRUSH_SETTINGS_COUNT);
115     settings[id]->set_n (input, n);
116   }
117
118   void set_mapping_point (int id, int input, int index, float x, float y) {
119     g_assert (id >= 0 && id < BRUSH_SETTINGS_COUNT);
120     settings[id]->set_point (input, index, x, y);
121   }
122
123 private:
124   // returns the fraction still left after t seconds
125   float exp_decay (float T_const, float t)
126   {
127     // the argument might not make mathematical sense (whatever.)
128     if (T_const <= 0.001) {
129       return 0.0;
130     } else {
131       return exp(- t / T_const);
132     }
133   }
134
135
136   void settings_base_values_have_changed ()
137   {
138     // precalculate stuff that does not change dynamically
139
140     // Precalculate how the physical speed will be mapped to the speed input value.
141     // The forumla for this mapping is:
142     //
143     // y = log(gamma+x)*m + q;
144     //
145     // x: the physical speed (pixels per basic dab radius)
146     // y: the speed input that will be reported
147     // gamma: parameter set by ths user (small means a logarithmic mapping, big linear)
148     // m, q: parameters to scale and translate the curve
149     //
150     // The code below calculates m and q given gamma and two hardcoded constraints.
151     //
152     for (int i=0; i<2; i++) {
153       float gamma;
154       gamma = settings[(i==0)?BRUSH_SPEED1_GAMMA:BRUSH_SPEED2_GAMMA]->base_value;
155       gamma = exp(gamma);
156
157       float fix1_x, fix1_y, fix2_x, fix2_dy;
158       fix1_x = 45.0;
159       fix1_y = 0.5;
160       fix2_x = 45.0;
161       fix2_dy = 0.015;
162
163       float m, q;
164       float c1;
165       c1 = log(fix1_x+gamma);
166       m = fix2_dy * (fix2_x + gamma);
167       q = fix1_y - m*c1;
168     
169       speed_mapping_gamma[i] = gamma;
170       speed_mapping_m[i] = m;
171       speed_mapping_q[i] = q;
172     }
173   }
174
175   // This function runs a brush "simulation" step. Usually it is
176   // called once or twice per dab. In theory the precision of the
177   // "simulation" gets better when it is called more often. In
178   // practice this only matters if there are some highly nonlinear
179   // mappings in critical places or extremely few events per second.
180   //
181   // note: parameters are is dx/ddab, ..., dtime/ddab (dab is the number, 5.0 = 5th dab)
182   void update_states_and_setting_values (float step_dx, float step_dy, float step_dpressure, float step_declination, float step_ascension, float step_dtime)
183   {
184     float pressure;
185     float inputs[INPUT_COUNT];
186
187     if (step_dtime < 0.0) {
188       printf("Time is running backwards!\n");
189       step_dtime = 0.001;
190     } else if (step_dtime == 0.0) {
191       // FIXME: happens about every 10th start, workaround (against division by zero)
192       step_dtime = 0.001;
193     }
194
195     states[STATE_X]        += step_dx;
196     states[STATE_Y]        += step_dy;
197     states[STATE_PRESSURE] += step_dpressure;
198
199     states[STATE_DECLINATION] += step_declination;
200     states[STATE_ASCENSION] += step_ascension;
201
202     float base_radius = expf(settings[BRUSH_RADIUS_LOGARITHMIC]->base_value);
203
204     // FIXME: does happen (interpolation problem?)
205     states[STATE_PRESSURE] = CLAMP(states[STATE_PRESSURE], 0.0, 1.0);
206     pressure = states[STATE_PRESSURE];
207
208     { // start / end stroke (for "stroke" input only)
209       if (!states[STATE_STROKE_STARTED]) {
210         if (pressure > settings[BRUSH_STROKE_THRESHOLD]->base_value + 0.0001) {
211           // start new stroke
212           //printf("stroke start %f\n", pressure);
213           states[STATE_STROKE_STARTED] = 1;
214           states[STATE_STROKE] = 0.0;
215         }
216       } else {
217         if (pressure <= settings[BRUSH_STROKE_THRESHOLD]->base_value * 0.9 + 0.0001) {
218           // end stroke
219           //printf("stroke end\n");
220           states[STATE_STROKE_STARTED] = 0;
221         }
222       }
223     }
224
225     // now follows input handling
226
227     float norm_dx, norm_dy, norm_dist, norm_speed;
228     norm_dx = step_dx / step_dtime / base_radius;
229     norm_dy = step_dy / step_dtime / base_radius;
230     norm_speed = sqrt(SQR(norm_dx) + SQR(norm_dy));
231     norm_dist = norm_speed * step_dtime;
232
233     inputs[INPUT_PRESSURE] = pressure;
234     inputs[INPUT_SPEED1] = log(speed_mapping_gamma[0] + states[STATE_NORM_SPEED1_SLOW])*speed_mapping_m[0] + speed_mapping_q[0];
235     inputs[INPUT_SPEED2] = log(speed_mapping_gamma[1] + states[STATE_NORM_SPEED2_SLOW])*speed_mapping_m[1] + speed_mapping_q[1];
236     inputs[INPUT_RANDOM] = g_rand_double (rng);
237     inputs[INPUT_STROKE] = MIN(states[STATE_STROKE], 1.0);
238     inputs[INPUT_DIRECTION] = fmodf (atan2f (states[STATE_DIRECTION_DY], states[STATE_DIRECTION_DX])/(2*M_PI)*360 + 180.0, 180.0);
239     inputs[INPUT_TILT_DECLINATION] = states[STATE_DECLINATION];
240     inputs[INPUT_TILT_ASCENSION] = states[STATE_ASCENSION];
241     inputs[INPUT_CUSTOM] = states[STATE_CUSTOM_INPUT];
242     if (print_inputs) {
243       g_print("press=% 4.3f, speed1=% 4.4f\tspeed2=% 4.4f\tstroke=% 4.3f\tcustom=% 4.3f\n", (double)inputs[INPUT_PRESSURE], (double)inputs[INPUT_SPEED1], (double)inputs[INPUT_SPEED2], (double)inputs[INPUT_STROKE], (double)inputs[INPUT_CUSTOM]);
244     }
245     // FIXME: this one fails!!!
246     //assert(inputs[INPUT_SPEED1] >= 0.0 && inputs[INPUT_SPEED1] < 1e8); // checking for inf
247
248     for (int i=0; i<BRUSH_SETTINGS_COUNT; i++) {
249       settings_value[i] = settings[i]->calculate (inputs);
250     }
251
252     {
253       float fac = 1.0 - exp_decay (settings_value[BRUSH_SLOW_TRACKING_PER_DAB], 1.0);
254       states[STATE_ACTUAL_X] += (states[STATE_X] - states[STATE_ACTUAL_X]) * fac; // FIXME: should this depend on base radius?
255       states[STATE_ACTUAL_Y] += (states[STATE_Y] - states[STATE_ACTUAL_Y]) * fac;
256     }
257
258     { // slow speed
259       float fac;
260       fac = 1.0 - exp_decay (settings_value[BRUSH_SPEED1_SLOWNESS], step_dtime);
261       states[STATE_NORM_SPEED1_SLOW] += (norm_speed - states[STATE_NORM_SPEED1_SLOW]) * fac;
262       fac = 1.0 - exp_decay (settings_value[BRUSH_SPEED2_SLOWNESS], step_dtime);
263       states[STATE_NORM_SPEED2_SLOW] += (norm_speed - states[STATE_NORM_SPEED2_SLOW]) * fac;
264     }
265   
266     { // slow speed, but as vector this time
267
268       // FIXME: offset_by_speed should be removed.
269       //   Is it broken, non-smooth, system-dependent math?!
270       //   A replacement could be a directed random offset.
271
272       float time_constant = exp(settings_value[BRUSH_OFFSET_BY_SPEED_SLOWNESS]*0.01)-1.0;
273       // Workaround for a bug that happens mainly on Windows, causing
274       // individual dabs to be placed far far away. Using the speed
275       // with zero filtering is just asking for trouble anyway.
276       if (time_constant < 0.002) time_constant = 0.002;
277       float fac = 1.0 - exp_decay (time_constant, step_dtime);
278       states[STATE_NORM_DX_SLOW] += (norm_dx - states[STATE_NORM_DX_SLOW]) * fac;
279       states[STATE_NORM_DY_SLOW] += (norm_dy - states[STATE_NORM_DY_SLOW]) * fac;
280     }
281
282     { // orientation (similar lowpass filter as above, but use dabtime instead of wallclock time)
283       float dx = step_dx / base_radius;
284       float dy = step_dy / base_radius;
285       float step_in_dabtime = hypotf(dx, dy); // FIXME: are we recalculating something here that we already have?
286       float fac = 1.0 - exp_decay (exp(settings_value[BRUSH_DIRECTION_FILTER]*0.5)-1.0, step_in_dabtime);
287
288       float dx_old = states[STATE_DIRECTION_DX];
289       float dy_old = states[STATE_DIRECTION_DY];
290       // use the opposite speed vector if it is closer (we don't care about 180 degree turns)
291       if (SQR(dx_old-dx) + SQR(dy_old-dy) > SQR(dx_old-(-dx)) + SQR(dy_old-(-dy))) {
292         dx = -dx;
293         dy = -dy;
294       }
295       states[STATE_DIRECTION_DX] += (dx - states[STATE_DIRECTION_DX]) * fac;
296       states[STATE_DIRECTION_DY] += (dy - states[STATE_DIRECTION_DY]) * fac;
297     }
298
299     { // custom input
300       float fac;
301       fac = 1.0 - exp_decay (settings_value[BRUSH_CUSTOM_INPUT_SLOWNESS], 0.1);
302       states[STATE_CUSTOM_INPUT] += (settings_value[BRUSH_CUSTOM_INPUT] - states[STATE_CUSTOM_INPUT]) * fac;
303     }
304
305     { // stroke length
306       float frequency;
307       float wrap;
308       frequency = expf(-settings_value[BRUSH_STROKE_DURATION_LOGARITHMIC]);
309       states[STATE_STROKE] += norm_dist * frequency;
310       // can happen, probably caused by rounding
311       if (states[STATE_STROKE] < 0) states[STATE_STROKE] = 0;
312       wrap = 1.0 + settings_value[BRUSH_STROKE_HOLDTIME];
313       if (states[STATE_STROKE] > wrap) {
314         if (wrap > 9.9 + 1.0) {
315           // "inifinity", just hold stroke somewhere >= 1.0
316           states[STATE_STROKE] = 1.0;
317         } else {
318           states[STATE_STROKE] = fmodf(states[STATE_STROKE], wrap);
319           // just in case
320           if (states[STATE_STROKE] < 0) states[STATE_STROKE] = 0;
321         }
322       }
323     }
324
325     // calculate final radius
326     float radius_log;
327     radius_log = settings_value[BRUSH_RADIUS_LOGARITHMIC];
328     states[STATE_ACTUAL_RADIUS] = expf(radius_log);
329     if (states[STATE_ACTUAL_RADIUS] < ACTUAL_RADIUS_MIN) states[STATE_ACTUAL_RADIUS] = ACTUAL_RADIUS_MIN;
330     if (states[STATE_ACTUAL_RADIUS] > ACTUAL_RADIUS_MAX) states[STATE_ACTUAL_RADIUS] = ACTUAL_RADIUS_MAX;
331
332     // aspect ratio (needs to be caluclated here because it can affect the dab spacing)
333     states[STATE_ACTUAL_ELLIPTICAL_DAB_RATIO] = settings_value[BRUSH_ELLIPTICAL_DAB_RATIO];
334     states[STATE_ACTUAL_ELLIPTICAL_DAB_ANGLE] = settings_value[BRUSH_ELLIPTICAL_DAB_ANGLE];
335   }
336
337   // Called only from stroke_to(). Calculate everything needed to
338   // draw the dab, then let the surface do the actual drawing.
339   //
340   // This is only gets called right after update_states_and_setting_values().
341   // Returns true if the surface was modified.
342   bool prepare_and_draw_dab (Surface * surface)
343   {
344     float x, y, opaque;
345     float radius;
346
347     // ensure we don't get a positive result with two negative opaque values
348     if (settings_value[BRUSH_OPAQUE] < 0) settings_value[BRUSH_OPAQUE] = 0;
349     opaque = settings_value[BRUSH_OPAQUE] * settings_value[BRUSH_OPAQUE_MULTIPLY];
350     opaque = CLAMP(opaque, 0.0, 1.0);
351     //if (opaque == 0.0) return false; <-- cannot do that, since we need to update smudge state.
352     if (settings_value[BRUSH_OPAQUE_LINEARIZE]) {
353       // OPTIMIZE: no need to recalculate this for each dab
354       float alpha, beta, alpha_dab, beta_dab;
355       float dabs_per_pixel;
356       // dabs_per_pixel is just estimated roughly, I didn't think hard
357       // about the case when the radius changes during the stroke
358       dabs_per_pixel = (
359                         settings[BRUSH_DABS_PER_ACTUAL_RADIUS]->base_value + 
360                         settings[BRUSH_DABS_PER_BASIC_RADIUS]->base_value
361                         ) * 2.0;
362
363       // the correction is probably not wanted if the dabs don't overlap
364       if (dabs_per_pixel < 1.0) dabs_per_pixel = 1.0;
365
366       // interpret the user-setting smoothly
367       dabs_per_pixel = 1.0 + settings[BRUSH_OPAQUE_LINEARIZE]->base_value*(dabs_per_pixel-1.0);
368
369       // see doc/brushdab_saturation.png
370       //      beta = beta_dab^dabs_per_pixel
371       // <==> beta_dab = beta^(1/dabs_per_pixel)
372       alpha = opaque;
373       beta = 1.0-alpha;
374       beta_dab = powf(beta, 1.0/dabs_per_pixel);
375       alpha_dab = 1.0-beta_dab;
376       opaque = alpha_dab;
377     }
378
379     x = states[STATE_ACTUAL_X];
380     y = states[STATE_ACTUAL_Y];
381
382     float base_radius = expf(settings[BRUSH_RADIUS_LOGARITHMIC]->base_value);
383
384     if (settings_value[BRUSH_OFFSET_BY_SPEED]) {
385       x += states[STATE_NORM_DX_SLOW] * settings_value[BRUSH_OFFSET_BY_SPEED] * 0.1 * base_radius;
386       y += states[STATE_NORM_DY_SLOW] * settings_value[BRUSH_OFFSET_BY_SPEED] * 0.1 * base_radius;
387     }
388
389     if (settings_value[BRUSH_OFFSET_BY_RANDOM]) {
390       float amp = settings_value[BRUSH_OFFSET_BY_RANDOM];
391       if (amp < 0.0) amp = 0.0;
392       x += rand_gauss (rng) * amp * base_radius;
393       y += rand_gauss (rng) * amp * base_radius;
394     }
395
396   
397     radius = states[STATE_ACTUAL_RADIUS];
398     if (settings_value[BRUSH_RADIUS_BY_RANDOM]) {
399       float radius_log, alpha_correction;
400       // go back to logarithmic radius to add the noise
401       radius_log  = settings_value[BRUSH_RADIUS_LOGARITHMIC];
402       radius_log += rand_gauss (rng) * settings_value[BRUSH_RADIUS_BY_RANDOM];
403       radius = expf(radius_log);
404       radius = CLAMP(radius, ACTUAL_RADIUS_MIN, ACTUAL_RADIUS_MAX);
405       alpha_correction = states[STATE_ACTUAL_RADIUS] / radius;
406       alpha_correction = SQR(alpha_correction);
407       if (alpha_correction <= 1.0) {
408         opaque *= alpha_correction;
409       }
410     }
411
412     // color part
413
414     float color_h = settings[BRUSH_COLOR_H]->base_value;
415     float color_s = settings[BRUSH_COLOR_S]->base_value;
416     float color_v = settings[BRUSH_COLOR_V]->base_value;
417     float eraser_target_alpha = 1.0;
418     if (settings_value[BRUSH_SMUDGE] > 0.0) {
419       // mix (in RGB) the smudge color with the brush color
420       hsv_to_rgb_float (&color_h, &color_s, &color_v);
421       float fac = settings_value[BRUSH_SMUDGE];
422       if (fac > 1.0) fac = 1.0;
423       // If the smudge color somewhat transparent, then the resulting
424       // dab will do erasing towards that transparency level.
425       // see also ../doc/smudge_math.png
426       eraser_target_alpha = (1-fac)*1.0 + fac*states[STATE_SMUDGE_A];
427       // fix rounding errors (they really seem to happen in the previous line)
428       eraser_target_alpha = CLAMP(eraser_target_alpha, 0.0, 1.0);
429       if (eraser_target_alpha > 0) {
430         color_h = (fac*states[STATE_SMUDGE_RA] + (1-fac)*color_h) / eraser_target_alpha;
431         color_s = (fac*states[STATE_SMUDGE_GA] + (1-fac)*color_s) / eraser_target_alpha;
432         color_v = (fac*states[STATE_SMUDGE_BA] + (1-fac)*color_v) / eraser_target_alpha;
433       } else {
434         // we are only erasing; the color does not matter
435         color_h = 1.0;
436         color_s = 0.0;
437         color_v = 0.0;
438       }
439       rgb_to_hsv_float (&color_h, &color_s, &color_v);
440     }
441
442     if (settings_value[BRUSH_SMUDGE_LENGTH] < 1.0 and
443         // optimization, since normal brushes have smudge_length == 0.5 without actually smudging
444         (settings_value[BRUSH_SMUDGE] != 0.0 or not settings[BRUSH_SMUDGE]->is_constant())) {
445
446       float smudge_radius = radius * expf(settings_value[BRUSH_SMUDGE_RADIUS_LOG]);
447       smudge_radius = CLAMP(smudge_radius, ACTUAL_RADIUS_MIN, ACTUAL_RADIUS_MAX);
448
449       float fac = settings_value[BRUSH_SMUDGE_LENGTH];
450       if (fac < 0.0) fac = 0;
451       int px, py;
452       px = ROUND(x);
453       py = ROUND(y);
454       float r, g, b, a;
455
456       surface->get_color (px, py, smudge_radius, &r, &g, &b, &a);
457       // updated the smudge color (stored with premultiplied alpha)
458       states[STATE_SMUDGE_A ] = fac*states[STATE_SMUDGE_A ] + (1-fac)*a;
459       // fix rounding errors
460       states[STATE_SMUDGE_A ] = CLAMP(states[STATE_SMUDGE_A], 0.0, 1.0);
461
462       states[STATE_SMUDGE_RA] = fac*states[STATE_SMUDGE_RA] + (1-fac)*r*a;
463       states[STATE_SMUDGE_GA] = fac*states[STATE_SMUDGE_GA] + (1-fac)*g*a;
464       states[STATE_SMUDGE_BA] = fac*states[STATE_SMUDGE_BA] + (1-fac)*b*a;
465     }
466
467     // eraser
468     if (settings_value[BRUSH_ERASER]) {
469       eraser_target_alpha *= (1.0-settings_value[BRUSH_ERASER]);
470     }
471
472     // HSV color change
473     color_h += settings_value[BRUSH_CHANGE_COLOR_H];
474     color_s += settings_value[BRUSH_CHANGE_COLOR_HSV_S];
475     color_v += settings_value[BRUSH_CHANGE_COLOR_V];
476
477     // HSL color change
478     if (settings_value[BRUSH_CHANGE_COLOR_L] || settings_value[BRUSH_CHANGE_COLOR_HSL_S]) {
479       // (calculating way too much here, can be optimized if neccessary)
480       // this function will CLAMP the inputs
481       hsv_to_rgb_float (&color_h, &color_s, &color_v);
482       rgb_to_hsl_float (&color_h, &color_s, &color_v);
483       color_v += settings_value[BRUSH_CHANGE_COLOR_L];
484       color_s += settings_value[BRUSH_CHANGE_COLOR_HSL_S];
485       hsl_to_rgb_float (&color_h, &color_s, &color_v);
486       rgb_to_hsv_float (&color_h, &color_s, &color_v);
487     }
488
489     float hardness = settings_value[BRUSH_HARDNESS];
490
491     // the functions below will CLAMP most inputs
492     hsv_to_rgb_float (&color_h, &color_s, &color_v);
493     return surface->draw_dab (x, y, radius, color_h, color_s, color_v, opaque, hardness, eraser_target_alpha,
494                               states[STATE_ACTUAL_ELLIPTICAL_DAB_RATIO], states[STATE_ACTUAL_ELLIPTICAL_DAB_ANGLE],
495                               settings_value[BRUSH_LOCK_ALPHA]);
496   }
497
498   // How many dabs will be drawn between the current and the next (x, y, pressure, +dt) position?
499   float count_dabs_to (float x, float y, float pressure, float dt)
500   {
501     float xx, yy;
502     float res1, res2, res3;
503     float dist;
504
505     if (states[STATE_ACTUAL_RADIUS] == 0.0) states[STATE_ACTUAL_RADIUS] = expf(settings[BRUSH_RADIUS_LOGARITHMIC]->base_value);
506     if (states[STATE_ACTUAL_RADIUS] < ACTUAL_RADIUS_MIN) states[STATE_ACTUAL_RADIUS] = ACTUAL_RADIUS_MIN;
507     if (states[STATE_ACTUAL_RADIUS] > ACTUAL_RADIUS_MAX) states[STATE_ACTUAL_RADIUS] = ACTUAL_RADIUS_MAX;
508
509
510     // OPTIMIZE: expf() called too often
511     float base_radius = expf(settings[BRUSH_RADIUS_LOGARITHMIC]->base_value);
512     if (base_radius < ACTUAL_RADIUS_MIN) base_radius = ACTUAL_RADIUS_MIN;
513     if (base_radius > ACTUAL_RADIUS_MAX) base_radius = ACTUAL_RADIUS_MAX;
514     //if (base_radius < 0.5) base_radius = 0.5;
515     //if (base_radius > 500.0) base_radius = 500.0;
516
517     xx = x - states[STATE_X];
518     yy = y - states[STATE_Y];
519     //dp = pressure - pressure; // Not useful?
520     // TODO: control rate with pressure (dabs per pressure) (dpressure is useless)
521
522     if (states[STATE_ACTUAL_ELLIPTICAL_DAB_RATIO] > 1.0) {
523       // code duplication, see tiledsurface::draw_dab()
524       float angle_rad=states[STATE_ACTUAL_ELLIPTICAL_DAB_ANGLE]/360*2*M_PI;
525       float cs=cos(angle_rad);
526       float sn=sin(angle_rad);
527       float yyr=(yy*cs-xx*sn)*states[STATE_ACTUAL_ELLIPTICAL_DAB_RATIO];
528       float xxr=yy*sn+xx*cs;
529       dist = sqrt(yyr*yyr + xxr*xxr);
530     } else {
531       dist = hypotf(xx, yy);
532     }
533
534     // FIXME: no need for base_value or for the range checks above IF always the interpolation
535     //        function will be called before this one
536     res1 = dist / states[STATE_ACTUAL_RADIUS] * settings[BRUSH_DABS_PER_ACTUAL_RADIUS]->base_value;
537     res2 = dist / base_radius   * settings[BRUSH_DABS_PER_BASIC_RADIUS]->base_value;
538     res3 = dt * settings[BRUSH_DABS_PER_SECOND]->base_value;
539     return res1 + res2 + res3;
540   }
541
542 public:
543   // This function:
544   // - is called once for each motion event
545   // - does motion event interpolation
546   // - paints zero, one or several dabs
547   // - decides whether the stroke is finished (for undo/redo)
548   // returns true if the stroke is finished or empty
549   bool stroke_to (Surface * surface, float x, float y, float pressure, float xtilt, float ytilt, double dtime)
550   {
551     //printf("%f %f %f %f\n", (double)dtime, (double)x, (double)y, (double)pressure);
552
553     float tilt_ascension = 0.0;
554     float tilt_declination = 90.0;
555     if (xtilt != 0 || ytilt != 0) {
556       // shield us from insane tilt input
557       xtilt = CLAMP(xtilt, -1.0, 1.0);
558       ytilt = CLAMP(ytilt, -1.0, 1.0);
559       assert(isfinite(xtilt) && isfinite(ytilt));
560
561       tilt_ascension = 180.0*atan2(-xtilt, ytilt)/M_PI;
562       float e;
563       if (abs(xtilt) > abs(ytilt)) {
564         e = sqrt(1+ytilt*ytilt);
565       } else {
566         e = sqrt(1+xtilt*xtilt);
567       }
568       float rad = hypot(xtilt, ytilt);
569       float cos_alpha = rad/e;
570       if (cos_alpha >= 1.0) cos_alpha = 1.0; // fix numerical inaccuracy
571       tilt_declination = 180.0*acos(cos_alpha)/M_PI;
572
573       assert(isfinite(tilt_ascension));
574       assert(isfinite(tilt_declination));
575     }
576
577     // printf("xtilt %f, ytilt %f\n", (double)xtilt, (double)ytilt);
578     // printf("ascension %f, declination %f\n", (double)tilt_ascension, (double)tilt_declination);
579       
580     pressure = CLAMP(pressure, 0.0, 1.0);
581     if (!isfinite(x) || !isfinite(y) ||
582         (x > 1e10 || y > 1e10 || x < -1e10 || y < -1e10)) {
583       // workaround attempt for https://gna.org/bugs/?14372
584       g_print("Warning: ignoring brush::stroke_to with insane inputs (x = %f, y = %f)\n", (double)x, (double)y);
585       x = 0.0;
586       y = 0.0;
587       pressure = 0.0;
588     }
589     // the assertion below is better than out-of-memory later at save time
590     assert(x < 1e8 && y < 1e8 && x > -1e8 && y > -1e8);
591
592     if (dtime < 0) g_print("Time jumped backwards by dtime=%f seconds!\n", dtime);
593     if (dtime <= 0) dtime = 0.0001; // protect against possible division by zero bugs
594     
595     if (dtime > 0.100 && pressure && states[STATE_PRESSURE] == 0) {
596       // Workaround for tablets that don't report motion events without pressure.
597       // This is to avoid linear interpolation of the pressure between two events.
598       stroke_to (surface, x, y, 0.0, 90.0, 0.0, dtime-0.0001);
599       dtime = 0.0001;
600     }
601
602     g_rand_set_seed (rng, states[STATE_RNG_SEED]);
603
604     { // calculate the actual "virtual" cursor position
605
606       // noise first
607       if (settings[BRUSH_TRACKING_NOISE]->base_value) {
608         // OPTIMIZE: expf() called too often
609         float base_radius = expf(settings[BRUSH_RADIUS_LOGARITHMIC]->base_value);
610
611         x += rand_gauss (rng) * settings[BRUSH_TRACKING_NOISE]->base_value * base_radius;
612         y += rand_gauss (rng) * settings[BRUSH_TRACKING_NOISE]->base_value * base_radius;
613       }
614
615       float fac = 1.0 - exp_decay (settings[BRUSH_SLOW_TRACKING]->base_value, 100.0*dtime);
616       x = states[STATE_X] + (x - states[STATE_X]) * fac;
617       y = states[STATE_Y] + (y - states[STATE_Y]) * fac;
618     }
619
620     // draw many (or zero) dabs to the next position
621
622     // see doc/stroke2dabs.png
623     float dist_moved = states[STATE_DIST];
624     float dist_todo = count_dabs_to (x, y, pressure, dtime);
625
626     //if (dtime > 5 || dist_todo > 300) {
627     if (dtime > 5 || reset_requested) {
628       reset_requested = false;
629
630       /*
631         TODO:
632         if (dist_todo > 300) {
633         // this happens quite often, eg when moving the cursor back into the window
634         // FIXME: bad to hardcode a distance treshold here - might look at zoomed image
635         //        better detect leaving/entering the window and reset then.
636         g_print ("Warning: NOT drawing %f dabs.\n", dist_todo);
637         g_print ("dtime=%f, dx=%f\n", dtime, x-states[STATE_X]);
638         //must_reset = 1;
639         }
640       */
641
642       //printf("Brush reset.\n");
643       for (int i=0; i<STATE_COUNT; i++) {
644         states[i] = 0;
645       }
646
647       states[STATE_X] = x;
648       states[STATE_Y] = y;
649       states[STATE_PRESSURE] = pressure;
650
651       // not resetting, because they will get overwritten below:
652       //dx, dy, dpress, dtime
653
654       states[STATE_ACTUAL_X] = states[STATE_X];
655       states[STATE_ACTUAL_Y] = states[STATE_Y];
656       states[STATE_STROKE] = 1.0; // start in a state as if the stroke was long finished
657
658       return true;
659     }
660
661     //g_print("dist = %f\n", states[STATE_DIST]);
662     enum { UNKNOWN, YES, NO } painted = UNKNOWN;
663     double dtime_left = dtime;
664
665     float step_dx, step_dy, step_dpressure, step_dtime;
666     float step_declination, step_ascension;
667     while (dist_moved + dist_todo >= 1.0) { // there are dabs pending
668       { // linear interpolation (nonlinear variant was too slow, see SVN log)
669         float frac; // fraction of the remaining distance to move
670         if (dist_moved > 0) {
671           // "move" the brush exactly to the first dab (moving less than one dab)
672           frac = (1.0 - dist_moved) / dist_todo;
673           dist_moved = 0;
674         } else {
675           // "move" the brush from one dab to the next
676           frac = 1.0 / dist_todo;
677         }
678         step_dx        = frac * (x - states[STATE_X]);
679         step_dy        = frac * (y - states[STATE_Y]);
680         step_dpressure = frac * (pressure - states[STATE_PRESSURE]);
681         step_dtime     = frac * (dtime_left - 0.0);
682         step_declination = frac * (tilt_declination - states[STATE_DECLINATION]);
683         step_ascension   = frac * (tilt_ascension - states[STATE_ASCENSION]);
684         // Though it looks different, time is interpolated exactly like x/y/pressure.
685       }
686     
687       update_states_and_setting_values (step_dx, step_dy, step_dpressure, step_declination, step_ascension, step_dtime);
688       bool painted_now = prepare_and_draw_dab (surface);
689       if (painted_now) {
690         painted = YES;
691       } else if (painted == UNKNOWN) {
692         painted = NO;
693       }
694
695       dtime_left   -= step_dtime;
696       dist_todo  = count_dabs_to (x, y, pressure, dtime_left);
697     }
698
699     {
700       // "move" the brush to the current time (no more dab will happen)
701       // Important to do this at least once every event, because
702       // brush_count_dabs_to depends on the radius and the radius can
703       // depend on something that changes much faster than only every
704       // dab (eg speed).
705     
706       step_dx        = x - states[STATE_X];
707       step_dy        = y - states[STATE_Y];
708       step_dpressure = pressure - states[STATE_PRESSURE];
709       step_declination = tilt_declination - states[STATE_DECLINATION];
710       step_ascension = tilt_ascension - states[STATE_ASCENSION];
711       step_dtime     = dtime_left;
712     
713       //dtime_left = 0; but that value is not used any more
714
715       update_states_and_setting_values (step_dx, step_dy, step_dpressure, step_declination, step_ascension, step_dtime);
716     }
717
718     // save the fraction of a dab that is already done now
719     states[STATE_DIST] = dist_moved + dist_todo;
720     //g_print("dist_final = %f\n", states[STATE_DIST]);
721
722     // next seed for the RNG (GRand has no get_state() and states[] must always contain our full state)
723     states[STATE_RNG_SEED] = g_rand_int(rng);
724
725     // stroke separation logic (for undo/redo)
726
727     if (painted == UNKNOWN) {
728       if (stroke_current_idling_time > 0 || stroke_total_painting_time == 0) {
729         // still idling
730         painted = NO;
731       } else {
732         // probably still painting (we get more events than brushdabs)
733         painted = YES;
734         //if (pressure == 0) g_print ("info: assuming 'still painting' while there is no pressure\n");
735       }
736     }
737     if (painted == YES) {
738       //if (stroke_current_idling_time > 0) g_print ("idling ==> painting\n");
739       stroke_total_painting_time += dtime;
740       stroke_current_idling_time = 0;
741       // force a stroke split after some time
742       if (stroke_total_painting_time > 4 + 3*pressure) {
743         // but only if pressure is not being released
744         // FIXME: use some smoothed state for dpressure, not the output of the interpolation code
745         //        (which might easily wrongly give dpressure == 0)
746         if (step_dpressure >= 0) {
747           return true;
748         }
749       }
750     } else if (painted == NO) {
751       //if (stroke_current_idling_time == 0) g_print ("painting ==> idling\n");
752       stroke_current_idling_time += dtime;
753       if (stroke_total_painting_time == 0) {
754         // not yet painted, start a new stroke if we have accumulated a lot of irrelevant motion events
755         if (stroke_current_idling_time > 1.0) {
756           return true;
757         }
758       } else {
759         // Usually we have pressure==0 here. But some brushes can paint
760         // nothing at full pressure (eg gappy lines, or a stroke that
761         // fades out). In either case this is the prefered moment to split.
762         if (stroke_total_painting_time+stroke_current_idling_time > 1.2 + 5*pressure) {
763           return true;
764         }
765       }
766     }
767     return false;
768   }
769
770   PyObject * get_state ()
771   {
772     npy_intp dims = {STATE_COUNT};
773     PyObject * data = PyArray_SimpleNew(1, &dims, NPY_FLOAT32);
774     npy_float32 * data_p = (npy_float32*)PyArray_DATA(data);
775     for (int i=0; i<STATE_COUNT; i++) {
776       data_p[i] = states[i];
777     }
778     return data;
779   }
780
781   void set_state (PyObject * data)
782   {
783     assert(PyArray_NDIM(data) == 1);
784     assert(PyArray_DIM(data, 0) == STATE_COUNT);
785     assert(PyArray_ISCARRAY(data));
786     npy_float32 * data_p = (npy_float32*)PyArray_DATA(data);
787     for (int i=0; i<STATE_COUNT; i++) {
788       states[i] = data_p[i];
789     }
790   }
791
792 };