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