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