Painting: fix uninitialized variable use
[blender.git] / source / blender / editors / sculpt_paint / paint_stroke.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2009 by Nicholas Bishop
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Jason Wilkins, Tom Musgrove.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  *
27  */
28
29 /** \file blender/editors/sculpt_paint/paint_stroke.c
30  *  \ingroup edsculpt
31  */
32
33
34 #include "MEM_guardedalloc.h"
35
36 #include "BLI_math.h"
37 #include "BLI_utildefines.h"
38 #include "BLI_rand.h"
39 #include "BLI_listbase.h"
40
41 #include "DNA_object_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_brush_types.h"
44 #include "DNA_curve_types.h"
45
46 #include "RNA_access.h"
47
48 #include "BKE_context.h"
49 #include "BKE_paint.h"
50 #include "BKE_brush.h"
51 #include "BKE_curve.h"
52 #include "BKE_colortools.h"
53 #include "BKE_image.h"
54
55 #include "WM_api.h"
56 #include "WM_types.h"
57
58 #include "BIF_gl.h"
59 #include "BIF_glutil.h"
60
61 #include "GPU_basic_shader.h"
62
63 #include "ED_screen.h"
64 #include "ED_view3d.h"
65
66 #include "IMB_imbuf_types.h"
67
68 #include "paint_intern.h"
69
70 #include <float.h>
71 #include <math.h>
72
73 //#define DEBUG_TIME
74
75 #ifdef DEBUG_TIME
76 #  include "PIL_time_utildefines.h"
77 #endif
78
79 typedef struct PaintSample {
80         float mouse[2];
81         float pressure;
82 } PaintSample;
83
84 typedef struct PaintStroke {
85         void *mode_data;
86         void *stroke_cursor;
87         wmTimer *timer;
88
89         /* Cached values */
90         ViewContext vc;
91         Brush *brush;
92         UnifiedPaintSettings *ups;
93
94         /* used for lines and curves */
95         ListBase line;
96
97         /* Paint stroke can use up to PAINT_MAX_INPUT_SAMPLES prior inputs
98          * to smooth the stroke */
99         PaintSample samples[PAINT_MAX_INPUT_SAMPLES];
100         int num_samples;
101         int cur_sample;
102
103         float last_mouse_position[2];
104         /* space distance covered so far */
105         float stroke_distance;
106
107         /* Set whether any stroke step has yet occurred
108          * e.g. in sculpt mode, stroke doesn't start until cursor
109          * passes over the mesh */
110         bool stroke_started;
111         /* Set when enough motion was found for rake rotation */
112         bool rake_started;
113         /* event that started stroke, for modal() return */
114         int event_type;
115         /* check if stroke variables have been initialized */
116         bool stroke_init;
117         /* check if various brush mapping variables have been initialized */
118         bool brush_init;
119         float initial_mouse[2];
120         /* cached_pressure stores initial pressure for size pressure influence mainly */
121         float cached_size_pressure;
122         /* last pressure will store last pressure value for use in interpolation for space strokes */
123         float last_pressure;
124         int stroke_mode;
125
126         float zoom_2d;
127         int pen_flip;
128
129         /* line constraint */
130         bool constrain_line;
131         float constrained_pos[2];
132
133         StrokeGetLocation get_location;
134         StrokeTestStart test_start;
135         StrokeUpdateStep update_step;
136         StrokeRedraw redraw;
137         StrokeDone done;
138 } PaintStroke;
139
140 /*** Cursors ***/
141 static void paint_draw_smooth_cursor(bContext *C, int x, int y, void *customdata)
142 {
143         Paint *paint = BKE_paint_get_active_from_context(C);
144         Brush *brush = BKE_paint_brush(paint);
145         PaintStroke *stroke = customdata;
146
147         if (stroke && brush) {
148                 glEnable(GL_LINE_SMOOTH);
149                 glEnable(GL_BLEND);
150                 glColor4ubv(paint->paint_cursor_col);
151                 sdrawline(x, y, (int)stroke->last_mouse_position[0],
152                           (int)stroke->last_mouse_position[1]);
153                 glDisable(GL_BLEND);
154                 glDisable(GL_LINE_SMOOTH);
155         }
156 }
157
158 static void paint_draw_line_cursor(bContext *C, int x, int y, void *customdata)
159 {
160         Paint *paint = BKE_paint_get_active_from_context(C);
161         PaintStroke *stroke = customdata;
162
163         glEnable(GL_LINE_SMOOTH);
164         glEnable(GL_BLEND);
165
166         GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
167         GPU_basic_shader_line_stipple(3, 0xAAAA);
168         GPU_basic_shader_line_width(3.0);
169
170         glColor4ub(0, 0, 0, paint->paint_cursor_col[3]);
171         if (stroke->constrain_line) {
172                 sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
173                         stroke->constrained_pos[0], stroke->constrained_pos[1]);
174         }
175         else {
176                 sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
177                         x, y);
178         }
179
180         glColor4ub(255, 255, 255, paint->paint_cursor_col[3]);
181         GPU_basic_shader_line_width(1.0);
182         if (stroke->constrain_line) {
183                 sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
184                         stroke->constrained_pos[0], stroke->constrained_pos[1]);
185         }
186         else {
187                 sdrawline((int)stroke->last_mouse_position[0], (int)stroke->last_mouse_position[1],
188                         x, y);
189         }
190
191         GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE);
192
193         glDisable(GL_BLEND);
194         glDisable(GL_LINE_SMOOTH);
195 }
196
197 static bool paint_tool_require_location(Brush *brush, ePaintMode mode)
198 {
199         switch (mode) {
200                 case ePaintSculpt:
201                         if (ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE,
202                                                      SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB))
203                         {
204                                 return false;
205                         }
206                         else {
207                                 return true;
208                         }
209                 default:
210                         break;
211         }
212
213         return true;
214 }
215
216 /* Initialize the stroke cache variants from operator properties */
217 static bool paint_brush_update(
218         bContext *C,
219         Brush *brush,
220         ePaintMode mode,
221         struct PaintStroke *stroke,
222         const float mouse_init[2],
223         float mouse[2], float pressure,
224         float r_location[3], bool *r_location_is_set)
225 {
226         Scene *scene = CTX_data_scene(C);
227         UnifiedPaintSettings *ups = stroke->ups;
228         bool location_sampled = false;
229         bool location_success = false;
230         /* Use to perform all operations except applying the stroke,
231          * needed for operations that require cursor motion (rake). */
232         bool is_dry_run = false;
233         bool do_random = false;
234         bool do_random_mask = false;
235         *r_location_is_set = false;
236         /* XXX: Use pressure value from first brush step for brushes which don't
237          *      support strokes (grab, thumb). They depends on initial state and
238          *      brush coord/pressure/etc.
239          *      It's more an events design issue, which doesn't split coordinate/pressure/angle
240          *      changing events. We should avoid this after events system re-design */
241         if (!stroke->brush_init) {
242                 copy_v2_v2(stroke->initial_mouse, mouse);
243                 copy_v2_v2(ups->last_rake, mouse);
244                 copy_v2_v2(ups->tex_mouse, mouse);
245                 copy_v2_v2(ups->mask_tex_mouse, mouse);
246                 stroke->cached_size_pressure = pressure;
247
248                 ups->do_linear_conversion = false;
249                 ups->colorspace = NULL;
250
251                 /* check here if color sampling the main brush should do color conversion. This is done here
252                  * to avoid locking up to get the image buffer during sampling */
253                 if (brush->mtex.tex && brush->mtex.tex->type == TEX_IMAGE && brush->mtex.tex->ima) {
254                         ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(brush->mtex.tex->ima, &brush->mtex.tex->iuser, NULL);
255                         if (tex_ibuf && tex_ibuf->rect_float == NULL) {
256                                 ups->do_linear_conversion = true;
257                                 ups->colorspace = tex_ibuf->rect_colorspace;
258                         }
259                         BKE_image_pool_release_ibuf(brush->mtex.tex->ima, tex_ibuf, NULL);
260                 }
261
262                 stroke->brush_init = true;
263         }
264
265         if (paint_supports_dynamic_size(brush, mode)) {
266                 copy_v2_v2(ups->tex_mouse, mouse);
267                 copy_v2_v2(ups->mask_tex_mouse, mouse);
268                 stroke->cached_size_pressure = pressure;
269         }
270
271         /* Truly temporary data that isn't stored in properties */
272
273         ups->stroke_active = true;
274         ups->size_pressure_value = stroke->cached_size_pressure;
275
276         ups->pixel_radius = BKE_brush_size_get(scene, brush);
277
278         if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush, mode)) {
279                 ups->pixel_radius *= stroke->cached_size_pressure;
280         }
281
282         if (paint_supports_dynamic_tex_coords(brush, mode)) {
283
284                 if (ELEM(brush->mtex.brush_map_mode,
285                          MTEX_MAP_MODE_VIEW,
286                          MTEX_MAP_MODE_AREA,
287                          MTEX_MAP_MODE_RANDOM))
288                 {
289                         do_random = true;
290                 }
291
292                 if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)
293                         BKE_brush_randomize_texture_coords(ups, false);
294                 else {
295                         copy_v2_v2(ups->tex_mouse, mouse);
296                 }
297
298                 /* take care of mask texture, if any */
299                 if (brush->mask_mtex.tex) {
300
301                         if (ELEM(brush->mask_mtex.brush_map_mode,
302                                  MTEX_MAP_MODE_VIEW,
303                                  MTEX_MAP_MODE_AREA,
304                                  MTEX_MAP_MODE_RANDOM))
305                         {
306                                 do_random_mask = true;
307                         }
308
309                         if (brush->mask_mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)
310                                 BKE_brush_randomize_texture_coords(ups, true);
311                         else {
312                                 copy_v2_v2(ups->mask_tex_mouse, mouse);
313                         }
314                 }
315         }
316
317
318         if (brush->flag & BRUSH_ANCHORED) {
319                 bool hit = false;
320                 float halfway[2];
321
322                 const float dx = mouse[0] - stroke->initial_mouse[0];
323                 const float dy = mouse[1] - stroke->initial_mouse[1];
324
325                 ups->anchored_size = ups->pixel_radius = sqrtf(dx * dx + dy * dy);
326
327                 ups->brush_rotation = ups->brush_rotation_sec = atan2f(dx, dy) + (float)M_PI;
328
329                 if (brush->flag & BRUSH_EDGE_TO_EDGE) {
330                         halfway[0] = dx * 0.5f + stroke->initial_mouse[0];
331                         halfway[1] = dy * 0.5f + stroke->initial_mouse[1];
332
333                         if (stroke->get_location) {
334                                 if (stroke->get_location(C, r_location, halfway)) {
335                                         hit = true;
336                                         location_sampled = true;
337                                         location_success = true;
338                                         *r_location_is_set = true;
339                                 }
340                                 else if (!paint_tool_require_location(brush, mode)) {
341                                         hit = true;
342                                 }
343                         }
344                         else {
345                                 hit = true;
346                         }
347                 }
348                 if (hit) {
349                         copy_v2_v2(ups->anchored_initial_mouse, halfway);
350                         copy_v2_v2(ups->tex_mouse, halfway);
351                         copy_v2_v2(ups->mask_tex_mouse, halfway);
352                         copy_v2_v2(mouse, halfway);
353                         ups->anchored_size /= 2.0f;
354                         ups->pixel_radius  /= 2.0f;
355                         stroke->stroke_distance = ups->pixel_radius;
356                 }
357                 else {
358                         copy_v2_v2(ups->anchored_initial_mouse, stroke->initial_mouse);
359                         copy_v2_v2(mouse, stroke->initial_mouse);
360                         stroke->stroke_distance = ups->pixel_radius;
361                 }
362                 ups->pixel_radius /= stroke->zoom_2d;
363                 ups->draw_anchored = true;
364         }
365         else {
366                 /* here we are using the initial mouse coordinate because we do not want the rake
367                  * result to depend on jittering */
368                 if (!stroke->brush_init) {
369                         copy_v2_v2(ups->last_rake, mouse_init);
370                 }
371                 /* curve strokes do their own rake calculation */
372                 else if (!(brush->flag & BRUSH_CURVE)) {
373                         if (!paint_calculate_rake_rotation(ups, brush, mouse_init)) {
374                                 /* Not enough motion to define an angle. */
375                                 if (!stroke->rake_started) {
376                                         is_dry_run = true;
377                                 }
378                         }
379                         else {
380                                 stroke->rake_started = true;
381                         }
382                 }
383         }
384
385         if (do_random) {
386                 if (brush->mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) {
387                         ups->brush_rotation += -brush->mtex.random_angle / 2.0f +
388                                                brush->mtex.random_angle * BLI_frand();
389                 }
390         }
391
392         if (do_random_mask) {
393                 if (brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RANDOM) {
394                         ups->brush_rotation_sec += -brush->mask_mtex.random_angle / 2.0f +
395                                                    brush->mask_mtex.random_angle * BLI_frand();
396                 }
397         }
398
399         if (!location_sampled) {
400                 if (stroke->get_location) {
401                         if (stroke->get_location(C, r_location, mouse)) {
402                                 location_success = true;
403                                 *r_location_is_set = true;
404                         }
405                         else if (!paint_tool_require_location(brush, mode))
406                                 location_success = true;
407                 }
408                 else {
409                         zero_v3(r_location);
410                         location_success = true;
411                         /* don't set 'r_location_is_set', since we don't want to use the value. */
412                 }
413         }
414
415         return location_success && (is_dry_run == false);
416 }
417
418 static bool paint_stroke_use_jitter(ePaintMode mode, Brush *brush, bool invert)
419 {
420         bool use_jitter = (brush->flag & BRUSH_ABSOLUTE_JITTER) ?
421                 (brush->jitter_absolute != 0) : (brush->jitter != 0);
422
423         /* jitter-ed brush gives weird and unpredictable result for this
424          * kinds of stroke, so manually disable jitter usage (sergey) */
425         use_jitter &= (brush->flag & (BRUSH_DRAG_DOT | BRUSH_ANCHORED)) == 0;
426         use_jitter &= (!ELEM(mode, ePaintTexture2D, ePaintTextureProjective) ||
427                        !(invert && brush->imagepaint_tool == PAINT_TOOL_CLONE));
428
429
430         return use_jitter;
431 }
432
433 /* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */
434 static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, const float mouse_in[2], float pressure)
435 {
436         Scene *scene = CTX_data_scene(C);
437         Paint *paint = BKE_paint_get_active_from_context(C);
438         ePaintMode mode = BKE_paintmode_get_active_from_context(C);
439         Brush *brush = BKE_paint_brush(paint);
440         PaintStroke *stroke = op->customdata;
441         UnifiedPaintSettings *ups = stroke->ups;
442         float mouse_out[2];
443         PointerRNA itemptr;
444         float location[3];
445
446 /* the following code is adapted from texture paint. It may not be needed but leaving here
447  * just in case for reference (code in texpaint removed as part of refactoring).
448  * It's strange that only texpaint had these guards. */
449 #if 0
450         /* special exception here for too high pressure values on first touch in
451          * windows for some tablets, then we just skip first touch ..  */
452         if (tablet && (pressure >= 0.99f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || BKE_brush_use_alpha_pressure(scene, pop->s.brush) || BKE_brush_use_size_pressure(scene, pop->s.brush)))
453                 return;
454
455         /* This can be removed once fixed properly in
456          * BKE_brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, double time, float pressure, void *user)
457          * at zero pressure we should do nothing 1/2^12 is 0.0002 which is the sensitivity of the most sensitive pen tablet available */
458         if (tablet && (pressure < 0.0002f) && ((pop->s.brush->flag & BRUSH_SPACING_PRESSURE) || BKE_brush_use_alpha_pressure(scene, pop->s.brush) || BKE_brush_use_size_pressure(scene, pop->s.brush)))
459                 return;
460 #endif
461
462         /* copy last position -before- jittering, or space fill code
463          * will create too many dabs */
464         copy_v2_v2(stroke->last_mouse_position, mouse_in);
465         stroke->last_pressure = pressure;
466
467         if (paint_stroke_use_jitter(mode, brush, stroke->stroke_mode == BRUSH_STROKE_INVERT)) {
468                 float delta[2];
469                 float factor = stroke->zoom_2d;
470
471                 if (brush->flag & BRUSH_JITTER_PRESSURE)
472                         factor *= pressure;
473
474                 BKE_brush_jitter_pos(scene, brush, mouse_in, mouse_out);
475
476                 /* XXX: meh, this is round about because
477                  * BKE_brush_jitter_pos isn't written in the best way to
478                  * be reused here */
479                 if (factor != 1.0f) {
480                         sub_v2_v2v2(delta, mouse_out, mouse_in);
481                         mul_v2_fl(delta, factor);
482                         add_v2_v2v2(mouse_out, mouse_in, delta);
483                 }
484         }
485         else {
486                 copy_v2_v2(mouse_out, mouse_in);
487         }
488
489
490         bool is_location_is_set;
491         ups->last_hit = paint_brush_update(
492                 C, brush, mode, stroke, mouse_in, mouse_out, pressure,
493                 location, &is_location_is_set);
494         if (is_location_is_set) {
495                 copy_v3_v3(ups->last_location, location);
496         }
497         if (!ups->last_hit) {
498                 return;
499         }
500
501         /* Add to stroke */
502         RNA_collection_add(op->ptr, "stroke", &itemptr);
503         RNA_float_set(&itemptr, "size", ups->pixel_radius);
504         RNA_float_set_array(&itemptr, "location", location);
505         RNA_float_set_array(&itemptr, "mouse", mouse_out);
506         RNA_boolean_set(&itemptr, "pen_flip", stroke->pen_flip);
507         RNA_float_set(&itemptr, "pressure", pressure);
508
509         stroke->update_step(C, stroke, &itemptr);
510
511         /* don't record this for now, it takes up a lot of memory when doing long
512          * strokes with small brush size, and operators have register disabled */
513         RNA_collection_clear(op->ptr, "stroke");
514 }
515
516 /* Returns zero if no sculpt changes should be made, non-zero otherwise */
517 static bool paint_smooth_stroke(
518         PaintStroke *stroke, const PaintSample *sample, ePaintMode mode,
519         float r_mouse[2], float *r_pressure)
520 {
521         if (paint_supports_smooth_stroke(stroke->brush, mode)) {
522                 float radius = stroke->brush->smooth_stroke_radius * stroke->zoom_2d;
523                 float u = stroke->brush->smooth_stroke_factor;
524
525                 /* If the mouse is moving within the radius of the last move,
526                  * don't update the mouse position. This allows sharp turns. */
527                 if (len_squared_v2v2(stroke->last_mouse_position, sample->mouse) < SQUARE(radius)) {
528                         return false;
529                 }
530
531                 interp_v2_v2v2(r_mouse, sample->mouse, stroke->last_mouse_position, u);
532                 *r_pressure = interpf(sample->pressure, stroke->last_pressure, u);
533         }
534         else {
535                 r_mouse[0] = sample->mouse[0];
536                 r_mouse[1] = sample->mouse[1];
537                 *r_pressure = sample->pressure;
538         }
539
540         return true;
541 }
542
543 static float paint_space_stroke_spacing(const Scene *scene, PaintStroke *stroke, float size_pressure, float spacing_pressure)
544 {
545         /* brushes can have a minimum size of 1.0 but with pressure it can be smaller then a pixel
546          * causing very high step sizes, hanging blender [#32381] */
547         const float size_clamp = max_ff(1.0f, BKE_brush_size_get(scene, stroke->brush) * size_pressure);
548         float spacing = stroke->brush->spacing;
549
550         /* apply spacing pressure */
551         if (stroke->brush->flag & BRUSH_SPACING_PRESSURE)
552                 spacing = spacing * (1.5f - spacing_pressure);
553
554         /* stroke system is used for 2d paint too, so we need to account for
555          * the fact that brush can be scaled there. */
556         spacing *= stroke->zoom_2d;
557
558         return max_ff(1.0, size_clamp * spacing / 50.0f);
559 }
560
561
562
563 static float paint_stroke_overlapped_curve(Brush *br, float x, float spacing)
564 {
565         int i;
566         const int n = 100 / spacing;
567         const float h = spacing / 50.0f;
568         const float x0 = x - 1;
569
570         float sum;
571
572         sum = 0;
573         for (i = 0; i < n; i++) {
574                 float xx;
575
576                 xx = fabsf(x0 + i * h);
577
578                 if (xx < 1.0f)
579                         sum += BKE_brush_curve_strength(br, xx, 1);
580         }
581
582         return sum;
583 }
584
585 static float paint_stroke_integrate_overlap(Brush *br, float factor)
586 {
587         int i;
588         int m;
589         float g;
590         float max;
591
592         float spacing = br->spacing * factor;
593
594         if (!(br->flag & BRUSH_SPACE_ATTEN && (br->spacing < 100)))
595                 return 1.0;
596
597         m = 10;
598         g = 1.0f / m;
599         max = 0;
600         for (i = 0; i < m; i++) {
601                 float overlap = fabs(paint_stroke_overlapped_curve(br, i * g, spacing));
602
603                 if (overlap > max)
604                         max = overlap;
605         }
606
607         if (max == 0.0f)
608                 return 1.0f;
609         else
610                 return 1.0f / max;
611 }
612
613 static float paint_space_stroke_spacing_variable(const Scene *scene, PaintStroke *stroke, float pressure, float dpressure, float length)
614 {
615         if (BKE_brush_use_size_pressure(scene, stroke->brush)) {
616                 /* use pressure to modify size. set spacing so that at 100%, the circles
617                  * are aligned nicely with no overlap. for this the spacing needs to be
618                  * the average of the previous and next size. */
619                 float s = paint_space_stroke_spacing(scene, stroke, 1.0f, pressure);
620                 float q = s * dpressure / (2.0f * length);
621                 float pressure_fac = (1.0f + q) / (1.0f - q);
622
623                 float last_size_pressure = stroke->last_pressure;
624                 float new_size_pressure = stroke->last_pressure * pressure_fac;
625
626                 /* average spacing */
627                 float last_spacing = paint_space_stroke_spacing(scene, stroke, last_size_pressure, pressure);
628                 float new_spacing = paint_space_stroke_spacing(scene, stroke, new_size_pressure, pressure);
629
630                 return 0.5f * (last_spacing + new_spacing);
631         }
632         else {
633                 /* no size pressure */
634                 return paint_space_stroke_spacing(scene, stroke, 1.0f, pressure);
635         }
636 }
637
638 /* For brushes with stroke spacing enabled, moves mouse in steps
639  * towards the final mouse location. */
640 static int paint_space_stroke(bContext *C, wmOperator *op, const float final_mouse[2], float final_pressure)
641 {
642         const Scene *scene = CTX_data_scene(C);
643         PaintStroke *stroke = op->customdata;
644         UnifiedPaintSettings *ups = stroke->ups;
645         int cnt = 0;
646
647         float pressure, dpressure;
648         float mouse[2], dmouse[2];
649         float length;
650         float no_pressure_spacing = paint_space_stroke_spacing(scene, stroke, 1.0f, 1.0f);
651
652         sub_v2_v2v2(dmouse, final_mouse, stroke->last_mouse_position);
653
654         pressure = stroke->last_pressure;
655         dpressure = final_pressure - stroke->last_pressure;
656
657         length = normalize_v2(dmouse);
658
659         while (length > 0.0f) {
660                 float spacing = paint_space_stroke_spacing_variable(scene, stroke, pressure, dpressure, length);
661
662                 if (length >= spacing) {
663                         mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing;
664                         mouse[1] = stroke->last_mouse_position[1] + dmouse[1] * spacing;
665                         pressure = stroke->last_pressure + (spacing / length) * dpressure;
666
667                         ups->overlap_factor = paint_stroke_integrate_overlap(stroke->brush, spacing / no_pressure_spacing);
668
669                         stroke->stroke_distance += spacing / stroke->zoom_2d;
670                         paint_brush_stroke_add_step(C, op, mouse, pressure);
671
672                         length -= spacing;
673                         pressure = stroke->last_pressure;
674                         dpressure = final_pressure - stroke->last_pressure;
675
676                         cnt++;
677                 }
678                 else {
679                         break;
680                 }
681         }
682
683         return cnt;
684 }
685
686 /**** Public API ****/
687
688 PaintStroke *paint_stroke_new(bContext *C,
689                               wmOperator *op,
690                               StrokeGetLocation get_location,
691                               StrokeTestStart test_start,
692                               StrokeUpdateStep update_step,
693                               StrokeRedraw redraw,
694                               StrokeDone done, int event_type)
695 {
696         PaintStroke *stroke = MEM_callocN(sizeof(PaintStroke), "PaintStroke");
697         ToolSettings *toolsettings = CTX_data_tool_settings(C);
698         UnifiedPaintSettings *ups = &toolsettings->unified_paint_settings;
699         Paint *p = BKE_paint_get_active_from_context(C);
700         Brush *br = stroke->brush = BKE_paint_brush(p);
701         float zoomx, zoomy;
702
703         ED_view3d_viewcontext_init(C, &stroke->vc);
704
705         stroke->get_location = get_location;
706         stroke->test_start = test_start;
707         stroke->update_step = update_step;
708         stroke->redraw = redraw;
709         stroke->done = done;
710         stroke->event_type = event_type; /* for modal, return event */
711         stroke->ups = ups;
712         stroke->stroke_mode = RNA_enum_get(op->ptr, "mode");
713
714         get_imapaint_zoom(C, &zoomx, &zoomy);
715         stroke->zoom_2d = max_ff(zoomx, zoomy);
716
717         if (stroke->stroke_mode == BRUSH_STROKE_INVERT) {
718                 if (br->flag & (BRUSH_CURVE)) {
719                         RNA_enum_set(op->ptr, "mode", BRUSH_STROKE_NORMAL);
720                 }
721         }
722         /* initialize here */
723         ups->overlap_factor = 1.0;
724         ups->stroke_active = true;
725
726         zero_v3(ups->average_stroke_accum);
727         ups->average_stroke_counter = 0;
728
729         /* initialize here to avoid initialization conflict with threaded strokes */
730         curvemapping_initialize(br->curve);
731         if (p->flags & PAINT_USE_CAVITY_MASK)
732                 curvemapping_initialize(p->cavity_curve);
733
734         BKE_paint_set_overlay_override(br->overlay_flags);
735
736         return stroke;
737 }
738
739 void paint_stroke_data_free(struct wmOperator *op)
740 {
741         BKE_paint_set_overlay_override(0);
742         MEM_SAFE_FREE(op->customdata);
743 }
744
745 static void stroke_done(struct bContext *C, struct wmOperator *op)
746 {
747         struct PaintStroke *stroke = op->customdata;
748         UnifiedPaintSettings *ups = stroke->ups;
749
750         ups->draw_anchored = false;
751         ups->stroke_active = false;
752
753         /* reset rotation here to avoid doing so in cursor display */
754         if (!(stroke->brush->mtex.brush_angle_mode & MTEX_ANGLE_RAKE))
755                 ups->brush_rotation = 0.0f;
756
757         if (!(stroke->brush->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE))
758                 ups->brush_rotation_sec = 0.0f;
759
760         if (stroke->stroke_started) {
761                 if (stroke->redraw)
762                         stroke->redraw(C, stroke, true);
763
764                 if (stroke->done)
765                         stroke->done(C, stroke);
766         }
767
768         if (stroke->timer) {
769                 WM_event_remove_timer(
770                         CTX_wm_manager(C),
771                         CTX_wm_window(C),
772                         stroke->timer);
773         }
774
775         if (stroke->stroke_cursor)
776                 WM_paint_cursor_end(CTX_wm_manager(C), stroke->stroke_cursor);
777
778         BLI_freelistN(&stroke->line);
779
780         paint_stroke_data_free(op);
781 }
782
783 /* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
784 bool paint_space_stroke_enabled(Brush *br, ePaintMode mode)
785 {
786         return (br->flag & BRUSH_SPACE) && paint_supports_dynamic_size(br, mode);
787 }
788
789 static bool sculpt_is_grab_tool(Brush *br)
790 {
791         return ELEM(br->sculpt_tool,
792                      SCULPT_TOOL_GRAB,
793                      SCULPT_TOOL_THUMB,
794                      SCULPT_TOOL_ROTATE,
795                      SCULPT_TOOL_SNAKE_HOOK);
796 }
797
798 /* return true if the brush size can change during paint (normally used for pressure) */
799 bool paint_supports_dynamic_size(Brush *br, ePaintMode mode)
800 {
801         if (br->flag & BRUSH_ANCHORED)
802                 return false;
803
804         switch (mode) {
805                 case ePaintSculpt:
806                         if (sculpt_is_grab_tool(br))
807                                 return false;
808                         break;
809
810                 case ePaintTexture2D: /* fall through */
811                 case ePaintTextureProjective:
812                         if ((br->imagepaint_tool == PAINT_TOOL_FILL) &&
813                             (br->flag & BRUSH_USE_GRADIENT))
814                         {
815                                 return false;
816                         }
817                         break;
818
819                 default:
820                         break;
821         }
822         return true;
823 }
824
825 bool paint_supports_smooth_stroke(Brush *br, ePaintMode mode)
826 {
827         if (!(br->flag & BRUSH_SMOOTH_STROKE) ||
828             (br->flag & (BRUSH_ANCHORED | BRUSH_DRAG_DOT | BRUSH_LINE)))
829         {
830                 return false;
831         }
832
833         switch (mode) {
834                 case ePaintSculpt:
835                         if (sculpt_is_grab_tool(br))
836                                 return false;
837                         break;
838                 default:
839                         break;
840         }
841         return true;
842 }
843
844 bool paint_supports_texture(ePaintMode mode)
845 {
846         /* omit: PAINT_WEIGHT, PAINT_SCULPT_UV, PAINT_INVALID */
847         return ELEM(mode, ePaintSculpt, ePaintVertex, ePaintTextureProjective, ePaintTexture2D);
848 }
849
850 /* return true if the brush size can change during paint (normally used for pressure) */
851 bool paint_supports_dynamic_tex_coords(Brush *br, ePaintMode mode)
852 {
853         if (br->flag & BRUSH_ANCHORED)
854                 return false;
855
856         switch (mode) {
857                 case ePaintSculpt:
858                         if (sculpt_is_grab_tool(br))
859                                 return false;
860                         break;
861                 default:
862                         break;
863         }
864         return true;
865 }
866
867 #define PAINT_STROKE_MODAL_CANCEL 1
868
869 /* called in paint_ops.c, on each regeneration of keymaps  */
870 struct wmKeyMap *paint_stroke_modal_keymap(struct wmKeyConfig *keyconf)
871 {
872         static struct EnumPropertyItem modal_items[] = {
873                 {PAINT_STROKE_MODAL_CANCEL, "CANCEL", 0,
874                 "Cancel",
875                 "Cancel and undo a stroke in progress"},
876
877                 { 0 }
878         };
879
880         static const char *name = "Paint Stroke Modal";
881
882         struct wmKeyMap *keymap = WM_modalkeymap_get(keyconf, name);
883
884         /* this function is called for each spacetype, only needs to add map once */
885         if (!keymap) {
886                 keymap = WM_modalkeymap_add(keyconf, name, modal_items);
887
888                 /* items for modal map */
889                 WM_modalkeymap_add_item(
890                         keymap, ESCKEY, KM_PRESS, KM_ANY, 0, PAINT_STROKE_MODAL_CANCEL);
891         }
892
893         return keymap;
894 }
895
896 static void paint_stroke_add_sample(const Paint *paint,
897                                     PaintStroke *stroke,
898                                     float x, float y, float pressure)
899 {
900         PaintSample *sample = &stroke->samples[stroke->cur_sample];
901         int max_samples = CLAMPIS(paint->num_input_samples, 1, PAINT_MAX_INPUT_SAMPLES);
902
903         sample->mouse[0] = x;
904         sample->mouse[1] = y;
905         sample->pressure = pressure;
906
907         stroke->cur_sample++;
908         if (stroke->cur_sample >= max_samples)
909                 stroke->cur_sample = 0;
910         if (stroke->num_samples < max_samples)
911                 stroke->num_samples++;
912 }
913
914 static void paint_stroke_sample_average(const PaintStroke *stroke,
915                                         PaintSample *average)
916 {
917         int i;
918
919         memset(average, 0, sizeof(*average));
920
921         BLI_assert(stroke->num_samples > 0);
922
923         for (i = 0; i < stroke->num_samples; i++) {
924                 add_v2_v2(average->mouse, stroke->samples[i].mouse);
925                 average->pressure += stroke->samples[i].pressure;
926         }
927
928         mul_v2_fl(average->mouse, 1.0f / stroke->num_samples);
929         average->pressure /= stroke->num_samples;
930
931         /*printf("avg=(%f, %f), num=%d\n", average->mouse[0], average->mouse[1], stroke->num_samples);*/
932 }
933
934 /**
935  * Slightly different version of spacing for line/curve strokes,
936  * makes sure the dabs stay on the line path.
937  */
938 static void paint_line_strokes_spacing(
939         bContext *C, wmOperator *op, PaintStroke *stroke, float spacing, float *length_residue,
940         const float old_pos[2], const float new_pos[2])
941 {
942         UnifiedPaintSettings *ups = stroke->ups;
943
944         float mouse[2], dmouse[2];
945         float length;
946
947         sub_v2_v2v2(dmouse, new_pos, old_pos);
948         copy_v2_v2(stroke->last_mouse_position, old_pos);
949
950         length = normalize_v2(dmouse);
951
952         BLI_assert(length >= 0.0f);
953
954         if (length == 0.0f)
955                 return;
956
957         while (length > 0.0f) {
958                 float spacing_final = spacing - *length_residue;
959                 length += *length_residue;
960                 *length_residue = 0.0;
961
962                 if (length >= spacing) {
963                         mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing_final;
964                         mouse[1] = stroke->last_mouse_position[1] + dmouse[1] * spacing_final;
965
966                         ups->overlap_factor = paint_stroke_integrate_overlap(stroke->brush, 1.0);
967
968                         stroke->stroke_distance += spacing / stroke->zoom_2d;
969                         paint_brush_stroke_add_step(C, op, mouse, 1.0);
970
971                         length -= spacing;
972                         spacing_final = spacing;
973                 }
974                 else {
975                         break;
976                 }
977         }
978
979         *length_residue = length;
980 }
981
982
983 static void paint_stroke_line_end(bContext *C, wmOperator *op, PaintStroke *stroke, float mouse[2])
984 {
985         Brush *br = stroke->brush;
986         if (stroke->stroke_started && (br->flag & BRUSH_LINE)) {
987                 stroke->ups->overlap_factor = paint_stroke_integrate_overlap(br, 1.0);
988
989                 paint_brush_stroke_add_step(C, op, stroke->last_mouse_position, 1.0);
990                 paint_space_stroke(C, op, mouse, 1.0);
991         }
992 }
993
994 static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *stroke)
995 {
996         Brush *br = stroke->brush;
997
998         if (br->flag & BRUSH_CURVE) {
999                 UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
1000                 const Scene *scene = CTX_data_scene(C);
1001                 const float spacing = paint_space_stroke_spacing(scene, stroke, 1.0f, 1.0f);
1002                 PaintCurve *pc = br->paint_curve;
1003                 PaintCurvePoint *pcp;
1004                 float length_residue = 0.0f;
1005                 int i;
1006
1007                 if (!pc)
1008                         return true;
1009
1010 #ifdef DEBUG_TIME
1011                 TIMEIT_START_AVERAGED(whole_stroke);
1012 #endif
1013
1014                 pcp = pc->points;
1015                 stroke->ups->overlap_factor = paint_stroke_integrate_overlap(br, 1.0);
1016
1017                 for (i = 0; i < pc->tot_points - 1; i++, pcp++) {
1018                         int j;
1019                         float data[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2];
1020                         float tangents[(PAINT_CURVE_NUM_SEGMENTS + 1) * 2];
1021                         PaintCurvePoint *pcp_next = pcp + 1;
1022                         bool do_rake = false;
1023
1024                         for (j = 0; j < 2; j++) {
1025                                 BKE_curve_forward_diff_bezier(
1026                                         pcp->bez.vec[1][j],
1027                                         pcp->bez.vec[2][j],
1028                                         pcp_next->bez.vec[0][j],
1029                                         pcp_next->bez.vec[1][j],
1030                                         data + j, PAINT_CURVE_NUM_SEGMENTS, sizeof(float[2]));
1031                         }
1032
1033                         if ((br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) ||
1034                             (br->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE))
1035                         {
1036                                 do_rake = true;
1037                                 for (j = 0; j < 2; j++) {
1038                                         BKE_curve_forward_diff_tangent_bezier(
1039                                                 pcp->bez.vec[1][j],
1040                                                 pcp->bez.vec[2][j],
1041                                                 pcp_next->bez.vec[0][j],
1042                                                 pcp_next->bez.vec[1][j],
1043                                                 tangents + j, PAINT_CURVE_NUM_SEGMENTS, sizeof(float[2]));
1044                                 }
1045                         }
1046
1047                         for (j = 0; j < PAINT_CURVE_NUM_SEGMENTS; j++) {
1048                                 if (do_rake) {
1049                                         float rotation = atan2f(tangents[2 * j], tangents[2 * j + 1]);
1050                                         paint_update_brush_rake_rotation(ups, br, rotation);
1051                                 }
1052
1053                                 if (!stroke->stroke_started) {
1054                                         stroke->last_pressure = 1.0;
1055                                         copy_v2_v2(stroke->last_mouse_position, data + 2 * j);
1056                                         stroke->stroke_started = stroke->test_start(C, op, stroke->last_mouse_position);
1057
1058                                         if (stroke->stroke_started) {
1059                                                 paint_brush_stroke_add_step(C, op, data + 2 * j, 1.0);
1060                                                 paint_line_strokes_spacing(C, op, stroke, spacing, &length_residue, data + 2 * j, data + 2 * (j + 1));
1061                                         }
1062                                 }
1063                                 else {
1064                                         paint_line_strokes_spacing(C, op, stroke, spacing, &length_residue, data + 2 * j, data + 2 * (j + 1));
1065                                 }
1066                         }
1067                 }
1068
1069                 stroke_done(C, op);
1070
1071 #ifdef DEBUG_TIME
1072                 TIMEIT_END_AVERAGED(whole_stroke);
1073 #endif
1074
1075                 return true;
1076         }
1077
1078         return false;
1079 }
1080
1081 static void paint_stroke_line_constrain(PaintStroke *stroke, float mouse[2])
1082 {
1083         if (stroke->constrain_line) {
1084                 float line[2];
1085                 float angle, len, res;
1086
1087                 sub_v2_v2v2(line, mouse, stroke->last_mouse_position);
1088                 angle = atan2f(line[1], line[0]);
1089                 len = len_v2(line);
1090
1091                 /* divide angle by PI/4 */
1092                 angle = 4.0f * angle / (float)M_PI;
1093
1094                 /* now take residue */
1095                 res = angle - floorf(angle);
1096
1097                 /* residue decides how close we are at a certain angle */
1098                 if (res <= 0.5f) {
1099                         angle = floorf(angle) * (float)M_PI_4;
1100                 }
1101                 else {
1102                         angle = (floorf(angle) + 1.0f) * (float)M_PI_4;
1103                 }
1104
1105                 mouse[0] = stroke->constrained_pos[0] = len * cosf(angle) + stroke->last_mouse_position[0];
1106                 mouse[1] = stroke->constrained_pos[1] = len * sinf(angle) + stroke->last_mouse_position[1];
1107         }
1108 }
1109
1110 int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event)
1111 {
1112         Paint *p = BKE_paint_get_active_from_context(C);
1113         ePaintMode mode = BKE_paintmode_get_active_from_context(C);
1114         PaintStroke *stroke = op->customdata;
1115         Brush *br = stroke->brush;
1116         PaintSample sample_average;
1117         float mouse[2];
1118         bool first_dab = false;
1119         bool first_modal = false;
1120         bool redraw = false;
1121         float pressure;
1122
1123         /* see if tablet affects event. Line, anchored and drag dot strokes do not support pressure */
1124         pressure = (br->flag & (BRUSH_LINE | BRUSH_ANCHORED | BRUSH_DRAG_DOT)) ? 1.0f : WM_event_tablet_data(event, &stroke->pen_flip, NULL);
1125
1126         paint_stroke_add_sample(p, stroke, event->mval[0], event->mval[1], pressure);
1127         paint_stroke_sample_average(stroke, &sample_average);
1128
1129 #ifdef WITH_INPUT_NDOF
1130         /* let NDOF motion pass through to the 3D view so we can paint and rotate simultaneously!
1131          * this isn't perfect... even when an extra MOUSEMOVE is spoofed, the stroke discards it
1132          * since the 2D deltas are zero -- code in this file needs to be updated to use the
1133          * post-NDOF_MOTION MOUSEMOVE */
1134         if (event->type == NDOF_MOTION)
1135                 return OPERATOR_PASS_THROUGH;
1136 #endif
1137
1138         /* one time initialization */
1139         if (!stroke->stroke_init) {
1140                 if (paint_stroke_curve_end(C, op, stroke))
1141                         return OPERATOR_FINISHED;
1142
1143                 if (paint_supports_smooth_stroke(br, mode))
1144                         stroke->stroke_cursor =
1145                             WM_paint_cursor_activate(CTX_wm_manager(C), paint_poll, paint_draw_smooth_cursor, stroke);
1146
1147                 stroke->stroke_init = true;
1148                 first_modal = true;
1149         }
1150
1151         /* one time stroke initialization */
1152         if (!stroke->stroke_started) {
1153                 stroke->last_pressure = sample_average.pressure;
1154                 copy_v2_v2(stroke->last_mouse_position, sample_average.mouse);
1155                 stroke->stroke_started = stroke->test_start(C, op, sample_average.mouse);
1156                 BLI_assert((stroke->stroke_started & ~1) == 0);  /* 0/1 */
1157
1158                 if (stroke->stroke_started) {
1159                         if (br->flag & BRUSH_AIRBRUSH)
1160                                 stroke->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, stroke->brush->rate);
1161
1162                         if (br->flag & BRUSH_LINE) {
1163                                 stroke->stroke_cursor =
1164                                         WM_paint_cursor_activate(CTX_wm_manager(C), paint_poll, paint_draw_line_cursor, stroke);
1165                         }
1166
1167                         first_dab = true;
1168                 }
1169         }
1170
1171         /* Cancel */
1172         if (event->type == EVT_MODAL_MAP && event->val == PAINT_STROKE_MODAL_CANCEL) {
1173                 if (op->type->cancel) {
1174                         op->type->cancel(C, op);
1175                 }
1176                 else {
1177                         paint_stroke_cancel(C, op);
1178                 }
1179                 return OPERATOR_CANCELLED;
1180         }
1181
1182         if (event->type == stroke->event_type && !first_modal) {
1183                 if (event->val == KM_RELEASE) {
1184                         copy_v2_fl2(mouse, event->mval[0], event->mval[1]);
1185                         paint_stroke_line_constrain(stroke, mouse);
1186                         paint_stroke_line_end(C, op, stroke, mouse);
1187                         stroke_done(C, op);
1188                         return OPERATOR_FINISHED;
1189                 }
1190         }
1191         else if (ELEM(event->type, RETKEY, SPACEKEY)) {
1192                 paint_stroke_line_end(C, op, stroke, sample_average.mouse);
1193                 stroke_done(C, op);
1194                 return OPERATOR_FINISHED;
1195         }
1196         else if (br->flag & BRUSH_LINE) {
1197                 if (event->alt)
1198                         stroke->constrain_line = true;
1199                 else
1200                         stroke->constrain_line = false;
1201
1202                 copy_v2_fl2(mouse, event->mval[0], event->mval[1]);
1203                 paint_stroke_line_constrain(stroke, mouse);
1204
1205                 if (stroke->stroke_started && (first_modal || (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)))) {
1206                         if ((br->mtex.brush_angle_mode & MTEX_ANGLE_RAKE) || (br->mask_mtex.brush_angle_mode & MTEX_ANGLE_RAKE)) {
1207                                 copy_v2_v2(stroke->ups->last_rake, stroke->last_mouse_position);
1208                         }
1209                         paint_calculate_rake_rotation(stroke->ups, br, mouse);
1210                 }
1211         }
1212         else if (first_modal ||
1213                  /* regular dabs */
1214                  (!(br->flag & (BRUSH_AIRBRUSH)) && (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE))) ||
1215                  /* airbrush */
1216                  ((br->flag & BRUSH_AIRBRUSH) && event->type == TIMER && event->customdata == stroke->timer))
1217         {
1218                 if (paint_smooth_stroke(stroke, &sample_average, mode, mouse, &pressure)) {
1219                         if (stroke->stroke_started) {
1220                                 if (paint_space_stroke_enabled(br, mode)) {
1221                                         if (paint_space_stroke(C, op, mouse, pressure))
1222                                                 redraw = true;
1223                                 }
1224                                 else {
1225                                         float dmouse[2];
1226                                         sub_v2_v2v2(dmouse, mouse, stroke->last_mouse_position);
1227                                         stroke->stroke_distance += len_v2(dmouse);
1228                                         paint_brush_stroke_add_step(C, op, mouse, pressure);
1229                                         redraw = true;
1230                                 }
1231                         }
1232                 }
1233         }
1234
1235         /* we want the stroke to have the first daub at the start location
1236          * instead of waiting till we have moved the space distance */
1237         if (first_dab &&
1238             paint_space_stroke_enabled(br, mode) &&
1239             !(br->flag & BRUSH_SMOOTH_STROKE))
1240         {
1241                 stroke->ups->overlap_factor = paint_stroke_integrate_overlap(br, 1.0);
1242                 paint_brush_stroke_add_step(C, op, sample_average.mouse, sample_average.pressure);
1243                 redraw = true;
1244         }
1245
1246         /* do updates for redraw. if event is inbetween mousemove there are more
1247          * coming, so postpone potentially slow redraw updates until all are done */
1248         if (event->type != INBETWEEN_MOUSEMOVE) {
1249                 wmWindow *window = CTX_wm_window(C);
1250                 ARegion *ar = CTX_wm_region(C);
1251
1252                 /* At the very least, invalidate the cursor */
1253                 if (ar && (p->flags & PAINT_SHOW_BRUSH))
1254                         WM_paint_cursor_tag_redraw(window, ar);
1255
1256                 if (redraw && stroke->redraw)
1257                         stroke->redraw(C, stroke, false);
1258         }
1259
1260         return OPERATOR_RUNNING_MODAL;
1261 }
1262
1263 int paint_stroke_exec(bContext *C, wmOperator *op)
1264 {
1265         PaintStroke *stroke = op->customdata;
1266
1267         /* only when executed for the first time */
1268         if (stroke->stroke_started == 0) {
1269                 PropertyRNA *strokeprop;
1270                 PointerRNA firstpoint;
1271                 float mouse[2];
1272
1273                 strokeprop = RNA_struct_find_property(op->ptr, "stroke");
1274
1275                 if (RNA_property_collection_lookup_int(op->ptr, strokeprop, 0, &firstpoint)) {
1276                         RNA_float_get_array(&firstpoint, "mouse", mouse);
1277                         stroke->stroke_started = stroke->test_start(C, op, mouse);
1278                 }
1279         }
1280
1281         if (stroke->stroke_started) {
1282                 RNA_BEGIN (op->ptr, itemptr, "stroke")
1283                 {
1284                         stroke->update_step(C, stroke, &itemptr);
1285                 }
1286                 RNA_END;
1287         }
1288
1289         bool ok = (stroke->stroke_started != 0);
1290
1291         stroke_done(C, op);
1292
1293         return ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
1294 }
1295
1296 void paint_stroke_cancel(bContext *C, wmOperator *op)
1297 {
1298         stroke_done(C, op);
1299 }
1300
1301 ViewContext *paint_stroke_view_context(PaintStroke *stroke)
1302 {
1303         return &stroke->vc;
1304 }
1305
1306 void *paint_stroke_mode_data(struct PaintStroke *stroke)
1307 {
1308         return stroke->mode_data;
1309 }
1310
1311 bool paint_stroke_flipped(struct PaintStroke *stroke)
1312 {
1313         return stroke->pen_flip;
1314 }
1315
1316 float paint_stroke_distance_get(struct PaintStroke *stroke)
1317 {
1318         return stroke->stroke_distance;
1319 }
1320
1321 void paint_stroke_set_mode_data(PaintStroke *stroke, void *mode_data)
1322 {
1323         stroke->mode_data = mode_data;
1324 }
1325
1326 bool paint_poll(bContext *C)
1327 {
1328         Paint *p = BKE_paint_get_active_from_context(C);
1329         Object *ob = CTX_data_active_object(C);
1330         ScrArea *sa = CTX_wm_area(C);
1331         ARegion *ar = CTX_wm_region(C);
1332
1333         return p && ob && BKE_paint_brush(p) &&
1334                (sa && ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_IMAGE)) &&
1335                (ar && ar->regiontype == RGN_TYPE_WINDOW);
1336 }