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