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