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