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