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