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