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