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