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