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