Tool System: per space/mode tool support
[blender.git] / source / blender / editors / sculpt_paint / paint_vertex.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) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/sculpt_paint/paint_vertex.c
29  *  \ingroup edsculpt
30  *
31  * Used for vertex color & weight paint and mode switching.
32  *
33  * \note This file is already big,
34  * use `paint_vertex_color_ops.c` & `paint_vertex_weight_ops.c` for general purpose operators.
35  */
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BLI_listbase.h"
40 #include "BLI_rect.h"
41 #include "BLI_math.h"
42 #include "BLI_array_utils.h"
43 #include "BLI_task.h"
44
45 #include "DNA_armature_types.h"
46 #include "DNA_mesh_types.h"
47 #include "DNA_particle_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_brush_types.h"
50 #include "DNA_object_types.h"
51
52 #include "RNA_access.h"
53 #include "RNA_define.h"
54
55 #include "BKE_brush.h"
56 #include "BKE_context.h"
57 #include "BKE_deform.h"
58 #include "BKE_global.h"
59 #include "BKE_main.h"
60 #include "BKE_mesh.h"
61 #include "BKE_mesh_mapping.h"
62 #include "BKE_object_deform.h"
63 #include "BKE_paint.h"
64 #include "BKE_report.h"
65 #include "BKE_subsurf.h"
66
67 #include "DEG_depsgraph.h"
68
69 #include "WM_api.h"
70 #include "WM_types.h"
71 #include "WM_message.h"
72
73 #include "ED_object.h"
74 #include "ED_mesh.h"
75 #include "ED_screen.h"
76 #include "ED_view3d.h"
77
78 #include "bmesh.h"
79 #include "BKE_ccg.h"
80
81 #include "sculpt_intern.h"
82 #include "paint_intern.h"  /* own include */
83
84 /* Use for 'blur' brush, align with PBVH nodes, created and freed on each update. */
85 struct VPaintAverageAccum {
86         uint len;
87         uint value[3];
88 };
89
90 struct WPaintAverageAccum {
91         uint len;
92         double value;
93 };
94
95 struct NormalAnglePrecalc {
96         bool do_mask_normal;
97         /* what angle to mask at */
98         float angle;
99         /* cos(angle), faster to compare */
100         float angle__cos;
101         float angle_inner;
102         float angle_inner__cos;
103         /* difference between angle and angle_inner, for easy access */
104         float angle_range;
105 };
106
107
108 static void view_angle_limits_init(
109         struct NormalAnglePrecalc *a, float angle, bool do_mask_normal)
110 {
111         angle = RAD2DEGF(angle);
112         a->do_mask_normal = do_mask_normal;
113         if (do_mask_normal) {
114                 a->angle_inner = angle;
115                 a->angle = (a->angle_inner + 90.0f) * 0.5f;
116         }
117         else {
118                 a->angle_inner = a->angle = angle;
119         }
120
121         a->angle_inner *=   (float)(M_PI_2 / 90);
122         a->angle *=         (float)(M_PI_2 / 90);
123         a->angle_range = a->angle - a->angle_inner;
124
125         if (a->angle_range <= 0.0f) {
126                 a->do_mask_normal = false;  /* no need to do blending */
127         }
128
129         a->angle__cos       = cosf(a->angle);
130         a->angle_inner__cos = cosf(a->angle_inner);
131 }
132
133 static float view_angle_limits_apply_falloff(
134         const struct NormalAnglePrecalc *a, float angle_cos, float *mask_p)
135 {
136         if (angle_cos <= a->angle__cos) {
137                 /* outsize the normal limit */
138                 return false;
139         }
140         else if (angle_cos < a->angle_inner__cos) {
141                 *mask_p *= (a->angle - acosf(angle_cos)) / a->angle_range;
142                 return true;
143         }
144         else {
145                 return true;
146         }
147 }
148
149 static bool vwpaint_use_normal(const VPaint *vp)
150 {
151         return ((vp->paint.brush->flag & BRUSH_FRONTFACE) != 0) ||
152                ((vp->paint.brush->flag & BRUSH_FRONTFACE_FALLOFF) != 0);
153 }
154
155 static bool brush_use_accumulate(const Brush *brush)
156 {
157         return (brush->flag & BRUSH_ACCUMULATE) != 0 || brush->vertexpaint_tool == PAINT_BLEND_SMEAR;
158 }
159
160 static MDeformVert *defweight_prev_init(MDeformVert *dvert_prev, MDeformVert *dvert_curr, int index)
161 {
162         MDeformVert *dv_curr = &dvert_curr[index];
163         MDeformVert *dv_prev = &dvert_prev[index];
164         if (dv_prev->flag == 1) {
165                 dv_prev->flag = 0;
166                 defvert_copy(dv_prev, dv_curr);
167         }
168         return dv_prev;
169 }
170
171 /* check if we can do partial updates and have them draw realtime
172  * (without rebuilding the 'derivedFinal') */
173 static bool vertex_paint_use_fast_update_check(Object *ob)
174 {
175         DerivedMesh *dm = ob->derivedFinal;
176
177         if (dm) {
178                 Mesh *me = BKE_mesh_from_object(ob);
179                 if (me && me->mloopcol) {
180                         return (me->mloopcol == CustomData_get_layer(&dm->loopData, CD_MLOOPCOL));
181                 }
182         }
183
184         return false;
185 }
186
187 static void paint_last_stroke_update(Scene *scene, ARegion *ar, const float mval[2])
188 {
189         const int mval_i[2] = {mval[0], mval[1]};
190         float world[3];
191
192         if (ED_view3d_autodist_simple(ar, mval_i, world, 0, NULL)) {
193                 UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
194                 ups->average_stroke_counter++;
195                 add_v3_v3(ups->average_stroke_accum, world);
196                 ups->last_stroke_valid = true;
197         }
198 }
199
200 /* polling - retrieve whether cursor should be set or operator should be done */
201
202 /* Returns true if vertex paint mode is active */
203 int vertex_paint_mode_poll(bContext *C)
204 {
205         Object *ob = CTX_data_active_object(C);
206
207         return ob && ob->mode == OB_MODE_VERTEX_PAINT && ((Mesh *)ob->data)->totpoly;
208 }
209
210 static int vertex_paint_poll_ex(bContext *C, bool check_tool)
211 {
212         if (vertex_paint_mode_poll(C) &&
213             BKE_paint_brush(&CTX_data_tool_settings(C)->vpaint->paint))
214         {
215                 ScrArea *sa = CTX_wm_area(C);
216                 if (sa && sa->spacetype == SPACE_VIEW3D) {
217                         ARegion *ar = CTX_wm_region(C);
218                         if (ar->regiontype == RGN_TYPE_WINDOW) {
219                                 if (!check_tool || WM_toolsystem_active_tool_is_brush(C)) {
220                                         return 1;
221                                 }
222                         }
223                 }
224         }
225         return 0;
226 }
227
228 int vertex_paint_poll(bContext *C)
229 {
230         return vertex_paint_poll_ex(C, true);
231 }
232
233 int vertex_paint_poll_ignore_tool(bContext *C)
234 {
235         return vertex_paint_poll_ex(C, true);
236 }
237
238 int weight_paint_mode_poll(bContext *C)
239 {
240         Object *ob = CTX_data_active_object(C);
241
242         return ob && ob->mode == OB_MODE_WEIGHT_PAINT && ((Mesh *)ob->data)->totpoly;
243 }
244
245 static int weight_paint_poll_ex(bContext *C, bool check_tool)
246 {
247         Object *ob = CTX_data_active_object(C);
248         ScrArea *sa;
249
250         if ((ob != NULL) &&
251             (ob->mode & OB_MODE_WEIGHT_PAINT) &&
252             (BKE_paint_brush(&CTX_data_tool_settings(C)->wpaint->paint) != NULL) &&
253             (sa = CTX_wm_area(C)) &&
254             (sa->spacetype == SPACE_VIEW3D))
255         {
256                 ARegion *ar = CTX_wm_region(C);
257                 if (ar->regiontype == RGN_TYPE_WINDOW) {
258                         if (!check_tool || WM_toolsystem_active_tool_is_brush(C)) {
259                                 return 1;
260                         }
261                 }
262         }
263         return 0;
264 }
265
266 int weight_paint_poll(bContext *C)
267 {
268         return weight_paint_poll_ex(C, true);
269 }
270
271 int weight_paint_poll_ignore_tool(bContext *C)
272 {
273         return weight_paint_poll_ex(C, false);
274 }
275
276 static VPaint *new_vpaint(void)
277 {
278         VPaint *vp = MEM_callocN(sizeof(VPaint), "VPaint");
279
280         vp->paint.flags |= PAINT_SHOW_BRUSH;
281
282         return vp;
283 }
284
285 uint vpaint_get_current_col(Scene *scene, VPaint *vp)
286 {
287         Brush *brush = BKE_paint_brush(&vp->paint);
288         uchar col[4];
289         rgb_float_to_uchar(col, BKE_brush_color_get(scene, brush));
290         col[3] = 255; /* alpha isn't used, could even be removed to speedup paint a little */
291         return *(uint *)col;
292 }
293
294 /* wpaint has 'wpaint_blend' */
295 static uint vpaint_blend(
296         const VPaint *vp, uint color_curr, uint color_orig,
297         uint color_paint, const int alpha_i,
298         /* pre scaled from [0-1] --> [0-255] */
299         const int brush_alpha_value_i)
300 {
301         const Brush *brush = vp->paint.brush;
302         const int tool = brush->vertexpaint_tool;
303
304         uint color_blend = ED_vpaint_blend_tool(tool, color_curr, color_paint, alpha_i);
305
306         /* if no accumulate, clip color adding with colorig & orig alpha */
307         if (!brush_use_accumulate(brush)) {
308                 uint color_test, a;
309                 char *cp, *ct, *co;
310
311                 color_test = ED_vpaint_blend_tool(tool, color_orig, color_paint, brush_alpha_value_i);
312
313                 cp = (char *)&color_blend;
314                 ct = (char *)&color_test;
315                 co = (char *)&color_orig;
316
317                 for (a = 0; a < 4; a++) {
318                         if (ct[a] < co[a]) {
319                                 if (cp[a] < ct[a]) cp[a] = ct[a];
320                                 else if (cp[a] > co[a]) cp[a] = co[a];
321                         }
322                         else {
323                                 if (cp[a] < co[a]) cp[a] = co[a];
324                                 else if (cp[a] > ct[a]) cp[a] = ct[a];
325                         }
326                 }
327         }
328
329         if ((brush->flag & BRUSH_LOCK_ALPHA) &&
330             !ELEM(tool, PAINT_BLEND_ALPHA_SUB, PAINT_BLEND_ALPHA_ADD))
331         {
332                 char *cp, *cc;
333                 cp = (char *)&color_blend;
334                 cc = (char *)&color_curr;
335                 cp[3] = cc[3];
336         }
337
338         return color_blend;
339 }
340
341 static void tex_color_alpha(
342         VPaint *vp, const ViewContext *vc, const float co[3],
343         float r_rgba[4])
344 {
345         const Brush *brush = BKE_paint_brush(&vp->paint);
346         BLI_assert(brush->mtex.tex != NULL);
347         if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_3D) {
348                 BKE_brush_sample_tex_3D(vc->scene, brush, co, r_rgba, 0, NULL);
349         }
350         else {
351                 float co_ss[2];  /* screenspace */
352                 if (ED_view3d_project_float_object(
353                         vc->ar,
354                         co, co_ss,
355                         V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
356                 {
357                         const float co_ss_3d[3] = {co_ss[0], co_ss[1], 0.0f};  /* we need a 3rd empty value */
358                         BKE_brush_sample_tex_3D(vc->scene, brush, co_ss_3d, r_rgba, 0, NULL);
359                 }
360                 else {
361                         zero_v4(r_rgba);
362                 }
363         }
364 }
365
366 /* vpaint has 'vpaint_blend' */
367 static float wpaint_blend(
368         const VPaint *wp, float weight,
369         const float alpha, float paintval,
370         const float UNUSED(brush_alpha_value),
371         const short do_flip)
372 {
373         const Brush *brush = wp->paint.brush;
374         int tool = brush->vertexpaint_tool;
375
376         if (do_flip) {
377                 switch (tool) {
378                         case PAINT_BLEND_MIX:
379                                 paintval = 1.f - paintval; break;
380                         case PAINT_BLEND_ADD:
381                                 tool = PAINT_BLEND_SUB; break;
382                         case PAINT_BLEND_SUB:
383                                 tool = PAINT_BLEND_ADD; break;
384                         case PAINT_BLEND_LIGHTEN:
385                                 tool = PAINT_BLEND_DARKEN; break;
386                         case PAINT_BLEND_DARKEN:
387                                 tool = PAINT_BLEND_LIGHTEN; break;
388                 }
389         }
390
391         weight = ED_wpaint_blend_tool(tool, weight, paintval, alpha);
392
393         CLAMP(weight, 0.0f, 1.0f);
394
395         return weight;
396 }
397
398 static float wpaint_clamp_monotonic(float oldval, float curval, float newval)
399 {
400         if (newval < oldval)
401                 return MIN2(newval, curval);
402         else if (newval > oldval)
403                 return MAX2(newval, curval);
404         else
405                 return newval;
406 }
407
408 /* ----------------------------------------------------- */
409
410 static void do_weight_paint_normalize_all(MDeformVert *dvert, const int defbase_tot, const bool *vgroup_validmap)
411 {
412         float sum = 0.0f, fac;
413         uint i, tot = 0;
414         MDeformWeight *dw;
415
416         for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
417                 if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) {
418                         tot++;
419                         sum += dw->weight;
420                 }
421         }
422
423         if ((tot == 0) || (sum == 1.0f)) {
424                 return;
425         }
426
427         if (sum != 0.0f) {
428                 fac = 1.0f / sum;
429
430                 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
431                         if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) {
432                                 dw->weight *= fac;
433                         }
434                 }
435         }
436         else {
437                 /* hrmf, not a factor in this case */
438                 fac = 1.0f / tot;
439
440                 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
441                         if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) {
442                                 dw->weight = fac;
443                         }
444                 }
445         }
446 }
447
448 /**
449  * A version of #do_weight_paint_normalize_all that includes locked weights
450  * but only changes unlocked weights.
451  */
452 static bool do_weight_paint_normalize_all_locked(
453         MDeformVert *dvert, const int defbase_tot, const bool *vgroup_validmap,
454         const bool *lock_flags)
455 {
456         float sum = 0.0f, fac;
457         float sum_unlock = 0.0f;
458         float lock_weight = 0.0f;
459         uint i, tot = 0;
460         MDeformWeight *dw;
461
462         if (lock_flags == NULL) {
463                 do_weight_paint_normalize_all(dvert, defbase_tot, vgroup_validmap);
464                 return true;
465         }
466
467         for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
468                 if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) {
469                         sum += dw->weight;
470
471                         if (lock_flags[dw->def_nr]) {
472                                 lock_weight += dw->weight;
473                         }
474                         else {
475                                 tot++;
476                                 sum_unlock += dw->weight;
477                         }
478                 }
479         }
480
481         if (sum == 1.0f) {
482                 return true;
483         }
484
485         if (tot == 0) {
486                 return false;
487         }
488
489         if (lock_weight >= 1.0f) {
490                 /* locked groups make it impossible to fully normalize,
491                  * zero out what we can and return false */
492                 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
493                         if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) {
494                                 if (lock_flags[dw->def_nr] == false) {
495                                         dw->weight = 0.0f;
496                                 }
497                         }
498                 }
499
500                 return (lock_weight == 1.0f);
501         }
502         else if (sum_unlock != 0.0f) {
503                 fac = (1.0f - lock_weight) / sum_unlock;
504
505                 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
506                         if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) {
507                                 if (lock_flags[dw->def_nr] == false) {
508                                         dw->weight *= fac;
509                                         /* paranoid but possibly with float error */
510                                         CLAMP(dw->weight, 0.0f, 1.0f);
511                                 }
512                         }
513                 }
514         }
515         else {
516                 /* hrmf, not a factor in this case */
517                 fac = (1.0f - lock_weight) / tot;
518                 /* paranoid but possibly with float error */
519                 CLAMP(fac, 0.0f, 1.0f);
520
521                 for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
522                         if (dw->def_nr < defbase_tot && vgroup_validmap[dw->def_nr]) {
523                                 if (lock_flags[dw->def_nr] == false) {
524                                         dw->weight = fac;
525                                 }
526                         }
527                 }
528         }
529
530         return true;
531 }
532
533 /**
534  * \note same as function above except it does a second pass without active group
535  * if normalize fails with it.
536  */
537 static void do_weight_paint_normalize_all_locked_try_active(
538         MDeformVert *dvert, const int defbase_tot, const bool *vgroup_validmap,
539         const bool *lock_flags, const bool *lock_with_active)
540 {
541         /* first pass with both active and explicitly locked groups restricted from change */
542
543         bool success = do_weight_paint_normalize_all_locked(dvert, defbase_tot, vgroup_validmap, lock_with_active);
544
545         if (!success) {
546                 /**
547                  * Locks prevented the first pass from full completion, so remove restriction on active group; e.g:
548                  *
549                  * - With 1.0 weight painted into active:
550                  *   nonzero locked weight; first pass zeroed out unlocked weight; scale 1 down to fit.
551                  * - With 0.0 weight painted into active:
552                  *   no unlocked groups; first pass did nothing; increase 0 to fit.
553                  */
554                 do_weight_paint_normalize_all_locked(dvert, defbase_tot, vgroup_validmap, lock_flags);
555         }
556 }
557
558 #if 0 /* UNUSED */
559 static bool has_unselected_unlocked_bone_group(
560         int defbase_tot, bool *defbase_sel, int selected,
561         const bool *lock_flags, const bool *vgroup_validmap)
562 {
563         int i;
564         if (defbase_tot == selected) {
565                 return false;
566         }
567         for (i = 0; i < defbase_tot; i++) {
568                 if (vgroup_validmap[i] && !defbase_sel[i] && !lock_flags[i]) {
569                         return true;
570                 }
571         }
572         return false;
573 }
574 #endif
575
576 static void multipaint_clamp_change(
577         MDeformVert *dvert, const int defbase_tot, const bool *defbase_sel,
578         float *change_p)
579 {
580         int i;
581         MDeformWeight *dw;
582         float val;
583         float change = *change_p;
584
585         /* verify that the change does not cause values exceeding 1 and clamp it */
586         for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
587                 if (dw->def_nr < defbase_tot && defbase_sel[dw->def_nr]) {
588                         if (dw->weight) {
589                                 val = dw->weight * change;
590                                 if (val > 1) {
591                                         change = 1.0f / dw->weight;
592                                 }
593                         }
594                 }
595         }
596
597         *change_p = change;
598 }
599
600 static bool multipaint_verify_change(MDeformVert *dvert, const int defbase_tot, float change, const bool *defbase_sel)
601 {
602         int i;
603         MDeformWeight *dw;
604         float val;
605
606         /* in case the change is reduced, you need to recheck
607          * the earlier values to make sure they are not 0
608          * (precision error) */
609         for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
610                 if (dw->def_nr < defbase_tot && defbase_sel[dw->def_nr]) {
611                         if (dw->weight) {
612                                 val = dw->weight * change;
613                                 /* the value should never reach zero while multi-painting if it
614                                  * was nonzero beforehand */
615                                 if (val <= 0) {
616                                         return false;
617                                 }
618                         }
619                 }
620         }
621
622         return true;
623 }
624
625 static void multipaint_apply_change(MDeformVert *dvert, const int defbase_tot, float change, const bool *defbase_sel)
626 {
627         int i;
628         MDeformWeight *dw;
629
630         /* apply the valid change */
631         for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
632                 if (dw->def_nr < defbase_tot && defbase_sel[dw->def_nr]) {
633                         if (dw->weight) {
634                                 dw->weight = dw->weight * change;
635                                 CLAMP(dw->weight, 0.0f, 1.0f);
636                         }
637                 }
638         }
639 }
640
641 /**
642  * Variables stored both for 'active' and 'mirror' sides.
643  */
644 struct WeightPaintGroupData {
645         /** index of active group or its mirror
646          *
647          * - 'active' is always `ob->actdef`.
648          * - 'mirror' is -1 when 'ME_EDIT_MIRROR_X' flag id disabled,
649          *   otherwise this will be set to the mirror or the active group (if the group isn't mirrored).
650          */
651         int index;
652         /** lock that includes the 'index' as locked too
653          *
654          * - 'active' is set of locked or active/selected groups
655          * - 'mirror' is set of locked or mirror groups
656          */
657         const bool *lock;
658 };
659
660 /* struct to avoid passing many args each call to do_weight_paint_vertex()
661  * this _could_ be made a part of the operators 'WPaintData' struct, or at
662  * least a member, but for now keep its own struct, initialized on every
663  * paint stroke update - campbell */
664 typedef struct WeightPaintInfo {
665
666         int defbase_tot;
667
668         /* both must add up to 'defbase_tot' */
669         int defbase_tot_sel;
670         int defbase_tot_unsel;
671
672         struct WeightPaintGroupData active, mirror;
673
674         /* boolean array for locked bones,
675          * length of defbase_tot */
676         const bool *lock_flags;
677         /* boolean array for selected bones,
678          * length of defbase_tot, cant be const because of how its passed */
679         const bool *defbase_sel;
680         /* same as WeightPaintData.vgroup_validmap,
681          * only added here for convenience */
682         const bool *vgroup_validmap;
683
684         bool do_flip;
685         bool do_multipaint;
686         bool do_auto_normalize;
687
688         float brush_alpha_value;  /* result of BKE_brush_alpha_get() */
689 } WeightPaintInfo;
690
691 static void do_weight_paint_vertex_single(
692         /* vars which remain the same for every vert */
693         const VPaint *wp, Object *ob, const WeightPaintInfo *wpi,
694         /* vars which change on each stroke */
695         const uint index, float alpha, float paintweight)
696 {
697         Mesh *me = ob->data;
698         MDeformVert *dv = &me->dvert[index];
699         bool topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
700
701         MDeformWeight *dw;
702         float weight_prev;
703
704         /* mirror vars */
705         int index_mirr;
706         int vgroup_mirr;
707
708         MDeformVert *dv_mirr;
709         MDeformWeight *dw_mirr;
710
711         /* from now on we can check if mirrors enabled if this var is -1 and not bother with the flag */
712         if (me->editflag & ME_EDIT_MIRROR_X) {
713                 index_mirr = mesh_get_x_mirror_vert(ob, NULL, index, topology);
714                 vgroup_mirr = wpi->mirror.index;
715
716                 /* another possible error - mirror group _and_ active group are the same (which is fine),
717                  * but we also are painting onto a center vertex - this would paint the same weight twice */
718                 if (index_mirr == index && vgroup_mirr == wpi->active.index) {
719                         index_mirr = vgroup_mirr = -1;
720                 }
721         }
722         else {
723                 index_mirr = vgroup_mirr = -1;
724         }
725
726         if (wp->flag & VP_FLAG_VGROUP_RESTRICT) {
727                 dw = defvert_find_index(dv, wpi->active.index);
728         }
729         else {
730                 dw = defvert_verify_index(dv, wpi->active.index);
731         }
732
733         if (dw == NULL) {
734                 return;
735         }
736
737         /* get the mirror def vars */
738         if (index_mirr != -1) {
739                 dv_mirr = &me->dvert[index_mirr];
740                 if (wp->flag & VP_FLAG_VGROUP_RESTRICT) {
741                         dw_mirr = defvert_find_index(dv_mirr, vgroup_mirr);
742
743                         if (dw_mirr == NULL) {
744                                 index_mirr = vgroup_mirr = -1;
745                                 dv_mirr = NULL;
746                         }
747                 }
748                 else {
749                         if (index != index_mirr) {
750                                 dw_mirr = defvert_verify_index(dv_mirr, vgroup_mirr);
751                         }
752                         else {
753                                 /* dv and dv_mirr are the same */
754                                 int totweight_prev = dv_mirr->totweight;
755                                 int dw_offset = (int)(dw - dv_mirr->dw);
756                                 dw_mirr = defvert_verify_index(dv_mirr, vgroup_mirr);
757
758                                 /* if we added another, get our old one back */
759                                 if (totweight_prev != dv_mirr->totweight) {
760                                         dw = &dv_mirr->dw[dw_offset];
761                                 }
762                         }
763                 }
764         }
765         else {
766                 dv_mirr = NULL;
767                 dw_mirr = NULL;
768         }
769
770         if (!brush_use_accumulate(wp->paint.brush)) {
771                 MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
772                 MDeformVert *dv_prev = defweight_prev_init(dvert_prev, me->dvert, index);
773                 if (index_mirr != -1) {
774                         defweight_prev_init(dvert_prev, me->dvert, index_mirr);
775                 }
776
777                 weight_prev = defvert_find_weight(dv_prev, wpi->active.index);
778         }
779         else {
780                 weight_prev = dw->weight;
781         }
782
783         /* If there are no normalize-locks or multipaint,
784          * then there is no need to run the more complicated checks */
785
786         {
787                 float new_weight = wpaint_blend(
788                         wp, weight_prev, alpha, paintweight,
789                         wpi->brush_alpha_value, wpi->do_flip);
790
791                 dw->weight = wpaint_clamp_monotonic(weight_prev, dw->weight, new_weight);
792
793                 /* WATCH IT: take care of the ordering of applying mirror -> normalize,
794                  * can give wrong results [#26193], least confusing if normalize is done last */
795
796                 /* apply mirror */
797                 if (index_mirr != -1) {
798                         /* copy, not paint again */
799                         dw_mirr->weight = dw->weight;
800                 }
801
802                 /* apply normalize */
803                 if (wpi->do_auto_normalize) {
804                         /* note on normalize - this used to be applied after painting and normalize all weights,
805                          * in some ways this is good because there is feedback where the more weights involved would
806                          * 'resist' so you couldn't instantly zero out other weights by painting 1.0 on the active.
807                          *
808                          * However this gave a problem since applying mirror, then normalize both verts
809                          * the resulting weight wont match on both sides.
810                          *
811                          * If this 'resisting', slower normalize is nicer, we could call
812                          * do_weight_paint_normalize_all() and only use...
813                          * do_weight_paint_normalize_all_active() when normalizing the mirror vertex.
814                          * - campbell
815                          */
816                         do_weight_paint_normalize_all_locked_try_active(
817                                 dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags, wpi->active.lock);
818
819                         if (index_mirr != -1) {
820                                 /* only normalize if this is not a center vertex, else we get a conflict, normalizing twice */
821                                 if (index != index_mirr) {
822                                         do_weight_paint_normalize_all_locked_try_active(
823                                                 dv_mirr, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags, wpi->mirror.lock);
824                                 }
825                                 else {
826                                         /* this case accounts for...
827                                          * - painting onto a center vertex of a mesh
828                                          * - x mirror is enabled
829                                          * - auto normalize is enabled
830                                          * - the group you are painting onto has a L / R version
831                                          *
832                                          * We want L/R vgroups to have the same weight but this cant be if both are over 0.5,
833                                          * We _could_ have special check for that, but this would need its own normalize function which
834                                          * holds 2 groups from changing at once.
835                                          *
836                                          * So! just balance out the 2 weights, it keeps them equal and everything normalized.
837                                          *
838                                          * While it wont hit the desired weight immediately as the user waggles their mouse,
839                                          * constant painting and re-normalizing will get there. this is also just simpler logic.
840                                          * - campbell */
841                                         dw_mirr->weight = dw->weight = (dw_mirr->weight + dw->weight) * 0.5f;
842                                 }
843                         }
844                 }
845         }
846 }
847
848 static void do_weight_paint_vertex_multi(
849         /* vars which remain the same for every vert */
850         const VPaint *wp, Object *ob, const WeightPaintInfo *wpi,
851         /* vars which change on each stroke */
852         const uint index, float alpha, float paintweight)
853 {
854         Mesh *me = ob->data;
855         MDeformVert *dv = &me->dvert[index];
856         bool topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
857
858         /* mirror vars */
859         int index_mirr = -1;
860         MDeformVert *dv_mirr = NULL;
861
862         /* weights */
863         float curw, oldw, neww, change, curw_mirr, change_mirr;
864
865         /* from now on we can check if mirrors enabled if this var is -1 and not bother with the flag */
866         if (me->editflag & ME_EDIT_MIRROR_X) {
867                 index_mirr = mesh_get_x_mirror_vert(ob, NULL, index, topology);
868
869                 if (index_mirr != -1 && index_mirr != index) {
870                         dv_mirr = &me->dvert[index_mirr];
871                 }
872                 else {
873                         index_mirr = -1;
874                 }
875         }
876
877         /* compute weight change by applying the brush to average or sum of group weights */
878         curw = BKE_defvert_multipaint_collective_weight(
879                 dv, wpi->defbase_tot, wpi->defbase_sel, wpi->defbase_tot_sel, wpi->do_auto_normalize);
880
881         if (curw == 0.0f) {
882                 /* note: no weight to assign to this vertex, could add all groups? */
883                 return;
884         }
885
886         if (!brush_use_accumulate(wp->paint.brush)) {
887                 MDeformVert *dvert_prev = ob->sculpt->mode.wpaint.dvert_prev;
888                 MDeformVert *dv_prev = defweight_prev_init(dvert_prev, me->dvert, index);
889                 if (index_mirr != -1) {
890                         defweight_prev_init(dvert_prev, me->dvert, index_mirr);
891                 }
892
893                 oldw = BKE_defvert_multipaint_collective_weight(
894                         dv_prev, wpi->defbase_tot, wpi->defbase_sel, wpi->defbase_tot_sel, wpi->do_auto_normalize);
895         }
896         else {
897                 oldw = curw;
898         }
899
900         neww = wpaint_blend(wp, oldw, alpha, paintweight, wpi->brush_alpha_value, wpi->do_flip);
901         neww = wpaint_clamp_monotonic(oldw, curw, neww);
902
903         change = neww / curw;
904
905         /* verify for all groups that 0 < result <= 1 */
906         multipaint_clamp_change(dv, wpi->defbase_tot, wpi->defbase_sel, &change);
907
908         if (dv_mirr != NULL) {
909                 curw_mirr = BKE_defvert_multipaint_collective_weight(
910                         dv_mirr, wpi->defbase_tot, wpi->defbase_sel, wpi->defbase_tot_sel, wpi->do_auto_normalize);
911
912                 if (curw_mirr == 0.0f) {
913                         /* can't mirror into a zero weight vertex */
914                         dv_mirr = NULL;
915                 }
916                 else {
917                         /* mirror is changed to achieve the same collective weight value */
918                         float orig = change_mirr = curw * change / curw_mirr;
919
920                         multipaint_clamp_change(dv_mirr, wpi->defbase_tot, wpi->defbase_sel, &change_mirr);
921
922                         if (!multipaint_verify_change(dv_mirr, wpi->defbase_tot, change_mirr, wpi->defbase_sel)) {
923                                 return;
924                         }
925
926                         change *= change_mirr / orig;
927                 }
928         }
929
930         if (!multipaint_verify_change(dv, wpi->defbase_tot, change, wpi->defbase_sel)) {
931                 return;
932         }
933
934         /* apply validated change to vertex and mirror */
935         multipaint_apply_change(dv, wpi->defbase_tot, change, wpi->defbase_sel);
936
937         if (dv_mirr != NULL) {
938                 multipaint_apply_change(dv_mirr, wpi->defbase_tot, change_mirr, wpi->defbase_sel);
939         }
940
941         /* normalize */
942         if (wpi->do_auto_normalize) {
943                 do_weight_paint_normalize_all_locked_try_active(
944                         dv, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags, wpi->active.lock);
945
946                 if (dv_mirr != NULL) {
947                         do_weight_paint_normalize_all_locked_try_active(
948                                 dv_mirr, wpi->defbase_tot, wpi->vgroup_validmap, wpi->lock_flags, wpi->active.lock);
949                 }
950         }
951 }
952
953 static void do_weight_paint_vertex(
954         /* vars which remain the same for every vert */
955         const VPaint *wp, Object *ob, const WeightPaintInfo *wpi,
956         /* vars which change on each stroke */
957         const uint index, float alpha, float paintweight)
958 {
959         if (wpi->do_multipaint) {
960                 do_weight_paint_vertex_multi(wp, ob, wpi, index, alpha, paintweight);
961         }
962         else {
963                 do_weight_paint_vertex_single(wp, ob, wpi, index, alpha, paintweight);
964         }
965 }
966
967
968 /* Toggle operator for turning vertex paint mode on or off (copied from sculpt.c) */
969 static void vertex_paint_init_session(Depsgraph *depsgraph, Scene *scene, Object *ob)
970 {
971         /* Create persistent sculpt mode data */
972         BKE_sculpt_toolsettings_data_ensure(scene);
973
974         if (ob->sculpt == NULL) {
975                 ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
976                 BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, 0, false);
977         }
978 }
979
980 static void vertex_paint_init_session_data(const ToolSettings *ts, Object *ob)
981 {
982         /* Create maps */
983         struct SculptVertexPaintGeomMap *gmap = NULL;
984         const Brush *brush = NULL;
985         if (ob->mode == OB_MODE_VERTEX_PAINT) {
986                 gmap = &ob->sculpt->mode.vpaint.gmap;
987                 brush = BKE_paint_brush(&ts->vpaint->paint);
988                 ob->sculpt->mode_type = OB_MODE_VERTEX_PAINT;
989         }
990         else if (ob->mode == OB_MODE_WEIGHT_PAINT) {
991                 gmap = &ob->sculpt->mode.wpaint.gmap;
992                 brush = BKE_paint_brush(&ts->wpaint->paint);
993                 ob->sculpt->mode_type = OB_MODE_WEIGHT_PAINT;
994         }
995         else {
996                 ob->sculpt->mode_type = 0;
997                 BLI_assert(0);
998                 return;
999         }
1000
1001         Mesh *me = ob->data;
1002
1003         if (gmap->vert_to_loop == NULL) {
1004                 gmap->vert_map_mem = NULL;
1005                 gmap->vert_to_loop = NULL;
1006                 gmap->poly_map_mem = NULL;
1007                 gmap->vert_to_poly = NULL;
1008                 BKE_mesh_vert_loop_map_create(
1009                         &gmap->vert_to_loop,
1010                         &gmap->vert_map_mem,
1011                         me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
1012                 BKE_mesh_vert_poly_map_create(
1013                         &gmap->vert_to_poly,
1014                         &gmap->poly_map_mem,
1015                         me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop);
1016         }
1017
1018         /* Create average brush arrays */
1019         if (ob->mode == OB_MODE_VERTEX_PAINT) {
1020                 if (!brush_use_accumulate(brush)) {
1021                         if (ob->sculpt->mode.vpaint.previous_color == NULL) {
1022                                 ob->sculpt->mode.vpaint.previous_color =
1023                                         MEM_callocN(me->totloop * sizeof(uint), __func__);
1024                         }
1025                 }
1026                 else {
1027                         MEM_SAFE_FREE(ob->sculpt->mode.vpaint.previous_color);
1028                 }
1029         }
1030         else if (ob->mode == OB_MODE_WEIGHT_PAINT) {
1031                 if (!brush_use_accumulate(brush)) {
1032                         if (ob->sculpt->mode.wpaint.alpha_weight == NULL) {
1033                                 ob->sculpt->mode.wpaint.alpha_weight =
1034                                         MEM_callocN(me->totvert * sizeof(float), __func__);
1035                         }
1036                         if (ob->sculpt->mode.wpaint.dvert_prev == NULL) {
1037                                 ob->sculpt->mode.wpaint.dvert_prev =
1038                                         MEM_callocN(me->totvert * sizeof(MDeformVert), __func__);
1039                                 MDeformVert *dv = ob->sculpt->mode.wpaint.dvert_prev;
1040                                 for (int i = 0; i < me->totvert; i++, dv++) {
1041                                         /* Use to show this isn't initialized, never apply to the mesh data. */
1042                                         dv->flag = 1;
1043                                 }
1044                         }
1045                 }
1046                 else {
1047                         MEM_SAFE_FREE(ob->sculpt->mode.wpaint.alpha_weight);
1048                         if (ob->sculpt->mode.wpaint.dvert_prev != NULL) {
1049                                 BKE_defvert_array_free_elems(ob->sculpt->mode.wpaint.dvert_prev, me->totvert);
1050                                 MEM_freeN(ob->sculpt->mode.wpaint.dvert_prev);
1051                                 ob->sculpt->mode.wpaint.dvert_prev = NULL;
1052                         }
1053                 }
1054         }
1055
1056 }
1057
1058 /* -------------------------------------------------------------------- */
1059 /** \name Enter Vertex/Weight Paint Mode
1060  * \{ */
1061
1062 static void ed_vwpaintmode_enter_generic(
1063         Depsgraph *depsgraph, wmWindowManager *wm, Scene *scene,
1064         Object *ob, const eObjectMode mode_flag)
1065 {
1066         ob->mode |= mode_flag;
1067         Mesh *me = BKE_mesh_from_object(ob);
1068
1069         if (mode_flag == OB_MODE_VERTEX_PAINT) {
1070                 const ePaintMode paint_mode = ePaintVertex;
1071                 ED_mesh_color_ensure(me, NULL);
1072
1073                 if (scene->toolsettings->vpaint == NULL) {
1074                         scene->toolsettings->vpaint = new_vpaint();
1075                 }
1076
1077                 Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);
1078                 paint_cursor_start_explicit(paint, wm, vertex_paint_poll);
1079                 BKE_paint_init(scene, paint_mode, PAINT_CURSOR_VERTEX_PAINT);
1080         }
1081         else if (mode_flag == OB_MODE_WEIGHT_PAINT) {
1082                 const  ePaintMode paint_mode = ePaintWeight;
1083
1084                 if (scene->toolsettings->wpaint == NULL) {
1085                         scene->toolsettings->wpaint = new_vpaint();
1086                 }
1087
1088                 Paint *paint = BKE_paint_get_active_from_paintmode(scene, paint_mode);
1089                 paint_cursor_start_explicit(paint, wm, weight_paint_poll);
1090                 BKE_paint_init(scene, paint_mode, PAINT_CURSOR_WEIGHT_PAINT);
1091
1092                 /* weight paint specific */
1093                 ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 's');
1094                 ED_vgroup_sync_from_pose(ob);
1095         }
1096         else {
1097                 BLI_assert(0);
1098         }
1099
1100         /* Create vertex/weight paint mode session data */
1101         if (ob->sculpt) {
1102                 if (ob->sculpt->cache) {
1103                         sculpt_cache_free(ob->sculpt->cache);
1104                         ob->sculpt->cache = NULL;
1105                 }
1106                 BKE_sculptsession_free(ob);
1107         }
1108
1109         vertex_paint_init_session(depsgraph, scene, ob);
1110 }
1111
1112 void ED_object_vpaintmode_enter_ex(
1113         Depsgraph *depsgraph, wmWindowManager *wm,
1114         Scene *scene, Object *ob)
1115 {
1116         ed_vwpaintmode_enter_generic(
1117                 depsgraph, wm, scene, ob, OB_MODE_VERTEX_PAINT);
1118 }
1119 void ED_object_vpaintmode_enter(struct bContext *C)
1120 {
1121         Depsgraph *depsgraph = CTX_data_depsgraph(C);
1122         wmWindowManager *wm = CTX_wm_manager(C);
1123         Scene *scene = CTX_data_scene(C);
1124         Object *ob = CTX_data_active_object(C);
1125         ED_object_vpaintmode_enter_ex(depsgraph, wm, scene, ob);
1126 }
1127
1128 void ED_object_wpaintmode_enter_ex(
1129         Depsgraph *depsgraph, wmWindowManager *wm,
1130         Scene *scene, Object *ob)
1131 {
1132         ed_vwpaintmode_enter_generic(
1133                 depsgraph, wm, scene, ob, OB_MODE_WEIGHT_PAINT);
1134 }
1135 void ED_object_wpaintmode_enter(struct bContext *C)
1136 {
1137         Depsgraph *depsgraph = CTX_data_depsgraph(C);
1138         wmWindowManager *wm = CTX_wm_manager(C);
1139         Scene *scene = CTX_data_scene(C);
1140         Object *ob = CTX_data_active_object(C);
1141         ED_object_wpaintmode_enter_ex(depsgraph, wm, scene, ob);
1142 }
1143
1144 /** \} */
1145
1146 /* -------------------------------------------------------------------- */
1147 /** \name Exit Vertex/Weight Paint Mode
1148  * \{ */
1149
1150 static void ed_vwpaintmode_exit_generic(
1151         Object *ob, const eObjectMode mode_flag)
1152 {
1153         Mesh *me = BKE_mesh_from_object(ob);
1154         ob->mode &= ~mode_flag;
1155
1156         if (mode_flag == OB_MODE_VERTEX_PAINT) {
1157                 if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
1158                         BKE_mesh_flush_select_from_polys(me);
1159                 }
1160                 else if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
1161                         BKE_mesh_flush_select_from_verts(me);
1162                 }
1163         }
1164         else if (mode_flag == OB_MODE_WEIGHT_PAINT) {
1165                 if (me->editflag & ME_EDIT_PAINT_VERT_SEL) {
1166                         BKE_mesh_flush_select_from_verts(me);
1167                 }
1168                 else if (me->editflag & ME_EDIT_PAINT_FACE_SEL) {
1169                         BKE_mesh_flush_select_from_polys(me);
1170                 }
1171         }
1172         else {
1173                 BLI_assert(0);
1174         }
1175
1176         /* If the cache is not released by a cancel or a done, free it now. */
1177         if (ob->sculpt && ob->sculpt->cache) {
1178                 sculpt_cache_free(ob->sculpt->cache);
1179                 ob->sculpt->cache = NULL;
1180         }
1181
1182         BKE_sculptsession_free(ob);
1183
1184         paint_cursor_delete_textures();
1185
1186         if (mode_flag == OB_MODE_WEIGHT_PAINT) {
1187                 ED_mesh_mirror_spatial_table(NULL, NULL, NULL, NULL, 'e');
1188                 ED_mesh_mirror_topo_table(NULL, NULL, 'e');
1189         }
1190 }
1191
1192 void ED_object_vpaintmode_exit_ex(Object *ob)
1193 {
1194         ed_vwpaintmode_exit_generic(ob, OB_MODE_VERTEX_PAINT);
1195 }
1196 void ED_object_vpaintmode_exit(struct bContext *C)
1197 {
1198         Object *ob = CTX_data_active_object(C);
1199         ED_object_vpaintmode_exit_ex(ob);
1200 }
1201
1202 void ED_object_wpaintmode_exit_ex(Object *ob)
1203 {
1204         ed_vwpaintmode_exit_generic(ob, OB_MODE_WEIGHT_PAINT);
1205 }
1206 void ED_object_wpaintmode_exit(struct bContext *C)
1207 {
1208         Object *ob = CTX_data_active_object(C);
1209         ED_object_wpaintmode_exit_ex(ob);
1210 }
1211
1212 /** \} */
1213
1214 /* *************** set wpaint operator ****************** */
1215
1216 /**
1217  * \note Keep in sync with #vpaint_mode_toggle_exec
1218  */
1219 static int wpaint_mode_toggle_exec(bContext *C, wmOperator *op)
1220 {
1221         struct wmMsgBus *mbus = CTX_wm_message_bus(C);
1222         Object *ob = CTX_data_active_object(C);
1223         const int mode_flag = OB_MODE_WEIGHT_PAINT;
1224         const bool is_mode_set = (ob->mode & mode_flag) != 0;
1225         Scene *scene = CTX_data_scene(C);
1226
1227         if (!is_mode_set) {
1228                 if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
1229                         return OPERATOR_CANCELLED;
1230                 }
1231         }
1232
1233         Mesh *me = BKE_mesh_from_object(ob);
1234
1235         if (is_mode_set) {
1236                 ED_object_wpaintmode_exit_ex(ob);
1237         }
1238         else {
1239                 Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C);
1240                 wmWindowManager *wm = CTX_wm_manager(C);
1241                 ED_object_wpaintmode_enter_ex(depsgraph, wm, scene, ob);
1242         }
1243
1244         /* Weightpaint works by overriding colors in mesh,
1245          * so need to make sure we recalc on enter and
1246          * exit (exit needs doing regardless because we
1247          * should redeform).
1248          */
1249         DEG_id_tag_update(&me->id, 0);
1250
1251         WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
1252
1253         WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode);
1254
1255         WM_toolsystem_update_from_context_view3d(C);
1256
1257         return OPERATOR_FINISHED;
1258 }
1259
1260 /* for switching to/from mode */
1261 static int paint_poll_test(bContext *C)
1262 {
1263         Object *ob = CTX_data_active_object(C);
1264         if (ob == NULL || ob->type != OB_MESH)
1265                 return 0;
1266         if (!ob->data || ID_IS_LINKED(ob->data))
1267                 return 0;
1268         if (CTX_data_edit_object(C))
1269                 return 0;
1270         return 1;
1271 }
1272
1273 void PAINT_OT_weight_paint_toggle(wmOperatorType *ot)
1274 {
1275
1276         /* identifiers */
1277         ot->name = "Weight Paint Mode";
1278         ot->idname = "PAINT_OT_weight_paint_toggle";
1279         ot->description = "Toggle weight paint mode in 3D view";
1280
1281         /* api callbacks */
1282         ot->exec = wpaint_mode_toggle_exec;
1283         ot->poll = paint_poll_test;
1284
1285         /* flags */
1286         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1287 }
1288
1289 /* ************ weight paint operator ********** */
1290
1291 struct WPaintData {
1292         ViewContext vc;
1293         struct NormalAnglePrecalc normal_angle_precalc;
1294
1295         struct WeightPaintGroupData active, mirror;
1296
1297         /* variables for auto normalize */
1298         const bool *vgroup_validmap; /* stores if vgroups tie to deforming bones or not */
1299         const bool *lock_flags;
1300
1301         /* variables for multipaint */
1302         const bool *defbase_sel;      /* set of selected groups */
1303         int defbase_tot_sel;          /* number of selected groups */
1304         bool do_multipaint;           /* true if multipaint enabled and multiple groups selected */
1305
1306         int defbase_tot;
1307
1308         /* original weight values for use in blur/smear */
1309         float *precomputed_weight;
1310         bool precomputed_weight_ready;
1311 };
1312
1313 /* Initialize the stroke cache invariants from operator properties */
1314 static void vwpaint_update_cache_invariants(
1315         bContext *C, const VPaint *vp, SculptSession *ss, wmOperator *op, const float mouse[2])
1316 {
1317         StrokeCache *cache;
1318         Scene *scene = CTX_data_scene(C);
1319         UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
1320         const Brush *brush = vp->paint.brush;
1321         ViewContext *vc = paint_stroke_view_context(op->customdata);
1322         Object *ob = CTX_data_active_object(C);
1323         float mat[3][3];
1324         float view_dir[3] = {0.0f, 0.0f, 1.0f};
1325         int mode;
1326
1327         /* VW paint needs to allocate stroke cache before update is called. */
1328         if (!ss->cache) {
1329                 cache = MEM_callocN(sizeof(StrokeCache), "stroke cache");
1330                 ss->cache = cache;
1331         }
1332         else {
1333                 cache = ss->cache;
1334         }
1335
1336         /* Initial mouse location */
1337         if (mouse)
1338                 copy_v2_v2(cache->initial_mouse, mouse);
1339         else
1340                 zero_v2(cache->initial_mouse);
1341
1342         mode = RNA_enum_get(op->ptr, "mode");
1343         cache->invert = mode == BRUSH_STROKE_INVERT;
1344         cache->alt_smooth = mode == BRUSH_STROKE_SMOOTH;
1345         /* not very nice, but with current events system implementation
1346          * we can't handle brush appearance inversion hotkey separately (sergey) */
1347         if (cache->invert) ups->draw_inverted = true;
1348         else ups->draw_inverted = false;
1349
1350         copy_v2_v2(cache->mouse, cache->initial_mouse);
1351         /* Truly temporary data that isn't stored in properties */
1352         cache->vc = vc;
1353         cache->brush = brush;
1354         cache->first_time = 1;
1355
1356         /* cache projection matrix */
1357         ED_view3d_ob_project_mat_get(cache->vc->rv3d, ob, cache->projection_mat);
1358
1359         invert_m4_m4(ob->imat, ob->obmat);
1360         copy_m3_m4(mat, cache->vc->rv3d->viewinv);
1361         mul_m3_v3(mat, view_dir);
1362         copy_m3_m4(mat, ob->imat);
1363         mul_m3_v3(mat, view_dir);
1364         normalize_v3_v3(cache->true_view_normal, view_dir);
1365
1366         copy_v3_v3(cache->view_normal, cache->true_view_normal);
1367         cache->bstrength = BKE_brush_alpha_get(scene, brush);
1368         cache->is_last_valid = false;
1369 }
1370
1371 /* Initialize the stroke cache variants from operator properties */
1372 static void vwpaint_update_cache_variants(bContext *C, VPaint *vp, Object *ob, PointerRNA *ptr)
1373 {
1374         Scene *scene = CTX_data_scene(C);
1375         SculptSession *ss = ob->sculpt;
1376         StrokeCache *cache = ss->cache;
1377         Brush *brush = BKE_paint_brush(&vp->paint);
1378
1379         /* This effects the actual brush radius, so things farther away
1380          * are compared with a larger radius and vise versa. */
1381         if (cache->first_time) {
1382                 RNA_float_get_array(ptr, "location", cache->true_location);
1383         }
1384
1385         RNA_float_get_array(ptr, "mouse", cache->mouse);
1386
1387         /* XXX: Use pressure value from first brush step for brushes which don't
1388          * support strokes (grab, thumb). They depends on initial state and
1389          * brush coord/pressure/etc.
1390          * It's more an events design issue, which doesn't split coordinate/pressure/angle
1391          * changing events. We should avoid this after events system re-design */
1392         if (paint_supports_dynamic_size(brush, ePaintSculpt) || cache->first_time) {
1393                 cache->pressure = RNA_float_get(ptr, "pressure");
1394         }
1395
1396         /* Truly temporary data that isn't stored in properties */
1397         if (cache->first_time) {
1398                 if (!BKE_brush_use_locked_size(scene, brush)) {
1399                         cache->initial_radius = paint_calc_object_space_radius(
1400                                 cache->vc, cache->true_location, BKE_brush_size_get(scene, brush));
1401                         BKE_brush_unprojected_radius_set(scene, brush, cache->initial_radius);
1402                 }
1403                 else {
1404                         cache->initial_radius = BKE_brush_unprojected_radius_get(scene, brush);
1405                 }
1406         }
1407
1408         if (BKE_brush_use_size_pressure(scene, brush) && paint_supports_dynamic_size(brush, ePaintSculpt)) {
1409                 cache->radius = cache->initial_radius * cache->pressure;
1410         }
1411         else {
1412                 cache->radius = cache->initial_radius;
1413         }
1414
1415         cache->radius_squared = cache->radius * cache->radius;
1416
1417         if (ss->pbvh) {
1418                 BKE_pbvh_update(ss->pbvh, PBVH_UpdateRedraw, NULL);
1419                 BKE_pbvh_update(ss->pbvh, PBVH_UpdateBB, NULL);
1420         }
1421 }
1422
1423 static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mouse[2])
1424 {
1425         Scene *scene = CTX_data_scene(C);
1426         struct PaintStroke *stroke = op->customdata;
1427         ToolSettings *ts = scene->toolsettings;
1428         Object *ob = CTX_data_active_object(C);
1429         Mesh *me = BKE_mesh_from_object(ob);
1430         struct WPaintData *wpd;
1431         struct WPaintVGroupIndex vgroup_index;
1432         int defbase_tot, defbase_tot_sel;
1433         bool *defbase_sel;
1434         SculptSession *ss = ob->sculpt;
1435         VPaint *vp = CTX_data_tool_settings(C)->wpaint;
1436         Depsgraph *depsgraph = CTX_data_depsgraph(C);
1437
1438         if (ED_wpaint_ensure_data(C, op->reports, WPAINT_ENSURE_MIRROR, &vgroup_index) == false) {
1439                 return false;
1440         }
1441
1442         {
1443                 /* check if we are attempting to paint onto a locked vertex group,
1444                  * and other options disallow it from doing anything useful */
1445                 bDeformGroup *dg;
1446                 dg = BLI_findlink(&ob->defbase, vgroup_index.active);
1447                 if (dg->flag & DG_LOCK_WEIGHT) {
1448                         BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting");
1449                         return false;
1450                 }
1451                 if (vgroup_index.mirror != -1) {
1452                         dg = BLI_findlink(&ob->defbase, vgroup_index.mirror);
1453                         if (dg->flag & DG_LOCK_WEIGHT) {
1454                                 BKE_report(op->reports, RPT_WARNING, "Mirror group is locked, aborting");
1455                                 return false;
1456                         }
1457                 }
1458         }
1459
1460         /* check that multipaint groups are unlocked */
1461         defbase_tot = BLI_listbase_count(&ob->defbase);
1462         defbase_sel = BKE_object_defgroup_selected_get(ob, defbase_tot, &defbase_tot_sel);
1463
1464         if (ts->multipaint && defbase_tot_sel > 1) {
1465                 int i;
1466                 bDeformGroup *dg;
1467
1468                 if (me->editflag & ME_EDIT_MIRROR_X) {
1469                         BKE_object_defgroup_mirror_selection(ob, defbase_tot, defbase_sel, defbase_sel, &defbase_tot_sel);
1470                 }
1471
1472                 for (i = 0; i < defbase_tot; i++) {
1473                         if (defbase_sel[i]) {
1474                                 dg = BLI_findlink(&ob->defbase, i);
1475                                 if (dg->flag & DG_LOCK_WEIGHT) {
1476                                         BKE_report(op->reports, RPT_WARNING, "Multipaint group is locked, aborting");
1477                                         MEM_freeN(defbase_sel);
1478                                         return false;
1479                                 }
1480                         }
1481                 }
1482         }
1483
1484         /* ALLOCATIONS! no return after this line */
1485         /* make mode data storage */
1486         wpd = MEM_callocN(sizeof(struct WPaintData), "WPaintData");
1487         paint_stroke_set_mode_data(stroke, wpd);
1488         ED_view3d_viewcontext_init(C, &wpd->vc);
1489         view_angle_limits_init(&wpd->normal_angle_precalc, vp->paint.brush->falloff_angle,
1490                                (vp->paint.brush->flag & BRUSH_FRONTFACE_FALLOFF) != 0);
1491
1492         wpd->active.index = vgroup_index.active;
1493         wpd->mirror.index = vgroup_index.mirror;
1494
1495         /* multipaint */
1496         wpd->defbase_tot = defbase_tot;
1497         wpd->defbase_sel = defbase_sel;
1498         wpd->defbase_tot_sel = defbase_tot_sel > 1 ? defbase_tot_sel : 1;
1499         wpd->do_multipaint = (ts->multipaint && defbase_tot_sel > 1);
1500
1501         /* set up auto-normalize, and generate map for detecting which
1502          * vgroups affect deform bones */
1503         wpd->lock_flags = BKE_object_defgroup_lock_flags_get(ob, wpd->defbase_tot);
1504         if (ts->auto_normalize || ts->multipaint || wpd->lock_flags) {
1505                 wpd->vgroup_validmap = BKE_object_defgroup_validmap_get(ob, wpd->defbase_tot);
1506         }
1507
1508         if (wpd->do_multipaint && ts->auto_normalize) {
1509                 bool *tmpflags;
1510                 tmpflags = MEM_mallocN(sizeof(bool) * defbase_tot, __func__);
1511                 if (wpd->lock_flags) {
1512                         BLI_array_binary_or(tmpflags, wpd->defbase_sel, wpd->lock_flags, wpd->defbase_tot);
1513                 }
1514                 else {
1515                         memcpy(tmpflags, wpd->defbase_sel, sizeof(*tmpflags) * wpd->defbase_tot);
1516                 }
1517                 wpd->active.lock = tmpflags;
1518         }
1519         else if (ts->auto_normalize) {
1520                 bool *tmpflags;
1521
1522                 tmpflags = wpd->lock_flags ?
1523                         MEM_dupallocN(wpd->lock_flags) :
1524                         MEM_callocN(sizeof(bool) * defbase_tot, __func__);
1525                 tmpflags[wpd->active.index] = true;
1526                 wpd->active.lock = tmpflags;
1527
1528                 tmpflags = wpd->lock_flags ?
1529                         MEM_dupallocN(wpd->lock_flags) :
1530                         MEM_callocN(sizeof(bool) * defbase_tot, __func__);
1531                 tmpflags[(wpd->mirror.index != -1) ? wpd->mirror.index : wpd->active.index] = true;
1532                 wpd->mirror.lock = tmpflags;
1533         }
1534
1535         if (ELEM(vp->paint.brush->vertexpaint_tool, PAINT_BLEND_SMEAR, PAINT_BLEND_BLUR)) {
1536                 wpd->precomputed_weight = MEM_mallocN(sizeof(float) * me->totvert, __func__);
1537         }
1538
1539         /* If not previously created, create vertex/weight paint mode session data */
1540         vertex_paint_init_session(depsgraph, scene, ob);
1541         vwpaint_update_cache_invariants(C, vp, ss, op, mouse);
1542         vertex_paint_init_session_data(ts, ob);
1543
1544         if (ob->sculpt->mode.wpaint.dvert_prev != NULL) {
1545                 MDeformVert *dv = ob->sculpt->mode.wpaint.dvert_prev;
1546                 for (int i = 0; i < me->totvert; i++, dv++) {
1547                         /* Use to show this isn't initialized, never apply to the mesh data. */
1548                         dv->flag = 1;
1549                 }
1550         }
1551
1552         return true;
1553 }
1554
1555 static float dot_vf3vs3(const float brushNormal[3], const short vertexNormal[3])
1556 {
1557         float normal[3];
1558         normal_short_to_float_v3(normal, vertexNormal);
1559         return dot_v3v3(brushNormal, normal);
1560 }
1561
1562 static void get_brush_alpha_data(
1563         const Scene *scene, const SculptSession *ss, const Brush *brush,
1564         float *r_brush_size_pressure, float *r_brush_alpha_value, float *r_brush_alpha_pressure)
1565 {
1566         *r_brush_size_pressure =
1567                 BKE_brush_size_get(scene, brush) *
1568                 (BKE_brush_use_size_pressure(scene, brush) ? ss->cache->pressure : 1.0f);
1569         *r_brush_alpha_value =
1570                 BKE_brush_alpha_get(scene, brush);
1571         *r_brush_alpha_pressure =
1572                 (BKE_brush_use_alpha_pressure(scene, brush) ? ss->cache->pressure : 1.0f);
1573 }
1574
1575 static float wpaint_get_active_weight(const MDeformVert *dv, const WeightPaintInfo *wpi)
1576 {
1577         if (wpi->do_multipaint) {
1578                 float weight = BKE_defvert_multipaint_collective_weight(
1579                      dv, wpi->defbase_tot, wpi->defbase_sel, wpi->defbase_tot_sel, wpi->do_auto_normalize);
1580
1581                 CLAMP(weight, 0.0f, 1.0f);
1582                 return weight;
1583         }
1584         else {
1585                 return defvert_find_weight(dv, wpi->active.index);
1586         }
1587 }
1588
1589 static void do_wpaint_precompute_weight_cb_ex(
1590         void *__restrict userdata,
1591         const int n,
1592         const ParallelRangeTLS *__restrict UNUSED(tls))
1593 {
1594         SculptThreadedTaskData *data = userdata;
1595         const MDeformVert *dv = &data->me->dvert[n];
1596
1597         data->wpd->precomputed_weight[n] = wpaint_get_active_weight(dv, data->wpi);
1598 }
1599
1600 static void precompute_weight_values(
1601         bContext *C, Object *ob, Brush *brush, struct WPaintData *wpd, WeightPaintInfo *wpi, Mesh *me)
1602 {
1603         if (wpd->precomputed_weight_ready && !brush_use_accumulate(brush))
1604                 return;
1605
1606         /* threaded loop over vertices */
1607         SculptThreadedTaskData data = {
1608                 .C = C, .ob = ob, .wpd = wpd, .wpi = wpi, .me = me,
1609         };
1610
1611         ParallelRangeSettings settings;
1612         BLI_parallel_range_settings_defaults(&settings);
1613         BLI_task_parallel_range(
1614                 0, me->totvert,
1615                 &data,
1616                 do_wpaint_precompute_weight_cb_ex,
1617                 &settings);
1618
1619         wpd->precomputed_weight_ready = true;
1620 }
1621
1622 static void do_wpaint_brush_blur_task_cb_ex(
1623         void *__restrict userdata,
1624         const int n,
1625         const ParallelRangeTLS *__restrict UNUSED(tls))
1626 {
1627         SculptThreadedTaskData *data = userdata;
1628         SculptSession *ss = data->ob->sculpt;
1629         CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
1630         const struct SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap;
1631
1632         const Brush *brush = data->brush;
1633         const StrokeCache *cache = ss->cache;
1634         Scene *scene = CTX_data_scene(data->C);
1635
1636         float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1637         get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1638         const bool use_normal = vwpaint_use_normal(data->vp);
1639         const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
1640         const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
1641
1642         SculptBrushTest test;
1643         SculptBrushTestFn sculpt_brush_test_sq_fn =
1644                 sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape);
1645         const float *sculpt_normal_frontface =
1646                 sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape);
1647
1648         /* For each vertex */
1649         PBVHVertexIter vd;
1650         BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
1651         {
1652                 /* Test to see if the vertex coordinates are within the spherical brush region. */
1653                 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
1654                         /* For grid based pbvh, take the vert whose loop coopresponds to the current grid.
1655                          * Otherwise, take the current vert. */
1656                         const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
1657                         const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
1658                         const char v_flag = data->me->mvert[v_index].flag;
1659                         /* If the vertex is selected */
1660                         if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
1661                                 /* Get the average poly weight */
1662                                 int total_hit_loops = 0;
1663                                 float weight_final = 0.0f;
1664                                 for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
1665                                         const int p_index = gmap->vert_to_poly[v_index].indices[j];
1666                                         const MPoly *mp = &data->me->mpoly[p_index];
1667
1668                                         total_hit_loops += mp->totloop;
1669                                         for (int k = 0; k < mp->totloop; k++) {
1670                                                 const int l_index = mp->loopstart + k;
1671                                                 const MLoop *ml = &data->me->mloop[l_index];
1672                                                 weight_final += data->wpd->precomputed_weight[ml->v];
1673                                         }
1674                                 }
1675
1676                                 /* Apply the weight to the vertex. */
1677                                 if (total_hit_loops != 0) {
1678                                         float brush_strength = cache->bstrength;
1679                                         const float angle_cos = (use_normal && vd.no) ?
1680                                                 dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f;
1681                                         if (((brush->flag & BRUSH_FRONTFACE) == 0 ||
1682                                              (angle_cos > 0.0f)) &&
1683                                             ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 ||
1684                                              view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength)))
1685                                         {
1686                                                 const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
1687                                                 const float final_alpha =
1688                                                         brush_fade * brush_strength *
1689                                                         grid_alpha * brush_alpha_pressure;
1690
1691                                                 if ((brush->flag & BRUSH_ACCUMULATE) == 0) {
1692                                                         if (ss->mode.wpaint.alpha_weight[v_index] < final_alpha) {
1693                                                                 ss->mode.wpaint.alpha_weight[v_index] = final_alpha;
1694                                                         }
1695                                                         else {
1696                                                                 continue;
1697                                                         }
1698                                                 }
1699
1700                                                 weight_final /= total_hit_loops;
1701                                                 /* Only paint visable verts */
1702                                                 do_weight_paint_vertex(
1703                                                         data->vp, data->ob, data->wpi,
1704                                                         v_index, final_alpha, weight_final);
1705                                         }
1706                                 }
1707                         }
1708                 }
1709         }
1710         BKE_pbvh_vertex_iter_end;
1711 }
1712
1713 static void do_wpaint_brush_smear_task_cb_ex(
1714         void *__restrict userdata,
1715         const int n,
1716         const ParallelRangeTLS *__restrict UNUSED(tls))
1717 {
1718         SculptThreadedTaskData *data = userdata;
1719         SculptSession *ss = data->ob->sculpt;
1720         CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
1721         const struct SculptVertexPaintGeomMap *gmap = &ss->mode.wpaint.gmap;
1722
1723         const Brush *brush = data->brush;
1724         const Scene *scene = CTX_data_scene(data->C);
1725         const StrokeCache *cache = ss->cache;
1726         float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1727         get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1728         const bool use_normal = vwpaint_use_normal(data->vp);
1729         const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
1730         const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
1731         float brush_dir[3];
1732
1733         sub_v3_v3v3(brush_dir, cache->location, cache->last_location);
1734         project_plane_v3_v3v3(brush_dir, brush_dir, cache->view_normal);
1735
1736         if (cache->is_last_valid && (normalize_v3(brush_dir) != 0.0f)) {
1737
1738                 SculptBrushTest test;
1739                 SculptBrushTestFn sculpt_brush_test_sq_fn =
1740                         sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape);
1741                 const float *sculpt_normal_frontface =
1742                         sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape);
1743
1744                 /* For each vertex */
1745                 PBVHVertexIter vd;
1746                 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
1747                 {
1748                         /* Test to see if the vertex coordinates are within the spherical brush region. */
1749                         if (sculpt_brush_test_sq_fn(&test, vd.co)) {
1750                                 /* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
1751                                  * Otherwise, take the current vert. */
1752                                 const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
1753                                 const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
1754                                 const MVert *mv_curr = &data->me->mvert[v_index];
1755
1756                                 /* If the vertex is selected */
1757                                 if (!(use_face_sel || use_vert_sel) || mv_curr->flag & SELECT) {
1758                                         float brush_strength = cache->bstrength;
1759                                         const float angle_cos = (use_normal && vd.no) ?
1760                                                 dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f;
1761                                         if (((brush->flag & BRUSH_FRONTFACE) == 0 ||
1762                                              (angle_cos > 0.0f)) &&
1763                                             ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 ||
1764                                              view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength)))
1765                                         {
1766                                                 bool do_color = false;
1767                                                 /* Minimum dot product between brush direction and current
1768                                                  * to neighbor direction is 0.0, meaning orthogonal. */
1769                                                 float stroke_dot_max = 0.0f;
1770
1771                                                 /* Get the color of the loop in the opposite direction of the brush movement
1772                                                  * (this callback is specifically for smear.) */
1773                                                 float weight_final = 0.0;
1774                                                 for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
1775                                                         const int p_index = gmap->vert_to_poly[v_index].indices[j];
1776                                                         const MPoly *mp = &data->me->mpoly[p_index];
1777                                                         const MLoop *ml_other = &data->me->mloop[mp->loopstart];
1778                                                         for (int k = 0; k < mp->totloop; k++, ml_other++) {
1779                                                                 const uint v_other_index = ml_other->v;
1780                                                                 if (v_other_index != v_index) {
1781                                                                         const MVert *mv_other = &data->me->mvert[v_other_index];
1782
1783                                                                         /* Get the direction from the selected vert to the neighbor. */
1784                                                                         float other_dir[3];
1785                                                                         sub_v3_v3v3(other_dir, mv_curr->co, mv_other->co);
1786                                                                         project_plane_v3_v3v3(other_dir, other_dir, cache->view_normal);
1787
1788                                                                         normalize_v3(other_dir);
1789
1790                                                                         const float stroke_dot = dot_v3v3(other_dir, brush_dir);
1791
1792                                                                         if (stroke_dot > stroke_dot_max) {
1793                                                                                 stroke_dot_max = stroke_dot;
1794                                                                                 weight_final = data->wpd->precomputed_weight[v_other_index];
1795                                                                                 do_color = true;
1796                                                                         }
1797                                                                 }
1798                                                         }
1799                                                 }
1800                                                 /* Apply weight to vertex */
1801                                                 if (do_color) {
1802                                                         const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
1803                                                         const float final_alpha =
1804                                                                 brush_fade * brush_strength *
1805                                                                 grid_alpha * brush_alpha_pressure;
1806
1807                                                         if (final_alpha <= 0.0f)
1808                                                                 continue;
1809
1810                                                         do_weight_paint_vertex(
1811                                                                 data->vp, data->ob, data->wpi,
1812                                                                 v_index, final_alpha, (float)weight_final);
1813                                                 }
1814                                         }
1815                                 }
1816                         }
1817                 }
1818                 BKE_pbvh_vertex_iter_end;
1819         }
1820 }
1821
1822 static void do_wpaint_brush_draw_task_cb_ex(
1823         void *__restrict userdata,
1824         const int n,
1825         const ParallelRangeTLS *__restrict UNUSED(tls))
1826 {
1827         SculptThreadedTaskData *data = userdata;
1828         SculptSession *ss = data->ob->sculpt;
1829         CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
1830         const Scene *scene = CTX_data_scene(data->C);
1831
1832         const Brush *brush = data->brush;
1833         const StrokeCache *cache = ss->cache;
1834         /* note: normally `BKE_brush_weight_get(scene, brush)` is used,
1835          * however in this case we calculate a new weight each time. */
1836         const float paintweight = data->strength;
1837         float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
1838         get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
1839         const bool use_normal = vwpaint_use_normal(data->vp);
1840         const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
1841         const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
1842
1843         SculptBrushTest test;
1844         SculptBrushTestFn sculpt_brush_test_sq_fn =
1845                 sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape);
1846         const float *sculpt_normal_frontface =
1847                 sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape);
1848
1849         /* For each vertex */
1850         PBVHVertexIter vd;
1851         BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
1852         {
1853                 /* Test to see if the vertex coordinates are within the spherical brush region. */
1854                 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
1855                         /* Note: grids are 1:1 with corners (aka loops).
1856                          * For multires, take the vert whose loop cooresponds to the current grid.
1857                          * Otherwise, take the current vert. */
1858                         const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
1859                         const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
1860
1861                         const char v_flag = data->me->mvert[v_index].flag;
1862                         /* If the vertex is selected */
1863                         if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
1864                                 float brush_strength = cache->bstrength;
1865                                 const float angle_cos = (use_normal && vd.no) ?
1866                                         dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f;
1867                                 if (((brush->flag & BRUSH_FRONTFACE) == 0 ||
1868                                      (angle_cos > 0.0f)) &&
1869                                     ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 ||
1870                                      view_angle_limits_apply_falloff(&data->wpd->normal_angle_precalc, angle_cos, &brush_strength)))
1871                                 {
1872                                         const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
1873                                         const float final_alpha = brush_fade * brush_strength * grid_alpha * brush_alpha_pressure;
1874
1875                                         if ((brush->flag & BRUSH_ACCUMULATE) == 0) {
1876                                                 if (ss->mode.wpaint.alpha_weight[v_index] < final_alpha) {
1877                                                         ss->mode.wpaint.alpha_weight[v_index] = final_alpha;
1878                                                 }
1879                                                 else {
1880                                                         continue;
1881                                                 }
1882                                         }
1883
1884                                         do_weight_paint_vertex(
1885                                                 data->vp, data->ob, data->wpi,
1886                                                 v_index, final_alpha, paintweight);
1887                                 }
1888                         }
1889                 }
1890         }
1891         BKE_pbvh_vertex_iter_end;
1892 }
1893
1894 static void do_wpaint_brush_calc_average_weight_cb_ex(
1895         void *__restrict userdata,
1896         const int n,
1897         const ParallelRangeTLS *__restrict UNUSED(tls))
1898 {
1899         SculptThreadedTaskData *data = userdata;
1900         SculptSession *ss = data->ob->sculpt;
1901         StrokeCache *cache = ss->cache;
1902         CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
1903
1904         const bool use_normal = vwpaint_use_normal(data->vp);
1905         const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
1906         const bool use_vert_sel = (data->me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
1907
1908         struct WPaintAverageAccum *accum = (struct WPaintAverageAccum *)data->custom_data + n;
1909         accum->len = 0;
1910         accum->value = 0.0;
1911
1912         SculptBrushTest test;
1913         SculptBrushTestFn sculpt_brush_test_sq_fn =
1914                 sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape);
1915         const float *sculpt_normal_frontface =
1916                 sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape);
1917
1918         /* For each vertex */
1919         PBVHVertexIter vd;
1920         BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
1921         {
1922                 /* Test to see if the vertex coordinates are within the spherical brush region. */
1923                 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
1924                         const float angle_cos = (use_normal && vd.no) ?
1925                                 dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f;
1926                         if (angle_cos > 0.0 && BKE_brush_curve_strength(data->brush, sqrtf(test.dist), cache->radius) > 0.0) {
1927                                 const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
1928                                 // const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
1929                                 const char v_flag = data->me->mvert[v_index].flag;
1930
1931                                 /* If the vertex is selected. */
1932                                 if (!(use_face_sel || use_vert_sel) || v_flag & SELECT) {
1933                                         const MDeformVert *dv = &data->me->dvert[v_index];
1934                                         accum->len += 1;
1935                                         accum->value += wpaint_get_active_weight(dv, data->wpi);
1936                                 }
1937                         }
1938                 }
1939         }
1940         BKE_pbvh_vertex_iter_end;
1941 }
1942
1943 static void calculate_average_weight(SculptThreadedTaskData *data, PBVHNode **UNUSED(nodes), int totnode)
1944 {
1945         struct WPaintAverageAccum *accum = MEM_mallocN(sizeof(*accum) * totnode, __func__);
1946         data->custom_data = accum;
1947
1948         ParallelRangeSettings settings;
1949         BLI_parallel_range_settings_defaults(&settings);
1950         settings.use_threading = ((data->sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
1951         BLI_task_parallel_range(
1952                 0, totnode,
1953                 data,
1954                 do_wpaint_brush_calc_average_weight_cb_ex,
1955                 &settings);
1956
1957         uint accum_len = 0;
1958         double accum_weight = 0.0;
1959         for (int i = 0; i < totnode; i++) {
1960                 accum_len += accum[i].len;
1961                 accum_weight += accum[i].value;
1962         }
1963         if (accum_len != 0) {
1964                 accum_weight /= accum_len;
1965                 data->strength = (float)accum_weight;
1966         }
1967
1968         MEM_SAFE_FREE(data->custom_data);  /* 'accum' */
1969 }
1970
1971
1972 static void wpaint_paint_leaves(
1973         bContext *C, Object *ob, Sculpt *sd, VPaint *vp, struct WPaintData *wpd, WeightPaintInfo *wpi,
1974         Mesh *me, PBVHNode **nodes, int totnode)
1975 {
1976         Scene *scene = CTX_data_scene(C);
1977         const Brush *brush = ob->sculpt->cache->brush;
1978
1979         /* threaded loop over nodes */
1980         SculptThreadedTaskData data = {
1981                  .C = C, .sd = sd, .ob = ob, .brush = brush, .nodes = nodes,
1982                  .vp = vp, .wpd = wpd, .wpi = wpi, .me = me,
1983         };
1984
1985         /* Use this so average can modify its weight without touching the brush. */
1986         data.strength = BKE_brush_weight_get(scene, brush);
1987
1988         ParallelRangeSettings settings;
1989         BLI_parallel_range_settings_defaults(&settings);
1990         /* NOTE: current mirroring code cannot be run in parallel */
1991         settings.use_threading = !(me->editflag & ME_EDIT_MIRROR_X);
1992
1993         switch (brush->vertexpaint_tool) {
1994                 case PAINT_BLEND_AVERAGE:
1995                         calculate_average_weight(&data, nodes, totnode);
1996                         BLI_task_parallel_range(
1997                                 0, totnode,
1998                                 &data,
1999                                 do_wpaint_brush_draw_task_cb_ex,
2000                                 &settings);
2001                         break;
2002                 case PAINT_BLEND_SMEAR:
2003                         BLI_task_parallel_range(
2004                                 0, totnode,
2005                                 &data,
2006                                 do_wpaint_brush_smear_task_cb_ex,
2007                                 &settings);
2008                         break;
2009                 case PAINT_BLEND_BLUR:
2010                         BLI_task_parallel_range(
2011                                 0, totnode,
2012                                 &data,
2013                                 do_wpaint_brush_blur_task_cb_ex,
2014                                 &settings);
2015                         break;
2016                 default:
2017                         BLI_task_parallel_range(
2018                                 0, totnode,
2019                                 &data,
2020                                 do_wpaint_brush_draw_task_cb_ex,
2021                                 &settings);
2022                         break;
2023         }
2024 }
2025
2026 static PBVHNode **vwpaint_pbvh_gather_generic(
2027         Object *ob, VPaint *wp, Sculpt *sd, Brush *brush, int *r_totnode)
2028 {
2029         SculptSession *ss = ob->sculpt;
2030         const bool use_normal = vwpaint_use_normal(wp);
2031         PBVHNode **nodes = NULL;
2032
2033         /* Build a list of all nodes that are potentially within the brush's area of influence */
2034         if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE) {
2035                 SculptSearchSphereData data = {
2036                         .ss = ss,
2037                         .sd = sd,
2038                         .radius_squared = ss->cache->radius_squared,
2039                         .original = true,
2040                 };
2041                 BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, r_totnode);
2042                 if (use_normal) {
2043                         sculpt_pbvh_calc_area_normal(brush, ob, nodes, *r_totnode, true, ss->cache->sculpt_normal_symm);
2044                 }
2045                 else {
2046                         zero_v3(ss->cache->sculpt_normal_symm);
2047                 }
2048         }
2049         else {
2050                 struct DistRayAABB_Precalc dist_ray_to_aabb_precalc;
2051                 dist_squared_ray_to_aabb_v3_precalc(&dist_ray_to_aabb_precalc, ss->cache->location, ss->cache->view_normal);
2052                 SculptSearchCircleData data = {
2053                         .ss = ss,
2054                         .sd = sd,
2055                         .radius_squared = ss->cache->radius_squared,
2056                         .original = true,
2057                         .dist_ray_to_aabb_precalc = &dist_ray_to_aabb_precalc,
2058                 };
2059                 BKE_pbvh_search_gather(ss->pbvh, sculpt_search_circle_cb, &data, &nodes, r_totnode);
2060                 if (use_normal) {
2061                         copy_v3_v3(ss->cache->sculpt_normal_symm, ss->cache->view_normal);
2062                 }
2063                 else {
2064                         zero_v3(ss->cache->sculpt_normal_symm);
2065                 }
2066         }
2067         return nodes;
2068 }
2069
2070 static void wpaint_do_paint(
2071         bContext *C, Object *ob, VPaint *wp, Sculpt *sd, struct WPaintData *wpd, WeightPaintInfo *wpi,
2072         Mesh *me, Brush *brush, const char symm, const int axis, const int i, const float angle)
2073 {
2074         SculptSession *ss = ob->sculpt;
2075         ss->cache->radial_symmetry_pass = i;
2076         sculpt_cache_calc_brushdata_symm(ss->cache, symm, axis, angle);
2077
2078         int totnode;
2079         PBVHNode **nodes = vwpaint_pbvh_gather_generic(ob, wp, sd, brush, &totnode);
2080
2081         wpaint_paint_leaves(C, ob, sd, wp, wpd, wpi, me, nodes, totnode);
2082
2083         if (nodes)
2084                 MEM_freeN(nodes);
2085 }
2086
2087 static void wpaint_do_radial_symmetry(
2088         bContext *C, Object *ob, VPaint *wp, Sculpt *sd, struct WPaintData *wpd, WeightPaintInfo *wpi,
2089         Mesh *me, Brush *brush, const char symm, const int axis)
2090 {
2091         for (int i = 1; i < wp->radial_symm[axis - 'X']; i++) {
2092                 const float angle = (2.0 * M_PI) * i / wp->radial_symm[axis - 'X'];
2093                 wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, symm, axis, i, angle);
2094         }
2095 }
2096
2097 /* near duplicate of: sculpt.c's, 'do_symmetrical_brush_actions' and 'vpaint_do_symmetrical_brush_actions'. */
2098 static void wpaint_do_symmetrical_brush_actions(
2099         bContext *C, Object *ob, VPaint *wp, Sculpt *sd, struct WPaintData *wpd, WeightPaintInfo *wpi)
2100 {
2101         Brush *brush = BKE_paint_brush(&wp->paint);
2102         Mesh *me = ob->data;
2103         SculptSession *ss = ob->sculpt;
2104         StrokeCache *cache = ss->cache;
2105         const char symm = wp->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
2106         int i = 0;
2107
2108         /* initial stroke */
2109         wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, 0, 'X', 0, 0);
2110         wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, 0, 'X');
2111         wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, 0, 'Y');
2112         wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, 0, 'Z');
2113
2114         cache->symmetry = symm;
2115
2116         /* symm is a bit combination of XYZ - 1 is mirror X; 2 is Y; 3 is XY; 4 is Z; 5 is XZ; 6 is YZ; 7 is XYZ */
2117         for (i = 1; i <= symm; i++) {
2118                 if ((symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
2119                         cache->mirror_symmetry_pass = i;
2120                         cache->radial_symmetry_pass = 0;
2121                         sculpt_cache_calc_brushdata_symm(cache, i, 0, 0);
2122
2123                         if (i & (1 << 0)) {
2124                                 wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, i, 'X', 0, 0);
2125                                 wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, i, 'X');
2126                         }
2127                         if (i & (1 << 1)) {
2128                                 wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, i, 'Y', 0, 0);
2129                                 wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, i, 'Y');
2130                         }
2131                         if (i & (1 << 2)) {
2132                                 wpaint_do_paint(C, ob, wp, sd, wpd, wpi, me, brush, i, 'Z', 0, 0);
2133                                 wpaint_do_radial_symmetry(C, ob, wp, sd, wpd, wpi, me, brush, i, 'Z');
2134                         }
2135                 }
2136         }
2137         copy_v3_v3(cache->true_last_location, cache->true_location);
2138         cache->is_last_valid = true;
2139 }
2140
2141 static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
2142 {
2143         Scene *scene = CTX_data_scene(C);
2144         ToolSettings *ts = CTX_data_tool_settings(C);
2145         VPaint *wp = ts->wpaint;
2146         Brush *brush = BKE_paint_brush(&wp->paint);
2147         struct WPaintData *wpd = paint_stroke_mode_data(stroke);
2148         ViewContext *vc;
2149         Object *ob = CTX_data_active_object(C);
2150
2151         SculptSession *ss = ob->sculpt;
2152         Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
2153
2154         vwpaint_update_cache_variants(C, wp, ob, itemptr);
2155
2156         float mat[4][4];
2157         float mval[2];
2158
2159         const float brush_alpha_value = BKE_brush_alpha_get(scene, brush);
2160
2161         /* intentionally don't initialize as NULL, make sure we initialize all members below */
2162         WeightPaintInfo wpi;
2163
2164         /* cannot paint if there is no stroke data */
2165         if (wpd == NULL) {
2166                 /* XXX: force a redraw here, since even though we can't paint,
2167                  * at least view won't freeze until stroke ends */
2168                 ED_region_tag_redraw(CTX_wm_region(C));
2169                 return;
2170         }
2171
2172         vc = &wpd->vc;
2173         ob = vc->obact;
2174
2175         view3d_operator_needs_opengl(C);
2176         ED_view3d_init_mats_rv3d(ob, vc->rv3d);
2177
2178         /* load projection matrix */
2179         mul_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
2180
2181
2182         /* *** setup WeightPaintInfo - pass onto do_weight_paint_vertex *** */
2183         wpi.defbase_tot =        wpd->defbase_tot;
2184         wpi.defbase_sel =        wpd->defbase_sel;
2185         wpi.defbase_tot_sel =    wpd->defbase_tot_sel;
2186
2187         wpi.defbase_tot_unsel =  wpi.defbase_tot - wpi.defbase_tot_sel;
2188         wpi.active =             wpd->active;
2189         wpi.mirror =             wpd->mirror;
2190         wpi.lock_flags =         wpd->lock_flags;
2191         wpi.vgroup_validmap =    wpd->vgroup_validmap;
2192         wpi.do_flip =            RNA_boolean_get(itemptr, "pen_flip");
2193         wpi.do_multipaint =      wpd->do_multipaint;
2194         wpi.do_auto_normalize =  ((ts->auto_normalize != 0) && (wpi.vgroup_validmap != NULL));
2195         wpi.brush_alpha_value =  brush_alpha_value;
2196         /* *** done setting up WeightPaintInfo *** */
2197
2198         if (wpd->precomputed_weight) {
2199                 precompute_weight_values(C, ob, brush, wpd, &wpi, ob->data);
2200         }
2201
2202         wpaint_do_symmetrical_brush_actions(C, ob, wp, sd, wpd, &wpi);
2203
2204         swap_m4m4(vc->rv3d->persmat, mat);
2205
2206         /* calculate pivot for rotation around seletion if needed */
2207         /* also needed for "View Selected" on last stroke */
2208         paint_last_stroke_update(scene, vc->ar, mval);
2209
2210         BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
2211
2212         DEG_id_tag_update(ob->data, 0);
2213         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
2214         swap_m4m4(wpd->vc.rv3d->persmat, mat);
2215
2216         rcti r;
2217         if (sculpt_get_redraw_rect(vc->ar, CTX_wm_region_view3d(C), ob, &r)) {
2218                 if (ss->cache) {
2219                         ss->cache->current_r = r;
2220                 }
2221
2222                 /* previous is not set in the current cache else
2223                  * the partial rect will always grow */
2224                 if (ss->cache) {
2225                         if (!BLI_rcti_is_empty(&ss->cache->previous_r))
2226                                 BLI_rcti_union(&r, &ss->cache->previous_r);
2227                 }
2228
2229                 r.xmin += vc->ar->winrct.xmin - 2;
2230                 r.xmax += vc->ar->winrct.xmin + 2;
2231                 r.ymin += vc->ar->winrct.ymin - 2;
2232                 r.ymax += vc->ar->winrct.ymin + 2;
2233
2234                 ss->partial_redraw = 1;
2235         }
2236         ED_region_tag_redraw_partial(vc->ar, &r);
2237 }
2238
2239 static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
2240 {
2241         Object *ob = CTX_data_active_object(C);
2242         struct WPaintData *wpd = paint_stroke_mode_data(stroke);
2243
2244         if (wpd) {
2245                 if (wpd->defbase_sel)
2246                         MEM_freeN((void *)wpd->defbase_sel);
2247                 if (wpd->vgroup_validmap)
2248                         MEM_freeN((void *)wpd->vgroup_validmap);
2249                 if (wpd->lock_flags)
2250                         MEM_freeN((void *)wpd->lock_flags);
2251                 if (wpd->active.lock)
2252                         MEM_freeN((void *)wpd->active.lock);
2253                 if (wpd->mirror.lock)
2254                         MEM_freeN((void *)wpd->mirror.lock);
2255                 if (wpd->precomputed_weight)
2256                         MEM_freeN(wpd->precomputed_weight);
2257
2258                 MEM_freeN(wpd);
2259         }
2260
2261         /* and particles too */
2262         if (ob->particlesystem.first) {
2263                 ParticleSystem *psys;
2264                 int i;
2265
2266                 for (psys = ob->particlesystem.first; psys; psys = psys->next) {
2267                         for (i = 0; i < PSYS_TOT_VG; i++) {
2268                                 if (psys->vgroup[i] == ob->actdef) {
2269                                         psys->recalc |= PSYS_RECALC_RESET;
2270                                         break;
2271                                 }
2272                         }
2273                 }
2274         }
2275
2276         DEG_id_tag_update(ob->data, 0);
2277
2278         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
2279
2280         sculpt_cache_free(ob->sculpt->cache);
2281         ob->sculpt->cache = NULL;
2282 }
2283
2284
2285 static int wpaint_invoke(bContext *C, wmOperator *op, const wmEvent *event)
2286 {
2287         int retval;
2288
2289         op->customdata = paint_stroke_new(
2290                 C, op, sculpt_stroke_get_location, wpaint_stroke_test_start,
2291                 wpaint_stroke_update_step, NULL,
2292                 wpaint_stroke_done, event->type);
2293
2294         if ((retval = op->type->modal(C, op, event)) == OPERATOR_FINISHED) {
2295                 paint_stroke_data_free(op);
2296                 return OPERATOR_FINISHED;
2297         }
2298         /* add modal handler */
2299         WM_event_add_modal_handler(C, op);
2300
2301         OPERATOR_RETVAL_CHECK(retval);
2302         BLI_assert(retval == OPERATOR_RUNNING_MODAL);
2303
2304         return OPERATOR_RUNNING_MODAL;
2305 }
2306
2307 static int wpaint_exec(bContext *C, wmOperator *op)
2308 {
2309         op->customdata = paint_stroke_new(
2310                 C, op, sculpt_stroke_get_location, wpaint_stroke_test_start,
2311                 wpaint_stroke_update_step, NULL,
2312                 wpaint_stroke_done, 0);
2313
2314         /* frees op->customdata */
2315         paint_stroke_exec(C, op);
2316
2317         return OPERATOR_FINISHED;
2318 }
2319
2320 static void wpaint_cancel(bContext *C, wmOperator *op)
2321 {
2322         Object *ob = CTX_data_active_object(C);
2323         if (ob->sculpt->cache) {
2324                 sculpt_cache_free(ob->sculpt->cache);
2325                 ob->sculpt->cache = NULL;
2326         }
2327
2328         paint_stroke_cancel(C, op);
2329 }
2330
2331 void PAINT_OT_weight_paint(wmOperatorType *ot)
2332 {
2333         /* identifiers */
2334         ot->name = "Weight Paint";
2335         ot->idname = "PAINT_OT_weight_paint";
2336         ot->description = "Paint a stroke in the current vertex group's weights";
2337
2338         /* api callbacks */
2339         ot->invoke = wpaint_invoke;
2340         ot->modal = paint_stroke_modal;
2341         ot->exec = wpaint_exec;
2342         ot->poll = weight_paint_poll;
2343         ot->cancel = wpaint_cancel;
2344
2345         /* flags */
2346         ot->flag = OPTYPE_UNDO | OPTYPE_BLOCKING;
2347
2348         paint_stroke_operator_properties(ot);
2349 }
2350
2351 /* ************ set / clear vertex paint mode ********** */
2352
2353 /**
2354  * \note Keep in sync with #wpaint_mode_toggle_exec
2355  */
2356 static int vpaint_mode_toggle_exec(bContext *C, wmOperator *op)
2357 {
2358         struct wmMsgBus *mbus = CTX_wm_message_bus(C);
2359         Object *ob = CTX_data_active_object(C);
2360         const int mode_flag = OB_MODE_VERTEX_PAINT;
2361         const bool is_mode_set = (ob->mode & mode_flag) != 0;
2362         Scene *scene = CTX_data_scene(C);
2363
2364         if (!is_mode_set) {
2365                 if (!ED_object_mode_compat_set(C, ob, mode_flag, op->reports)) {
2366                         return OPERATOR_CANCELLED;
2367                 }
2368         }
2369
2370         Mesh *me = BKE_mesh_from_object(ob);
2371
2372         /* toggle: end vpaint */
2373         if (is_mode_set) {
2374                 ED_object_vpaintmode_exit_ex(ob);
2375         }
2376         else {
2377                 Depsgraph *depsgraph = CTX_data_depsgraph_on_load(C);
2378                 wmWindowManager *wm = CTX_wm_manager(C);
2379                 ED_object_vpaintmode_enter_ex(depsgraph, wm, scene, ob);
2380         }
2381
2382         BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_ALL);
2383
2384         /* update modifier stack for mapping requirements */
2385         DEG_id_tag_update(&me->id, 0);
2386
2387         WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
2388
2389         WM_msg_publish_rna_prop(mbus, &ob->id, ob, Object, mode);
2390
2391         WM_toolsystem_update_from_context_view3d(C);
2392
2393         return OPERATOR_FINISHED;
2394 }
2395
2396 void PAINT_OT_vertex_paint_toggle(wmOperatorType *ot)
2397 {
2398         /* identifiers */
2399         ot->name = "Vertex Paint Mode";
2400         ot->idname = "PAINT_OT_vertex_paint_toggle";
2401         ot->description = "Toggle the vertex paint mode in 3D view";
2402
2403         /* api callbacks */
2404         ot->exec = vpaint_mode_toggle_exec;
2405         ot->poll = paint_poll_test;
2406
2407         /* flags */
2408         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
2409 }
2410
2411
2412
2413 /* ********************** vertex paint operator ******************* */
2414
2415 /* Implementation notes:
2416  *
2417  * Operator->invoke()
2418  * - validate context (add mcol)
2419  * - create customdata storage
2420  * - call paint once (mouse click)
2421  * - add modal handler
2422  *
2423  * Operator->modal()
2424  * - for every mousemove, apply vertex paint
2425  * - exit on mouse release, free customdata
2426  *   (return OPERATOR_FINISHED also removes handler and operator)
2427  *
2428  * For future:
2429  * - implement a stroke event (or mousemove with past positons)
2430  * - revise whether op->customdata should be added in object, in set_vpaint
2431  */
2432
2433 typedef struct PolyFaceMap {
2434         struct PolyFaceMap *next, *prev;
2435         int facenr;
2436 } PolyFaceMap;
2437
2438 struct VPaintData {
2439         ViewContext vc;
2440         struct NormalAnglePrecalc normal_angle_precalc;
2441
2442         uint paintcol;
2443
2444         struct VertProjHandle *vp_handle;
2445         struct DMCoNo *vertexcosnos;
2446
2447         /* modify 'me->mcol' directly, since the derived mesh is drawing from this
2448          * array, otherwise we need to refresh the modifier stack */
2449         bool use_fast_update;
2450
2451         /* loops tagged as having been painted, to apply shared vertex color
2452          * blending only to modified loops */
2453         bool *mlooptag;
2454
2455         bool is_texbrush;
2456
2457         /* Special storage for smear brush, avoid feedback loop - update each step. */
2458         struct {
2459                 uint *color_prev;
2460                 uint *color_curr;
2461         } smear;
2462 };
2463
2464 static bool vpaint_stroke_test_start(bContext *C, struct wmOperator *op, const float mouse[2])
2465 {
2466         Scene *scene = CTX_data_scene(C);
2467         ToolSettings *ts = scene->toolsettings;
2468         struct PaintStroke *stroke = op->customdata;
2469         VPaint *vp = ts->vpaint;
2470         Brush *brush = BKE_paint_brush(&vp->paint);
2471         struct VPaintData *vpd;
2472         Object *ob = CTX_data_active_object(C);
2473         Mesh *me;
2474         SculptSession *ss = ob->sculpt;
2475         Depsgraph *depsgraph = CTX_data_depsgraph(C);
2476
2477         /* context checks could be a poll() */
2478         me = BKE_mesh_from_object(ob);
2479         if (me == NULL || me->totpoly == 0)
2480                 return false;
2481
2482         ED_mesh_color_ensure(me, NULL);
2483         if (me->mloopcol == NULL)
2484                 return false;
2485
2486         /* make mode data storage */
2487         vpd = MEM_callocN(sizeof(*vpd), "VPaintData");
2488         paint_stroke_set_mode_data(stroke, vpd);
2489         ED_view3d_viewcontext_init(C, &vpd->vc);
2490         view_angle_limits_init(&vpd->normal_angle_precalc, vp->paint.brush->falloff_angle,
2491                                (vp->paint.brush->flag & BRUSH_FRONTFACE_FALLOFF) != 0);
2492
2493         vpd->paintcol = vpaint_get_current_col(scene, vp);
2494
2495         vpd->is_texbrush = !(brush->vertexpaint_tool == PAINT_BLEND_BLUR) &&
2496                            brush->mtex.tex;
2497
2498         /* are we painting onto a modified mesh?,
2499          * if not we can skip face map trickiness */
2500         if (vertex_paint_use_fast_update_check(ob)) {
2501                 vpd->use_fast_update = true;
2502 /*              printf("Fast update!\n");*/
2503         }
2504         else {
2505                 vpd->use_fast_update = false;
2506 /*              printf("No fast update!\n");*/
2507         }
2508
2509         /* to keep tracked of modified loops for shared vertex color blending */
2510         if (brush->vertexpaint_tool == PAINT_BLEND_BLUR) {
2511                 vpd->mlooptag = MEM_mallocN(sizeof(bool) * me->totloop, "VPaintData mlooptag");
2512         }
2513
2514         if (brush->vertexpaint_tool == PAINT_BLEND_SMEAR) {
2515                 vpd->smear.color_prev = MEM_mallocN(sizeof(uint) * me->totloop, __func__);
2516                 memcpy(vpd->smear.color_prev, me->mloopcol, sizeof(uint) * me->totloop);
2517                 vpd->smear.color_curr = MEM_dupallocN(vpd->smear.color_prev);
2518         }
2519
2520         /* Create projection handle */
2521         if (vpd->is_texbrush) {
2522                 ob->sculpt->building_vp_handle = true;
2523                 vpd->vp_handle = ED_vpaint_proj_handle_create(depsgraph, scene, ob, &vpd->vertexcosnos);
2524                 ob->sculpt->building_vp_handle = false;
2525         }
2526
2527         /* If not previously created, create vertex/weight paint mode session data */
2528         vertex_paint_init_session(depsgraph, scene, ob);
2529         vwpaint_update_cache_invariants(C, vp, ss, op, mouse);
2530         vertex_paint_init_session_data(ts, ob);
2531
2532         if (ob->sculpt->mode.vpaint.previous_color != NULL) {
2533                 memset(ob->sculpt->mode.vpaint.previous_color, 0, sizeof(uint) * me->totloop);
2534         }
2535
2536         return 1;
2537 }
2538
2539 static void do_vpaint_brush_calc_average_color_cb_ex(
2540         void *__restrict userdata,
2541         const int n,
2542         const ParallelRangeTLS *__restrict UNUSED(tls))
2543 {
2544         SculptThreadedTaskData *data = userdata;
2545         SculptSession *ss = data->ob->sculpt;
2546         CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
2547         const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
2548
2549         StrokeCache *cache = ss->cache;
2550         uint *lcol = data->lcol;
2551         char *col;
2552         const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
2553
2554         struct VPaintAverageAccum *accum = (struct VPaintAverageAccum *)data->custom_data + n;
2555         accum->len = 0;
2556         memset(accum->value, 0, sizeof(accum->value));
2557
2558         SculptBrushTest test;
2559         SculptBrushTestFn sculpt_brush_test_sq_fn =
2560                 sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape);
2561
2562         /* For each vertex */
2563         PBVHVertexIter vd;
2564         BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
2565         {
2566                 /* Test to see if the vertex coordinates are within the spherical brush region. */
2567                 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
2568                         const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
2569                         if (BKE_brush_curve_strength(data->brush, 0.0, cache->radius) > 0.0) {
2570                                 /* If the vertex is selected for painting. */
2571                                 const MVert *mv = &data->me->mvert[v_index];
2572                                 if (!use_vert_sel || mv->flag & SELECT) {
2573                                         accum->len += gmap->vert_to_loop[v_index].count;
2574                                         /* if a vertex is within the brush region, then add it's color to the blend. */
2575                                         for (int j = 0; j < gmap->vert_to_loop[v_index].count; j++) {
2576                                                 const int l_index = gmap->vert_to_loop[v_index].indices[j];
2577                                                 col = (char *)(&lcol[l_index]);
2578                                                 /* Color is squared to compensate the sqrt color encoding. */
2579                                                 accum->value[0] += col[0] * col[0];
2580                                                 accum->value[1] += col[1] * col[1];
2581                                                 accum->value[2] += col[2] * col[2];
2582                                         }
2583                                 }
2584                         }
2585                 }
2586         }
2587         BKE_pbvh_vertex_iter_end;
2588 }
2589
2590 static float tex_color_alpha_ubyte(
2591         SculptThreadedTaskData *data, const float v_co[3],
2592         uint *r_color)
2593 {
2594         float rgba[4];
2595         float rgba_br[3];
2596         tex_color_alpha(data->vp, &data->vpd->vc, v_co, rgba);
2597         rgb_uchar_to_float(rgba_br, (const uchar *)&data->vpd->paintcol);
2598         mul_v3_v3(rgba_br, rgba);
2599         rgb_float_to_uchar((uchar *)r_color, rgba_br);
2600         return rgba[3];
2601 }
2602
2603 static void do_vpaint_brush_draw_task_cb_ex(
2604         void *__restrict userdata, 
2605         const int n,
2606         const ParallelRangeTLS *__restrict UNUSED(tls))
2607 {
2608         SculptThreadedTaskData *data = userdata;
2609         SculptSession *ss = data->ob->sculpt;
2610         CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
2611         const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
2612
2613         const Brush *brush = data->brush;
2614         const StrokeCache *cache = ss->cache;
2615         uint *lcol = data->lcol;
2616         const Scene *scene = CTX_data_scene(data->C);
2617         float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
2618         get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
2619         const bool use_normal = vwpaint_use_normal(data->vp);
2620         const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
2621         const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
2622
2623         SculptBrushTest test;
2624         SculptBrushTestFn sculpt_brush_test_sq_fn =
2625                 sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape);
2626         const float *sculpt_normal_frontface =
2627                 sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape);
2628
2629         /* For each vertex */
2630         PBVHVertexIter vd;
2631         BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
2632         {
2633                 /* Test to see if the vertex coordinates are within the spherical brush region. */
2634                 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
2635                         /* Note: Grids are 1:1 with corners (aka loops).
2636                          * For grid based pbvh, take the vert whose loop cooresponds to the current grid.
2637                          * Otherwise, take the current vert. */
2638                         const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
2639                         const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
2640                         const MVert *mv = &data->me->mvert[v_index];
2641
2642                         /* If the vertex is selected for painting. */
2643                         if (!use_vert_sel || mv->flag & SELECT) {
2644                                 /* Calc the dot prod. between ray norm on surf and current vert
2645                                  * (ie splash prevention factor), and only paint front facing verts. */
2646                                 float brush_strength = cache->bstrength;
2647                                 const float angle_cos = (use_normal && vd.no) ?
2648                                         dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f;
2649                                 if (((brush->flag & BRUSH_FRONTFACE) == 0 ||
2650                                      (angle_cos > 0.0f)) &&
2651                                     ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 ||
2652                                      view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength)))
2653                                 {
2654                                         const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
2655                                         uint color_final = data->vpd->paintcol;
2656
2657                                         /* If we're painting with a texture, sample the texture color and alpha. */
2658                                         float tex_alpha = 1.0;
2659                                         if (data->vpd->is_texbrush) {
2660                                                 /* Note: we may want to paint alpha as vertex color alpha. */
2661                                                 tex_alpha = tex_color_alpha_ubyte(
2662                                                         data, data->vpd->vertexcosnos[v_index].co,
2663                                                         &color_final);
2664                                         }
2665                                         /* For each poly owning this vert, paint each loop belonging to this vert. */
2666                                         for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
2667                                                 const int p_index = gmap->vert_to_poly[v_index].indices[j];
2668                                                 const int l_index = gmap->vert_to_loop[v_index].indices[j];
2669                                                 BLI_assert(data->me->mloop[l_index].v == v_index);
2670                                                 const MPoly *mp = &data->me->mpoly[p_index];
2671                                                 if (!use_face_sel || mp->flag & ME_FACE_SEL) {
2672                                                         uint color_orig = 0;  /* unused when array is NULL */
2673                                                         if (ss->mode.vpaint.previous_color != NULL) {
2674                                                                 /* Get the previous loop color */
2675                                                                 if (ss->mode.vpaint.previous_color[l_index] == 0) {
2676                                                                         ss->mode.vpaint.previous_color[l_index] = lcol[l_index];
2677                                                                 }
2678                                                                 color_orig = ss->mode.vpaint.previous_color[l_index];
2679                                                         }
2680                                                         const float final_alpha =
2681                                                                 255 * brush_fade * brush_strength *
2682                                                                 tex_alpha * brush_alpha_pressure * grid_alpha;
2683
2684                                                         /* Mix the new color with the original based on final_alpha. */
2685                                                         lcol[l_index] = vpaint_blend(
2686                                                                 data->vp, lcol[l_index], color_orig, color_final,
2687                                                                 final_alpha, 255 * brush_strength);
2688                                                 }
2689                                         }
2690                                 }
2691                         }
2692                 }
2693         }
2694         BKE_pbvh_vertex_iter_end;
2695 }
2696
2697 static void do_vpaint_brush_blur_task_cb_ex(
2698         void *__restrict userdata,
2699         const int n,
2700         const ParallelRangeTLS *__restrict UNUSED(tls))
2701 {
2702         SculptThreadedTaskData *data = userdata;
2703         SculptSession *ss = data->ob->sculpt;
2704         CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
2705
2706         Scene *scene = CTX_data_scene(data->C);
2707         const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
2708         const Brush *brush = data->brush;
2709         const StrokeCache *cache = ss->cache;
2710         uint *lcol = data->lcol;
2711         float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
2712         get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
2713         const bool use_normal = vwpaint_use_normal(data->vp);
2714         const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
2715         const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
2716
2717         SculptBrushTest test;
2718         SculptBrushTestFn sculpt_brush_test_sq_fn =
2719                 sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape);
2720         const float *sculpt_normal_frontface =
2721                 sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape);
2722
2723         /* For each vertex */
2724         PBVHVertexIter vd;
2725         BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
2726         {
2727                 /* Test to see if the vertex coordinates are within the spherical brush region. */
2728                 if (sculpt_brush_test_sq_fn(&test, vd.co)) {
2729                         /* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
2730                          * Otherwise, take the current vert. */
2731                         const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
2732                         const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
2733                         const MVert *mv = &data->me->mvert[v_index];
2734
2735                         /* If the vertex is selected for painting. */
2736                         if (!use_vert_sel || mv->flag & SELECT) {
2737                                 float brush_strength = cache->bstrength;
2738                                 const float angle_cos = (use_normal && vd.no) ?
2739                                         dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f;
2740                                 if (((brush->flag & BRUSH_FRONTFACE) == 0 ||
2741                                      (angle_cos > 0.0f)) &&
2742                                     ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 ||
2743                                      view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength)))
2744                                 {
2745                                         const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
2746
2747                                         /* Get the average poly color */
2748                                         uint color_final = 0;
2749                                         int total_hit_loops = 0;
2750                                         uint blend[4] = {0};
2751                                         for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
2752                                                 int p_index = gmap->vert_to_poly[v_index].indices[j];
2753                                                 const MPoly *mp = &data->me->mpoly[p_index];
2754                                                 if (!use_face_sel || mp->flag & ME_FACE_SEL) {
2755                                                         total_hit_loops += mp->totloop;
2756                                                         for (int k = 0; k < mp->totloop; k++) {
2757                                                                 const uint l_index = mp->loopstart + k;
2758                                                                 const char *col = (const char *)(&lcol[l_index]);
2759                                                                 /* Color is squared to compensate the sqrt color encoding. */
2760                                                                 blend[0] += (uint)col[0] * (uint)col[0];
2761                                                                 blend[1] += (uint)col[1] * (uint)col[1];
2762                                                                 blend[2] += (uint)col[2] * (uint)col[2];
2763                                                                 blend[3] += (uint)col[3] * (uint)col[3];
2764                                                         }
2765                                                 }
2766                                         }
2767                                         if (total_hit_loops != 0) {
2768                                                 /* Use rgb^2 color averaging. */
2769                                                 char *col = (char *)(&color_final);
2770                                                 col[0] = round_fl_to_uchar(sqrtf(divide_round_i(blend[0], total_hit_loops)));
2771                                                 col[1] = round_fl_to_uchar(sqrtf(divide_round_i(blend[1], total_hit_loops)));
2772                                                 col[2] = round_fl_to_uchar(sqrtf(divide_round_i(blend[2], total_hit_loops)));
2773                                                 col[3] = round_fl_to_uchar(sqrtf(divide_round_i(blend[3], total_hit_loops)));
2774
2775                                                 /* For each poly owning this vert, paint each loop belonging to this vert. */
2776                                                 for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
2777                                                         const int p_index = gmap->vert_to_poly[v_index].indices[j];
2778                                                         const int l_index = gmap->vert_to_loop[v_index].indices[j];
2779                                                         BLI_assert(data->me->mloop[l_index].v == v_index);
2780                                                         const MPoly *mp = &data->me->mpoly[p_index];
2781                                                         if (!use_face_sel || mp->flag & ME_FACE_SEL) {
2782                                                                 uint color_orig = 0;  /* unused when array is NULL */
2783                                                                 if (ss->mode.vpaint.previous_color != NULL) {
2784                                                                         /* Get the previous loop color */
2785                                                                         if (ss->mode.vpaint.previous_color[l_index] == 0) {
2786                                                                                 ss->mode.vpaint.previous_color[l_index] = lcol[l_index];
2787                                                                         }
2788                                                                         color_orig = ss->mode.vpaint.previous_color[l_index];
2789                                                                 }
2790                                                                 const float final_alpha =
2791                                                                         255 * brush_fade * brush_strength *
2792                                                                         brush_alpha_pressure * grid_alpha;
2793                                                                 /* Mix the new color with the original
2794                                                                  * based on the brush strength and the curve. */
2795                                                                 lcol[l_index] = vpaint_blend(
2796                                                                         data->vp, lcol[l_index], color_orig, *((uint *)col),
2797                                                                         final_alpha, 255 * brush_strength);
2798                                                         }
2799                                                 }
2800                                         }
2801                                 }
2802                         }
2803                 }
2804         }
2805         BKE_pbvh_vertex_iter_end;
2806 }
2807
2808 static void do_vpaint_brush_smear_task_cb_ex(
2809         void *__restrict userdata,
2810         const int n,
2811         const ParallelRangeTLS *__restrict UNUSED(tls))
2812 {
2813         SculptThreadedTaskData *data = userdata;
2814         SculptSession *ss = data->ob->sculpt;
2815         CCGDerivedMesh *ccgdm = BKE_pbvh_get_ccgdm(ss->pbvh);
2816
2817         Scene *scene = CTX_data_scene(data->C);
2818         const struct SculptVertexPaintGeomMap *gmap = &ss->mode.vpaint.gmap;
2819         const Brush *brush = data->brush;
2820         const StrokeCache *cache = ss->cache;
2821         uint *lcol = data->lcol;
2822         float brush_size_pressure, brush_alpha_value, brush_alpha_pressure;
2823         get_brush_alpha_data(scene, ss, brush, &brush_size_pressure, &brush_alpha_value, &brush_alpha_pressure);
2824         float brush_dir[3];
2825         const bool use_normal = vwpaint_use_normal(data->vp);
2826         const bool use_vert_sel = (data->me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
2827         const bool use_face_sel = (data->me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
2828
2829         sub_v3_v3v3(brush_dir, cache->location, cache->last_location);
2830         project_plane_v3_v3v3(brush_dir, brush_dir, cache->view_normal);
2831
2832         if (cache->is_last_valid && (normalize_v3(brush_dir) != 0.0f)) {
2833
2834                 SculptBrushTest test;
2835                 SculptBrushTestFn sculpt_brush_test_sq_fn =
2836                         sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape);
2837                 const float *sculpt_normal_frontface =
2838                         sculpt_brush_frontface_normal_from_falloff_shape(ss, data->brush->falloff_shape);
2839
2840                 /* For each vertex */
2841                 PBVHVertexIter vd;
2842                 BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
2843                 {
2844                         /* Test to see if the vertex coordinates are within the spherical brush region. */
2845                         if (sculpt_brush_test_sq_fn(&test, vd.co)) {
2846                                 /* For grid based pbvh, take the vert whose loop cooresponds to the current grid.
2847                                  * Otherwise, take the current vert. */
2848                                 const int v_index = ccgdm ? data->me->mloop[vd.grid_indices[vd.g]].v : vd.vert_indices[vd.i];
2849                                 const float grid_alpha = ccgdm ? 1.0f / vd.gridsize : 1.0f;
2850                                 const MVert *mv_curr = &data->me->mvert[v_index];
2851
2852                                 /* if the vertex is selected for painting. */
2853                                 if (!use_vert_sel || mv_curr->flag & SELECT) {
2854                                         /* Calc the dot prod. between ray norm on surf and current vert
2855                                          * (ie splash prevention factor), and only paint front facing verts. */
2856                                         float brush_strength = cache->bstrength;
2857                                         const float angle_cos = (use_normal && vd.no) ?
2858                                                 dot_vf3vs3(sculpt_normal_frontface, vd.no) : 1.0f;
2859                                         if (((brush->flag & BRUSH_FRONTFACE) == 0 ||
2860                                              (angle_cos > 0.0f)) &&
2861                                             ((brush->flag & BRUSH_FRONTFACE_FALLOFF) == 0 ||
2862                                              view_angle_limits_apply_falloff(&data->vpd->normal_angle_precalc, angle_cos, &brush_strength)))
2863                                         {
2864                                                 const float brush_fade = BKE_brush_curve_strength(brush, sqrtf(test.dist), cache->radius);
2865
2866                                                 bool do_color = false;
2867                                                 /* Minimum dot product between brush direction and current
2868                                                  * to neighbor direction is 0.0, meaning orthogonal. */
2869                                                 float stroke_dot_max = 0.0f;
2870
2871                                                 /* Get the color of the loop in the opposite direction of the brush movement */
2872                                                 uint color_final = 0;
2873                                                 for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
2874                                                         const int p_index = gmap->vert_to_poly[v_index].indices[j];
2875                                                         const int l_index = gmap->vert_to_loop[v_index].indices[j];
2876                                                         BLI_assert(data->me->mloop[l_index].v == v_index);
2877                                                         UNUSED_VARS_NDEBUG(l_index);
2878                                                         const MPoly *mp = &data->me->mpoly[p_index];
2879                                                         if (!use_face_sel || mp->flag & ME_FACE_SEL) {
2880                                                                 const MLoop *ml_other = &data->me->mloop[mp->loopstart];
2881                                                                 for (int k = 0; k < mp->totloop; k++, ml_other++) {
2882                                                                         const uint v_other_index = ml_other->v;
2883                                                                         if (v_other_index != v_index) {
2884                                                                                 const MVert *mv_other = &data->me->mvert[v_other_index];
2885
2886                                                                                 /* Get the direction from the selected vert to the neighbor. */
2887                                                                                 float other_dir[3];
2888                                                                                 sub_v3_v3v3(other_dir, mv_curr->co, mv_other->co);
2889                                                                                 project_plane_v3_v3v3(other_dir, other_dir, cache->view_normal);
2890
2891                                                                                 normalize_v3(other_dir);
2892
2893                                                                                 const float stroke_dot = dot_v3v3(other_dir, brush_dir);
2894
2895                                                                                 if (stroke_dot > stroke_dot_max) {
2896                                                                                         stroke_dot_max = stroke_dot;
2897                                                                                         color_final = data->vpd->smear.color_prev[mp->loopstart + k];
2898                                                                                         do_color = true;
2899                                                                                 }
2900                                                                         }
2901                                                                 }
2902                                                         }
2903                                                 }
2904
2905                                                 if (do_color) {
2906                                                         const float final_alpha =
2907                                                                 255 * brush_fade * brush_strength *
2908                                                                 brush_alpha_pressure * grid_alpha;
2909
2910                                                         /* For each poly owning this vert, paint each loop belonging to this vert. */
2911                                                         for (int j = 0; j < gmap->vert_to_poly[v_index].count; j++) {
2912                                                                 const int p_index = gmap->vert_to_poly[v_index].indices[j];
2913                                                                 const int l_index = gmap->vert_to_loop[v_index].indices[j];
2914                                                                 BLI_assert(data->me->mloop[l_index].v == v_index);
2915                                                                 const MPoly *mp = &data->me->mpoly[p_index];
2916                                                                 if (!use_face_sel || mp->flag & ME_FACE_SEL) {
2917                                                                         /* Get the previous loop color */
2918                                                                         uint color_orig = 0;  /* unused when array is NULL */
2919                                                                         if (ss->mode.vpaint.previous_color != NULL) {
2920                                                                                 /* Get the previous loop color */
2921                                                                                 if (ss->mode.vpaint.previous_color[l_index] == 0) {
2922                                                                                         ss->mode.vpaint.previous_color[l_index] = lcol[l_index];
2923                                                                                 }
2924                                                                                 color_orig = ss->mode.vpaint.previous_color[l_index];
2925                                                                         }
2926                                                                         /* Mix the new color with the original
2927                                                                          * based on the brush strength and the curve. */
2928      &n