Logging: Use CLOG for blenkernel
[blender.git] / source / blender / blenkernel / intern / dynamicpaint.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  * Contributor(s): Miika Hämäläinen
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/blenkernel/intern/dynamicpaint.c
24  *  \ingroup bke
25  */
26
27 #include "MEM_guardedalloc.h"
28
29 #include <math.h>
30 #include <stdio.h>
31
32 #include "BLI_blenlib.h"
33 #include "BLI_math.h"
34 #include "BLI_kdtree.h"
35 #include "BLI_string_utils.h"
36 #include "BLI_task.h"
37 #include "BLI_threads.h"
38 #include "BLI_utildefines.h"
39
40 #include "BLT_translation.h"
41
42 #include "DNA_anim_types.h"
43 #include "DNA_armature_types.h"
44 #include "DNA_collection_types.h"
45 #include "DNA_constraint_types.h"
46 #include "DNA_dynamicpaint_types.h"
47 #include "DNA_material_types.h"
48 #include "DNA_mesh_types.h"
49 #include "DNA_meshdata_types.h"
50 #include "DNA_modifier_types.h"
51 #include "DNA_object_types.h"
52 #include "DNA_scene_types.h"
53 #include "DNA_texture_types.h"
54
55 #include "BKE_animsys.h"
56 #include "BKE_armature.h"
57 #include "BKE_bvhutils.h"   /* bvh tree */
58 #include "BKE_collection.h"
59 #include "BKE_collision.h"
60 #include "BKE_colorband.h"
61 #include "BKE_constraint.h"
62 #include "BKE_customdata.h"
63 #include "BKE_deform.h"
64 #include "BKE_dynamicpaint.h"
65 #include "BKE_effect.h"
66 #include "BKE_image.h"
67 #include "BKE_library.h"
68 #include "BKE_main.h"
69 #include "BKE_material.h"
70 #include "BKE_mesh.h"
71 #include "BKE_mesh_mapping.h"
72 #include "BKE_mesh_runtime.h"
73 #include "BKE_modifier.h"
74 #include "BKE_object.h"
75 #include "BKE_particle.h"
76 #include "BKE_pointcache.h"
77 #include "BKE_scene.h"
78
79 #include "DEG_depsgraph.h"
80 #include "DEG_depsgraph_query.h"
81
82 /* for image output     */
83 #include "IMB_imbuf_types.h"
84 #include "IMB_imbuf.h"
85
86 /* to read material/texture color */
87 #include "RE_render_ext.h"
88 #include "RE_shader_ext.h"
89
90 #include "atomic_ops.h"
91
92 #include "CLG_log.h"
93
94 /* could enable at some point but for now there are far too many conversions */
95 #ifdef __GNUC__
96 //#  pragma GCC diagnostic ignored "-Wdouble-promotion"
97 #endif
98
99 static CLG_LogRef LOG = {"bke.dynamicpaint"};
100
101 /* precalculated gaussian factors for 5x super sampling */
102 static const float gaussianFactors[5] = {
103     0.996849f,
104     0.596145f,
105     0.596145f,
106     0.596145f,
107     0.524141f};
108 static const float gaussianTotal = 3.309425f;
109
110 /* UV Image neighboring pixel table x and y list */
111 static int neighX[8] = {1, 1, 0, -1, -1, -1, 0, 1};
112 static int neighY[8] = {0, 1, 1, 1, 0, -1, -1, -1};
113
114 /* Neighbor x/y list that prioritizes grid directions over diagonals */
115 static int neighStraightX[8] = {1, 0, -1,  0, 1, -1, -1,  1};
116 static int neighStraightY[8] = {0, 1,  0, -1, 1,  1, -1, -1};
117
118 /* subframe_updateObject() flags */
119 #define SUBFRAME_RECURSION 5
120 /* surface_getBrushFlags() return vals */
121 #define BRUSH_USES_VELOCITY (1 << 0)
122 /* brush mesh raycast status */
123 #define HIT_VOLUME 1
124 #define HIT_PROXIMITY 2
125 /* dynamicPaint_findNeighbourPixel() return codes */
126 #define NOT_FOUND -1
127 #define ON_MESH_EDGE -2
128 #define OUT_OF_TEXTURE -3
129 /* paint effect default movement per frame in global units */
130 #define EFF_MOVEMENT_PER_FRAME 0.05f
131 /* initial wave time factor */
132 #define WAVE_TIME_FAC (1.0f / 24.f)
133 #define CANVAS_REL_SIZE 5.0f
134 /* drying limits */
135 #define MIN_WETNESS 0.001f
136 #define MAX_WETNESS 5.0f
137
138
139 /* dissolve inline function */
140 BLI_INLINE void value_dissolve(float *r_value, const float time, const float scale, const bool is_log)
141 {
142         *r_value = (is_log) ?
143                       (*r_value) * (powf(MIN_WETNESS, 1.0f / (1.2f * time / scale))) :
144                       (*r_value) - 1.0f / time * scale;
145 }
146
147
148 /***************************** Internal Structs ***************************/
149
150 typedef struct Bounds2D {
151         float min[2], max[2];
152 } Bounds2D;
153
154 typedef struct Bounds3D {
155         float min[3], max[3];
156         bool valid;
157 } Bounds3D;
158
159 typedef struct VolumeGrid {
160         int dim[3];
161         Bounds3D grid_bounds;  /* whole grid bounds */
162
163         Bounds3D *bounds;  /* (x*y*z) precalculated grid cell bounds */
164         int *s_pos;  /* (x*y*z) t_index begin id */
165         int *s_num;  /* (x*y*z) number of t_index points */
166         int *t_index;  /* actual surface point index, access: (s_pos + s_num) */
167
168         int *temp_t_index;
169 } VolumeGrid;
170
171 typedef struct Vec3f {
172         float v[3];
173 } Vec3f;
174
175 typedef struct BakeAdjPoint {
176         float dir[3];   /* vector pointing towards this neighbor */
177         float dist;     /* distance to */
178 } BakeAdjPoint;
179
180 /* Surface data used while processing a frame */
181 typedef struct PaintBakeNormal {
182         float invNorm[3];  /* current pixel world-space inverted normal */
183         float normal_scale;  /* normal directional scale for displace mapping */
184 } PaintBakeNormal;
185
186 /* Temp surface data used to process a frame */
187 typedef struct PaintBakeData {
188         /* point space data */
189         PaintBakeNormal *bNormal;
190         int *s_pos;  /* index to start reading point sample realCoord */
191         int *s_num;  /* num of realCoord samples */
192         Vec3f *realCoord;  /* current pixel center world-space coordinates for each sample ordered as (s_pos + s_num) */
193         Bounds3D mesh_bounds;
194         float dim[3];
195
196         /* adjacency info */
197         BakeAdjPoint *bNeighs;  /* current global neighbor distances and directions, if required */
198         double average_dist;
199         /* space partitioning */
200         VolumeGrid *grid;       /* space partitioning grid to optimize brush checks */
201
202         /* velocity and movement */
203         Vec3f *velocity;        /* speed vector in global space movement per frame, if required */
204         Vec3f *prev_velocity;
205         float *brush_velocity;  /* special temp data for post-p velocity based brushes like smudge
206                                  * 3 float dir vec + 1 float str */
207         MVert *prev_verts;      /* copy of previous frame vertices. used to observe surface movement */
208         float prev_obmat[4][4]; /* previous frame object matrix */
209         int clear;              /* flag to check if surface was cleared/reset -> have to redo velocity etc. */
210 } PaintBakeData;
211
212 /* UV Image sequence format point */
213 typedef struct PaintUVPoint {
214         /* Pixel / mesh data */
215         unsigned int tri_index, pixel_index;    /* tri index on domain derived mesh */
216         unsigned int v1, v2, v3;                /* vertex indexes */
217
218         unsigned int neighbour_pixel;   /* If this pixel isn't uv mapped to any face, but it's neighboring pixel is */
219 } PaintUVPoint;
220
221 typedef struct ImgSeqFormatData {
222         PaintUVPoint *uv_p;
223         Vec3f *barycentricWeights;      /* b-weights for all pixel samples */
224 } ImgSeqFormatData;
225
226 /* adjacency data flags */
227 #define ADJ_ON_MESH_EDGE (1 << 0)
228 #define ADJ_BORDER_PIXEL (1 << 1)
229
230 typedef struct PaintAdjData {
231         int *n_target;  /* array of neighboring point indexes, for single sample use (n_index + neigh_num) */
232         int *n_index;   /* index to start reading n_target for each point */
233         int *n_num;     /* num of neighs for each point */
234         int *flags;     /* vertex adjacency flags */
235         int total_targets; /* size of n_target */
236         int *border;    /* indices of border pixels (only for texture paint) */
237         int total_border; /* size of border */
238 } PaintAdjData;
239
240 /***************************** General Utils ******************************/
241
242 /* Set canvas error string to display at the bake report */
243 static int setError(DynamicPaintCanvasSettings *canvas, const char *string)
244 {
245         /* Add error to canvas ui info label */
246         BLI_strncpy(canvas->error, string, sizeof(canvas->error));
247         CLOG_STR_ERROR(&LOG, string);
248         return 0;
249 }
250
251 /* Get number of surface points for cached types */
252 static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface)
253 {
254         if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) {
255                 return 0; /* not supported atm */
256         }
257         else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
258                 return (surface->canvas->mesh) ? surface->canvas->mesh->totvert : 0;
259         }
260
261         return 0;
262 }
263
264 /* checks whether surface's format/type has realtime preview */
265 bool dynamicPaint_surfaceHasColorPreview(DynamicPaintSurface *surface)
266 {
267         if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
268                 return false;
269         }
270         else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
271                 return !ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WAVE);
272         }
273
274         return true;
275 }
276
277 /* get currently active surface (in user interface) */
278 DynamicPaintSurface *get_activeSurface(DynamicPaintCanvasSettings *canvas)
279 {
280         return BLI_findlink(&canvas->surfaces, canvas->active_sur);
281 }
282
283 /* set preview to first previewable surface */
284 void dynamicPaint_resetPreview(DynamicPaintCanvasSettings *canvas)
285 {
286         DynamicPaintSurface *surface = canvas->surfaces.first;
287         bool done = false;
288
289         for (; surface; surface = surface->next) {
290                 if (!done && dynamicPaint_surfaceHasColorPreview(surface)) {
291                         surface->flags |= MOD_DPAINT_PREVIEW;
292                         done = true;
293                 }
294                 else {
295                         surface->flags &= ~MOD_DPAINT_PREVIEW;
296                 }
297         }
298 }
299
300 /* set preview to defined surface */
301 static void dynamicPaint_setPreview(DynamicPaintSurface *t_surface)
302 {
303         DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
304         for (; surface; surface = surface->next) {
305                 if (surface == t_surface)
306                         surface->flags |= MOD_DPAINT_PREVIEW;
307                 else
308                         surface->flags &= ~MOD_DPAINT_PREVIEW;
309         }
310 }
311
312 bool dynamicPaint_outputLayerExists(struct DynamicPaintSurface *surface, Object *ob, int output)
313 {
314         const char *name;
315
316         if (output == 0)
317                 name = surface->output_name;
318         else if (output == 1)
319                 name = surface->output_name2;
320         else
321                 return false;
322
323         if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
324                 if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
325                         Mesh *me = ob->data;
326                         return (CustomData_get_named_layer_index(&me->ldata, CD_MLOOPCOL, name) != -1);
327                 }
328                 else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
329                         return (defgroup_name_index(ob, name) != -1);
330                 }
331         }
332
333         return false;
334 }
335
336 static bool surface_duplicateOutputExists(void *arg, const char *name)
337 {
338         DynamicPaintSurface *t_surface = arg;
339         DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
340
341         for (; surface; surface = surface->next) {
342                 if (surface != t_surface && surface->type == t_surface->type && surface->format == t_surface->format) {
343                         if ((surface->output_name[0] != '\0' && !BLI_path_cmp(name, surface->output_name)) ||
344                             (surface->output_name2[0] != '\0' && !BLI_path_cmp(name, surface->output_name2)))
345                         {
346                                 return true;
347                         }
348                 }
349         }
350         return false;
351 }
352
353 static void surface_setUniqueOutputName(DynamicPaintSurface *surface, char *basename, int output)
354 {
355         char name[64];
356         BLI_strncpy(name, basename, sizeof(name)); /* in case basename is surface->name use a copy */
357         if (output == 0) {
358                 BLI_uniquename_cb(surface_duplicateOutputExists, surface, name, '.',
359                                   surface->output_name, sizeof(surface->output_name));
360         }
361         else if (output == 1) {
362                 BLI_uniquename_cb(surface_duplicateOutputExists, surface, name, '.',
363                                   surface->output_name2, sizeof(surface->output_name2));
364         }
365 }
366
367
368 static bool surface_duplicateNameExists(void *arg, const char *name)
369 {
370         DynamicPaintSurface *t_surface = arg;
371         DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
372
373         for (; surface; surface = surface->next) {
374                 if (surface != t_surface && STREQ(name, surface->name))
375                         return true;
376         }
377         return false;
378 }
379
380 void dynamicPaintSurface_setUniqueName(DynamicPaintSurface *surface, const char *basename)
381 {
382         char name[64];
383         BLI_strncpy(name, basename, sizeof(name)); /* in case basename is surface->name use a copy */
384         BLI_uniquename_cb(surface_duplicateNameExists, surface, name, '.', surface->name, sizeof(surface->name));
385 }
386
387
388 /* change surface data to defaults on new type */
389 void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface)
390 {
391         if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
392                 surface->output_name[0] = '\0';
393                 surface->output_name2[0] = '\0';
394                 surface->flags |= MOD_DPAINT_ANTIALIAS;
395                 surface->depth_clamp = 1.0f;
396         }
397         else {
398                 strcpy(surface->output_name, "dp_");
399                 BLI_strncpy(surface->output_name2, surface->output_name, sizeof(surface->output_name2));
400                 surface->flags &= ~MOD_DPAINT_ANTIALIAS;
401                 surface->depth_clamp = 0.0f;
402         }
403
404         if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
405                 strcat(surface->output_name, "paintmap");
406                 strcat(surface->output_name2, "wetmap");
407                 surface_setUniqueOutputName(surface, surface->output_name2, 1);
408         }
409         else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
410                 strcat(surface->output_name, "displace");
411         }
412         else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
413                 strcat(surface->output_name, "weight");
414         }
415         else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
416                 strcat(surface->output_name, "wave");
417         }
418
419         surface_setUniqueOutputName(surface, surface->output_name, 0);
420
421         /* update preview */
422         if (dynamicPaint_surfaceHasColorPreview(surface))
423                 dynamicPaint_setPreview(surface);
424         else
425                 dynamicPaint_resetPreview(surface->canvas);
426 }
427
428 static int surface_totalSamples(DynamicPaintSurface *surface)
429 {
430         if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->flags & MOD_DPAINT_ANTIALIAS) {
431                 return (surface->data->total_points * 5);
432         }
433         if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX &&
434             surface->flags & MOD_DPAINT_ANTIALIAS && surface->data->adj_data)
435         {
436                 return (surface->data->total_points + surface->data->adj_data->total_targets);
437         }
438
439         return surface->data->total_points;
440 }
441
442 static void blendColors(
443         const float t_color[3], const float t_alpha, const float s_color[3], const float s_alpha, float result[4])
444 {
445         /* Same thing as BLI's blend_color_mix_float(), but for non-premultiplied alpha. */
446         int i;
447         float i_alpha = 1.0f - s_alpha;
448         float f_alpha = t_alpha * i_alpha + s_alpha;
449
450         /* blend colors */
451         if (f_alpha) {
452                 for (i = 0; i < 3; i++) {
453                         result[i] = (t_color[i] * t_alpha * i_alpha + s_color[i] * s_alpha) / f_alpha;
454                 }
455         }
456         else {
457                 copy_v3_v3(result, t_color);
458         }
459         /* return final alpha */
460         result[3] = f_alpha;
461 }
462
463 /* Mix two alpha weighed colors by a defined ratio. output is saved at a_color */
464 static float mixColors(float a_color[3], float a_weight, const float b_color[3], float b_weight, float ratio)
465 {
466         float weight_ratio, factor;
467         if (b_weight) {
468                 /* if first value has no weight just use b_color */
469                 if (!a_weight) {
470                         copy_v3_v3(a_color, b_color);
471                         return b_weight * ratio;
472                 }
473                 weight_ratio = b_weight / (a_weight + b_weight);
474         }
475         else {
476                 return a_weight * (1.0f - ratio);
477         }
478
479         /* calculate final interpolation factor */
480         if (ratio <= 0.5f) {
481                 factor = weight_ratio * (ratio * 2.0f);
482         }
483         else {
484                 ratio = (ratio * 2.0f - 1.0f);
485                 factor = weight_ratio * (1.0f - ratio) + ratio;
486         }
487         /* mix final color */
488         interp_v3_v3v3(a_color, a_color, b_color, factor);
489         return (1.0f - factor) * a_weight + factor * b_weight;
490 }
491
492 static void scene_setSubframe(Scene *scene, float subframe)
493 {
494         /* dynamic paint subframes must be done on previous frame */
495         scene->r.cfra -= 1;
496         scene->r.subframe = subframe;
497 }
498
499 static int surface_getBrushFlags(DynamicPaintSurface *surface, Depsgraph *depsgraph)
500 {
501         unsigned int numobjects;
502         Object **objects = BKE_collision_objects_create(depsgraph, NULL, surface->brush_group, &numobjects, eModifierType_DynamicPaint);
503
504         int flags = 0;
505
506         for (int i = 0; i < numobjects; i++) {
507                 Object *brushObj = objects[i];
508
509                 ModifierData *md = modifiers_findByType(brushObj, eModifierType_DynamicPaint);
510                 if (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)) {
511                         DynamicPaintModifierData *pmd2 = (DynamicPaintModifierData *)md;
512
513                         if (pmd2->brush) {
514                                 DynamicPaintBrushSettings *brush = pmd2->brush;
515
516                                 if (brush->flags & MOD_DPAINT_USES_VELOCITY)
517                                         flags |= BRUSH_USES_VELOCITY;
518                         }
519                 }
520         }
521
522         BKE_collision_objects_free(objects);
523
524         return flags;
525 }
526
527 /* check whether two bounds intersect */
528 static bool boundsIntersect(Bounds3D *b1, Bounds3D *b2)
529 {
530         if (!b1->valid || !b2->valid)
531                 return false;
532         for (int i = 2; i--;) {
533                 if (!(b1->min[i] <= b2->max[i] && b1->max[i] >= b2->min[i]))
534                         return false;
535         }
536         return true;
537 }
538
539 /* check whether two bounds intersect inside defined proximity */
540 static bool boundsIntersectDist(Bounds3D *b1, Bounds3D *b2, const float dist)
541 {
542         if (!b1->valid || !b2->valid)
543                 return false;
544         for (int i = 2; i--;) {
545                 if (!(b1->min[i] <= (b2->max[i] + dist) && b1->max[i] >= (b2->min[i] - dist)))
546                         return false;
547         }
548         return true;
549 }
550
551 /* check whether bounds intersects a point with given radius */
552 static bool boundIntersectPoint(Bounds3D *b, float point[3], const float radius)
553 {
554         if (!b->valid)
555                 return false;
556         for (int i = 2; i--;) {
557                 if (!(b->min[i] <= (point[i] + radius) && b->max[i] >= (point[i] - radius)))
558                         return false;
559         }
560         return true;
561 }
562
563 /* expand bounds by a new point */
564 static void boundInsert(Bounds3D *b, float point[3])
565 {
566         if (!b->valid) {
567                 copy_v3_v3(b->min, point);
568                 copy_v3_v3(b->max, point);
569                 b->valid = true;
570                 return;
571         }
572
573         minmax_v3v3_v3(b->min, b->max, point);
574 }
575
576 static float getSurfaceDimension(PaintSurfaceData *sData)
577 {
578         Bounds3D *mb = &sData->bData->mesh_bounds;
579         return max_fff((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
580 }
581
582 static void freeGrid(PaintSurfaceData *data)
583 {
584         PaintBakeData *bData = data->bData;
585         VolumeGrid *grid = bData->grid;
586
587         if (grid->bounds) MEM_freeN(grid->bounds);
588         if (grid->s_pos) MEM_freeN(grid->s_pos);
589         if (grid->s_num) MEM_freeN(grid->s_num);
590         if (grid->t_index) MEM_freeN(grid->t_index);
591
592         MEM_freeN(bData->grid);
593         bData->grid = NULL;
594 }
595
596 static void grid_bound_insert_cb_ex(void *__restrict userdata,
597                                     const int i,
598                                     const ParallelRangeTLS *__restrict tls)
599 {
600         PaintBakeData *bData = userdata;
601
602         Bounds3D *grid_bound = tls->userdata_chunk;
603
604         boundInsert(grid_bound, bData->realCoord[bData->s_pos[i]].v);
605 }
606
607 static void grid_bound_insert_finalize(void *__restrict userdata,
608                                        void *__restrict userdata_chunk)
609 {
610         PaintBakeData *bData = userdata;
611         VolumeGrid *grid = bData->grid;
612
613         Bounds3D *grid_bound = userdata_chunk;
614
615         boundInsert(&grid->grid_bounds, grid_bound->min);
616         boundInsert(&grid->grid_bounds, grid_bound->max);
617 }
618
619 static void grid_cell_points_cb_ex(void *__restrict userdata,
620                                    const int i,
621                                    const ParallelRangeTLS *__restrict tls)
622 {
623         PaintBakeData *bData = userdata;
624         VolumeGrid *grid = bData->grid;
625         int *temp_t_index = grid->temp_t_index;
626         int *s_num = tls->userdata_chunk;
627
628         int co[3];
629
630         for (int j = 3; j--;) {
631                 co[j] = (int)floorf((bData->realCoord[bData->s_pos[i]].v[j] - grid->grid_bounds.min[j]) /
632                                     bData->dim[j] * grid->dim[j]);
633                 CLAMP(co[j], 0, grid->dim[j] - 1);
634         }
635
636         temp_t_index[i] = co[0] + co[1] * grid->dim[0] + co[2] * grid->dim[0] * grid->dim[1];
637         s_num[temp_t_index[i]]++;
638 }
639
640 static void grid_cell_points_finalize(void *__restrict userdata,
641                                       void *__restrict userdata_chunk)
642 {
643         PaintBakeData *bData = userdata;
644         VolumeGrid *grid = bData->grid;
645         const int grid_cells = grid->dim[0] * grid->dim[1] * grid->dim[2];
646
647         int *s_num = userdata_chunk;
648
649         /* calculate grid indexes */
650         for (int i = 0; i < grid_cells; i++) {
651                 grid->s_num[i] += s_num[i];
652         }
653 }
654
655 static void grid_cell_bounds_cb(void *__restrict userdata,
656                                 const int x,
657                                 const ParallelRangeTLS *__restrict UNUSED(tls))
658 {
659         PaintBakeData *bData = userdata;
660         VolumeGrid *grid = bData->grid;
661         float *dim = bData->dim;
662         int *grid_dim = grid->dim;
663
664         for (int y = 0; y < grid_dim[1]; y++) {
665                 for (int z = 0; z < grid_dim[2]; z++) {
666                         const int b_index = x + y * grid_dim[0] + z * grid_dim[0] * grid_dim[1];
667                         /* set bounds */
668                         for (int j = 3; j--;) {
669                                 const int s = (j == 0) ? x : ((j == 1) ? y : z);
670                                 grid->bounds[b_index].min[j] = grid->grid_bounds.min[j] + dim[j] / grid_dim[j] * s;
671                                 grid->bounds[b_index].max[j] = grid->grid_bounds.min[j] + dim[j] / grid_dim[j] * (s + 1);
672                         }
673                         grid->bounds[b_index].valid = true;
674                 }
675         }
676 }
677
678 static void surfaceGenerateGrid(struct DynamicPaintSurface *surface)
679 {
680         PaintSurfaceData *sData = surface->data;
681         PaintBakeData *bData = sData->bData;
682         VolumeGrid *grid;
683         int grid_cells, axis = 3;
684         int *temp_t_index = NULL;
685         int *temp_s_num = NULL;
686
687         if (bData->grid)
688                 freeGrid(sData);
689
690         bData->grid = MEM_callocN(sizeof(VolumeGrid), "Surface Grid");
691         grid = bData->grid;
692
693         {
694                 int i, error = 0;
695                 float dim_factor, volume, dim[3];
696                 float td[3];
697                 float min_dim;
698
699                 /* calculate canvas dimensions */
700                 /* Important to init correctly our ref grid_bound... */
701                 boundInsert(&grid->grid_bounds, bData->realCoord[bData->s_pos[0]].v);
702                 {
703                         ParallelRangeSettings settings;
704                         BLI_parallel_range_settings_defaults(&settings);
705                         settings.use_threading = (sData->total_points > 1000);
706                         settings.userdata_chunk = &grid->grid_bounds;
707                         settings.userdata_chunk_size = sizeof(grid->grid_bounds);
708                         settings.func_finalize = grid_bound_insert_finalize;
709                         BLI_task_parallel_range(
710                                 0, sData->total_points,
711                                 bData,
712                                 grid_bound_insert_cb_ex,
713                                 &settings);
714                 }
715                 /* get dimensions */
716                 sub_v3_v3v3(dim, grid->grid_bounds.max, grid->grid_bounds.min);
717                 copy_v3_v3(td, dim);
718                 copy_v3_v3(bData->dim, dim);
719                 min_dim = max_fff(td[0], td[1], td[2]) / 1000.f;
720
721                 /* deactivate zero axises */
722                 for (i = 0; i < 3; i++) {
723                         if (td[i] < min_dim) {
724                                 td[i] = 1.0f;
725                                 axis--;
726                         }
727                 }
728
729                 if (axis == 0 || max_fff(td[0], td[1], td[2]) < 0.0001f) {
730                         MEM_freeN(bData->grid);
731                         bData->grid = NULL;
732                         return;
733                 }
734
735                 /* now calculate grid volume/area/width depending on num of active axis */
736                 volume = td[0] * td[1] * td[2];
737
738                 /* determine final grid size by trying to fit average 10.000 points per grid cell */
739                 dim_factor = (float)pow((double)volume / ((double)sData->total_points / 10000.0), 1.0 / (double)axis);
740
741                 /* define final grid size using dim_factor, use min 3 for active axises */
742                 for (i = 0; i < 3; i++) {
743                         grid->dim[i] = (int)floor(td[i] / dim_factor);
744                         CLAMP(grid->dim[i], (dim[i] >= min_dim) ? 3 : 1, 100);
745                 }
746                 grid_cells = grid->dim[0] * grid->dim[1] * grid->dim[2];
747
748                 /* allocate memory for grids */
749                 grid->bounds = MEM_callocN(sizeof(Bounds3D) * grid_cells, "Surface Grid Bounds");
750                 grid->s_pos = MEM_callocN(sizeof(int) * grid_cells, "Surface Grid Position");
751
752                 grid->s_num = MEM_callocN(sizeof(int) * grid_cells, "Surface Grid Points");
753                 temp_s_num = MEM_callocN(sizeof(int) * grid_cells, "Temp Surface Grid Points");
754                 grid->t_index = MEM_callocN(sizeof(int) * sData->total_points, "Surface Grid Target Ids");
755                 grid->temp_t_index = temp_t_index = MEM_callocN(sizeof(int) * sData->total_points, "Temp Surface Grid Target Ids");
756
757                 /* in case of an allocation failure abort here */
758                 if (!grid->bounds || !grid->s_pos || !grid->s_num || !grid->t_index || !temp_s_num || !temp_t_index)
759                         error = 1;
760
761                 if (!error) {
762                         /* calculate number of points within each cell */
763                         {
764                                 ParallelRangeSettings settings;
765                                 BLI_parallel_range_settings_defaults(&settings);
766                                 settings.use_threading = (sData->total_points > 1000);
767                                 settings.userdata_chunk = grid->s_num;
768                                 settings.userdata_chunk_size = sizeof(*grid->s_num) * grid_cells;
769                                 settings.func_finalize = grid_cell_points_finalize;
770                                 BLI_task_parallel_range(
771                                         0, sData->total_points,
772                                         bData,
773                                         grid_cell_points_cb_ex,
774                                         &settings);
775                         }
776
777                         /* calculate grid indexes (not needed for first cell, which is zero). */
778                         for (i = 1; i < grid_cells; i++) {
779                                 grid->s_pos[i] = grid->s_pos[i - 1] + grid->s_num[i - 1];
780                         }
781
782                         /* save point indexes to final array */
783                         for (i = 0; i < sData->total_points; i++) {
784                                 int pos = grid->s_pos[temp_t_index[i]] + temp_s_num[temp_t_index[i]];
785                                 grid->t_index[pos] = i;
786
787                                 temp_s_num[temp_t_index[i]]++;
788                         }
789
790                         /* calculate cell bounds */
791                         {
792                                 ParallelRangeSettings settings;
793                                 BLI_parallel_range_settings_defaults(&settings);
794                                 settings.use_threading = (grid_cells > 1000);
795                                 BLI_task_parallel_range(0, grid->dim[0],
796                                                         bData,
797                                                         grid_cell_bounds_cb,
798                                                         &settings);
799                         }
800                 }
801
802                 if (temp_s_num)
803                         MEM_freeN(temp_s_num);
804                 if (temp_t_index)
805                         MEM_freeN(temp_t_index);
806                 grid->temp_t_index = NULL;
807
808                 if (error || !grid->s_num) {
809                         setError(surface->canvas, N_("Not enough free memory"));
810                         freeGrid(sData);
811                 }
812         }
813 }
814
815 /***************************** Freeing data ******************************/
816
817 /* Free brush data */
818 void dynamicPaint_freeBrush(struct DynamicPaintModifierData *pmd)
819 {
820         if (pmd->brush) {
821                 if (pmd->brush->mesh) {
822                         BKE_id_free(NULL, pmd->brush->mesh);
823                 }
824                 pmd->brush->mesh = NULL;
825
826                 if (pmd->brush->paint_ramp)
827                         MEM_freeN(pmd->brush->paint_ramp);
828                 if (pmd->brush->vel_ramp)
829                         MEM_freeN(pmd->brush->vel_ramp);
830
831                 MEM_freeN(pmd->brush);
832                 pmd->brush = NULL;
833         }
834 }
835
836 static void dynamicPaint_freeAdjData(PaintSurfaceData *data)
837 {
838         if (data->adj_data) {
839                 if (data->adj_data->n_index)
840                         MEM_freeN(data->adj_data->n_index);
841                 if (data->adj_data->n_num)
842                         MEM_freeN(data->adj_data->n_num);
843                 if (data->adj_data->n_target)
844                         MEM_freeN(data->adj_data->n_target);
845                 if (data->adj_data->flags)
846                         MEM_freeN(data->adj_data->flags);
847                 if (data->adj_data->border)
848                         MEM_freeN(data->adj_data->border);
849                 MEM_freeN(data->adj_data);
850                 data->adj_data = NULL;
851         }
852 }
853
854 static void free_bakeData(PaintSurfaceData *data)
855 {
856         PaintBakeData *bData = data->bData;
857         if (bData) {
858                 if (bData->bNormal)
859                         MEM_freeN(bData->bNormal);
860                 if (bData->s_pos)
861                         MEM_freeN(bData->s_pos);
862                 if (bData->s_num)
863                         MEM_freeN(bData->s_num);
864                 if (bData->realCoord)
865                         MEM_freeN(bData->realCoord);
866                 if (bData->bNeighs)
867                         MEM_freeN(bData->bNeighs);
868                 if (bData->grid)
869                         freeGrid(data);
870                 if (bData->prev_verts)
871                         MEM_freeN(bData->prev_verts);
872                 if (bData->velocity)
873                         MEM_freeN(bData->velocity);
874                 if (bData->prev_velocity)
875                         MEM_freeN(bData->prev_velocity);
876
877                 MEM_freeN(data->bData);
878                 data->bData = NULL;
879         }
880 }
881
882 /* free surface data if it's not used anymore */
883 static void surface_freeUnusedData(DynamicPaintSurface *surface)
884 {
885         if (!surface->data)
886                 return;
887
888         /* free bakedata if not active or surface is baked */
889         if (!(surface->flags & MOD_DPAINT_ACTIVE) || (surface->pointcache && surface->pointcache->flag & PTCACHE_BAKED)) {
890                 free_bakeData(surface->data);
891         }
892 }
893
894 void dynamicPaint_freeSurfaceData(DynamicPaintSurface *surface)
895 {
896         PaintSurfaceData *data = surface->data;
897         if (!data)
898                 return;
899
900         if (data->format_data) {
901                 /* format specific free */
902                 if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
903                         ImgSeqFormatData *format_data = (ImgSeqFormatData *)data->format_data;
904                         if (format_data->uv_p)
905                                 MEM_freeN(format_data->uv_p);
906                         if (format_data->barycentricWeights)
907                                 MEM_freeN(format_data->barycentricWeights);
908                 }
909                 MEM_freeN(data->format_data);
910         }
911         /* type data */
912         if (data->type_data)
913                 MEM_freeN(data->type_data);
914         dynamicPaint_freeAdjData(data);
915         /* bake data */
916         free_bakeData(data);
917
918         MEM_freeN(surface->data);
919         surface->data = NULL;
920 }
921
922 void dynamicPaint_freeSurface(const DynamicPaintModifierData *pmd,
923                               DynamicPaintSurface *surface)
924 {
925         /* point cache */
926         if ((pmd->modifier.flag & eModifierFlag_SharedCaches) == 0) {
927                 BKE_ptcache_free_list(&(surface->ptcaches));
928         }
929         surface->pointcache = NULL;
930
931         if (surface->effector_weights)
932                 MEM_freeN(surface->effector_weights);
933         surface->effector_weights = NULL;
934
935         BLI_remlink(&(surface->canvas->surfaces), surface);
936         dynamicPaint_freeSurfaceData(surface);
937         MEM_freeN(surface);
938 }
939
940 /* Free canvas data */
941 void dynamicPaint_freeCanvas(DynamicPaintModifierData *pmd)
942 {
943         if (pmd->canvas) {
944                 /* Free surface data */
945                 DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
946                 DynamicPaintSurface *next_surface = NULL;
947
948                 while (surface) {
949                         next_surface = surface->next;
950                         dynamicPaint_freeSurface(pmd, surface);
951                         surface = next_surface;
952                 }
953
954                 /* free mesh copy */
955                 if (pmd->canvas->mesh) {
956                         BKE_id_free(NULL, pmd->canvas->mesh);
957                 }
958                 pmd->canvas->mesh = NULL;
959
960                 MEM_freeN(pmd->canvas);
961                 pmd->canvas = NULL;
962         }
963 }
964
965 /* Free whole dp modifier */
966 void dynamicPaint_Modifier_free(struct DynamicPaintModifierData *pmd)
967 {
968         if (pmd) {
969                 dynamicPaint_freeCanvas(pmd);
970                 dynamicPaint_freeBrush(pmd);
971         }
972 }
973
974
975 /***************************** Initialize and reset ******************************/
976
977 /*
978  * Creates a new surface and adds it to the list
979  * If scene is null, frame range of 1-250 is used
980  * A pointer to this surface is returned
981  */
982 DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *canvas, Scene *scene)
983 {
984         DynamicPaintSurface *surface = MEM_callocN(sizeof(DynamicPaintSurface), "DynamicPaintSurface");
985         if (!surface)
986                 return NULL;
987
988         surface->canvas = canvas;
989         surface->format = MOD_DPAINT_SURFACE_F_VERTEX;
990         surface->type = MOD_DPAINT_SURFACE_T_PAINT;
991
992         /* cache */
993         surface->pointcache = BKE_ptcache_add(&(surface->ptcaches));
994         surface->pointcache->flag |= PTCACHE_DISK_CACHE;
995         surface->pointcache->step = 1;
996
997         /* Set initial values */
998         surface->flags = MOD_DPAINT_ANTIALIAS | MOD_DPAINT_MULALPHA | MOD_DPAINT_DRY_LOG | MOD_DPAINT_DISSOLVE_LOG |
999                          MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW | MOD_DPAINT_OUT1 | MOD_DPAINT_USE_DRYING;
1000         surface->effect = 0;
1001         surface->effect_ui = 1;
1002
1003         surface->diss_speed = 250;
1004         surface->dry_speed = 500;
1005         surface->color_dry_threshold = 1.0f;
1006         surface->depth_clamp = 0.0f;
1007         surface->disp_factor = 1.0f;
1008         surface->disp_type = MOD_DPAINT_DISP_DISPLACE;
1009         surface->image_fileformat = MOD_DPAINT_IMGFORMAT_PNG;
1010
1011         surface->influence_scale = 1.0f;
1012         surface->radius_scale = 1.0f;
1013
1014         surface->init_color[0] = 1.0f;
1015         surface->init_color[1] = 1.0f;
1016         surface->init_color[2] = 1.0f;
1017         surface->init_color[3] = 1.0f;
1018
1019         surface->image_resolution = 256;
1020         surface->substeps = 0;
1021
1022         if (scene) {
1023                 surface->start_frame = scene->r.sfra;
1024                 surface->end_frame = scene->r.efra;
1025         }
1026         else {
1027                 surface->start_frame = 1;
1028                 surface->end_frame = 250;
1029         }
1030
1031         surface->spread_speed = 1.0f;
1032         surface->color_spread_speed = 1.0f;
1033         surface->shrink_speed = 1.0f;
1034
1035         surface->wave_damping = 0.04f;
1036         surface->wave_speed = 1.0f;
1037         surface->wave_timescale = 1.0f;
1038         surface->wave_spring = 0.20f;
1039         surface->wave_smoothness = 1.0f;
1040
1041         modifier_path_init(surface->image_output_path, sizeof(surface->image_output_path), "cache_dynamicpaint");
1042
1043         /* Using ID_BRUSH i18n context, as we have no physics/dpaint one for now... */
1044         dynamicPaintSurface_setUniqueName(surface, CTX_DATA_(BLT_I18NCONTEXT_ID_BRUSH, "Surface"));
1045
1046         surface->effector_weights = BKE_effector_add_weights(NULL);
1047
1048         dynamicPaintSurface_updateType(surface);
1049
1050         BLI_addtail(&canvas->surfaces, surface);
1051
1052         return surface;
1053 }
1054
1055 /*
1056  * Initialize modifier data
1057  */
1058 bool dynamicPaint_createType(struct DynamicPaintModifierData *pmd, int type, struct Scene *scene)
1059 {
1060         if (pmd) {
1061                 if (type == MOD_DYNAMICPAINT_TYPE_CANVAS) {
1062                         DynamicPaintCanvasSettings *canvas;
1063                         if (pmd->canvas)
1064                                 dynamicPaint_freeCanvas(pmd);
1065
1066                         canvas = pmd->canvas = MEM_callocN(sizeof(DynamicPaintCanvasSettings), "DynamicPaint Canvas");
1067                         if (!canvas)
1068                                 return false;
1069                         canvas->pmd = pmd;
1070                         canvas->mesh = NULL;
1071
1072                         /* Create one surface */
1073                         if (!dynamicPaint_createNewSurface(canvas, scene))
1074                                 return false;
1075
1076                 }
1077                 else if (type == MOD_DYNAMICPAINT_TYPE_BRUSH) {
1078                         DynamicPaintBrushSettings *brush;
1079                         if (pmd->brush)
1080                                 dynamicPaint_freeBrush(pmd);
1081
1082                         brush = pmd->brush = MEM_callocN(sizeof(DynamicPaintBrushSettings), "DynamicPaint Paint");
1083                         if (!brush)
1084                                 return false;
1085                         brush->pmd = pmd;
1086
1087                         brush->psys = NULL;
1088
1089                         brush->flags = MOD_DPAINT_ABS_ALPHA | MOD_DPAINT_RAMP_ALPHA;
1090                         brush->collision = MOD_DPAINT_COL_VOLUME;
1091
1092                         brush->r = 0.15f;
1093                         brush->g = 0.4f;
1094                         brush->b = 0.8f;
1095                         brush->alpha = 1.0f;
1096                         brush->wetness = 1.0f;
1097
1098                         brush->paint_distance = 1.0f;
1099                         brush->proximity_falloff = MOD_DPAINT_PRFALL_SMOOTH;
1100
1101                         brush->particle_radius = 0.2f;
1102                         brush->particle_smooth = 0.05f;
1103
1104                         brush->wave_type = MOD_DPAINT_WAVEB_CHANGE;
1105                         brush->wave_factor = 1.0f;
1106                         brush->wave_clamp = 0.0f;
1107                         brush->smudge_strength = 0.3f;
1108                         brush->max_velocity = 1.0f;
1109
1110                         brush->mesh = NULL;
1111
1112                         /* Paint proximity falloff colorramp. */
1113                         {
1114                                 CBData *ramp;
1115
1116                                 brush->paint_ramp = BKE_colorband_add(false);
1117                                 if (!brush->paint_ramp)
1118                                         return false;
1119                                 ramp = brush->paint_ramp->data;
1120                                 /* Add default smooth-falloff ramp. */
1121                                 ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = 1.0f;
1122                                 ramp[0].pos = 0.0f;
1123                                 ramp[1].r = ramp[1].g = ramp[1].b = ramp[1].pos = 1.0f;
1124                                 ramp[1].a = 0.0f;
1125                                 pmd->brush->paint_ramp->tot = 2;
1126                         }
1127
1128                         /* Brush velocity ramp. */
1129                         {
1130                                 CBData *ramp;
1131
1132                                 brush->vel_ramp = BKE_colorband_add(false);
1133                                 if (!brush->vel_ramp)
1134                                         return false;
1135                                 ramp = brush->vel_ramp->data;
1136                                 ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = ramp[0].pos = 0.0f;
1137                                 ramp[1].r = ramp[1].g = ramp[1].b = ramp[1].a = ramp[1].pos = 1.0f;
1138                                 brush->paint_ramp->tot = 2;
1139                         }
1140                 }
1141         }
1142         else {
1143                 return false;
1144         }
1145
1146         return true;
1147 }
1148
1149 void dynamicPaint_Modifier_copy(const struct DynamicPaintModifierData *pmd,
1150                                 struct DynamicPaintModifierData *tpmd,
1151                                 int flag)
1152 {
1153         /* Init modifier */
1154         tpmd->type = pmd->type;
1155         if (pmd->canvas)
1156                 dynamicPaint_createType(tpmd, MOD_DYNAMICPAINT_TYPE_CANVAS, NULL);
1157         if (pmd->brush)
1158                 dynamicPaint_createType(tpmd, MOD_DYNAMICPAINT_TYPE_BRUSH, NULL);
1159
1160         /* Copy data */
1161         if (tpmd->canvas) {
1162                 DynamicPaintSurface *surface;
1163                 tpmd->canvas->pmd = tpmd;
1164                 /* free default surface */
1165                 if (tpmd->canvas->surfaces.first)
1166                         dynamicPaint_freeSurface(tpmd, tpmd->canvas->surfaces.first);
1167
1168                 /* copy existing surfaces */
1169                 for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) {
1170                         DynamicPaintSurface *t_surface = dynamicPaint_createNewSurface(tpmd->canvas, NULL);
1171                         if (flag & LIB_ID_CREATE_NO_MAIN) {
1172                                 /* TODO(sergey): Consider passing some tips to the surface
1173                                  * creation to avoid this allocate-and-free cache behavior. */
1174                                 BKE_ptcache_free_list(&t_surface->ptcaches);
1175                                 tpmd->modifier.flag |= eModifierFlag_SharedCaches;
1176                                 t_surface->ptcaches = surface->ptcaches;
1177                                 t_surface->pointcache = surface->pointcache;
1178                         }
1179
1180                         /* surface settings */
1181                         t_surface->brush_group = surface->brush_group;
1182                         MEM_freeN(t_surface->effector_weights);
1183                         t_surface->effector_weights = MEM_dupallocN(surface->effector_weights);
1184
1185                         BLI_strncpy(t_surface->name, surface->name, sizeof(t_surface->name));
1186                         t_surface->format = surface->format;
1187                         t_surface->type = surface->type;
1188                         t_surface->disp_type = surface->disp_type;
1189                         t_surface->image_fileformat = surface->image_fileformat;
1190                         t_surface->effect_ui = surface->effect_ui;
1191                         t_surface->preview_id = surface->preview_id;
1192                         t_surface->init_color_type = surface->init_color_type;
1193                         t_surface->flags = surface->flags;
1194                         t_surface->effect = surface->effect;
1195
1196                         t_surface->image_resolution = surface->image_resolution;
1197                         t_surface->substeps = surface->substeps;
1198                         t_surface->start_frame = surface->start_frame;
1199                         t_surface->end_frame = surface->end_frame;
1200
1201                         copy_v4_v4(t_surface->init_color, surface->init_color);
1202                         t_surface->init_texture = surface->init_texture;
1203                         BLI_strncpy(t_surface->init_layername, surface->init_layername, sizeof(t_surface->init_layername));
1204
1205                         t_surface->dry_speed = surface->dry_speed;
1206                         t_surface->diss_speed = surface->diss_speed;
1207                         t_surface->color_dry_threshold = surface->color_dry_threshold;
1208                         t_surface->depth_clamp = surface->depth_clamp;
1209                         t_surface->disp_factor = surface->disp_factor;
1210
1211
1212                         t_surface->spread_speed = surface->spread_speed;
1213                         t_surface->color_spread_speed = surface->color_spread_speed;
1214                         t_surface->shrink_speed = surface->shrink_speed;
1215                         t_surface->drip_vel = surface->drip_vel;
1216                         t_surface->drip_acc = surface->drip_acc;
1217
1218                         t_surface->influence_scale = surface->influence_scale;
1219                         t_surface->radius_scale = surface->radius_scale;
1220
1221                         t_surface->wave_damping = surface->wave_damping;
1222                         t_surface->wave_speed = surface->wave_speed;
1223                         t_surface->wave_timescale = surface->wave_timescale;
1224                         t_surface->wave_spring = surface->wave_spring;
1225                         t_surface->wave_smoothness = surface->wave_smoothness;
1226
1227                         BLI_strncpy(t_surface->uvlayer_name, surface->uvlayer_name, sizeof(t_surface->uvlayer_name));
1228                         BLI_strncpy(t_surface->image_output_path, surface->image_output_path, sizeof(t_surface->image_output_path));
1229                         BLI_strncpy(t_surface->output_name, surface->output_name, sizeof(t_surface->output_name));
1230                         BLI_strncpy(t_surface->output_name2, surface->output_name2, sizeof(t_surface->output_name2));
1231                 }
1232                 dynamicPaint_resetPreview(tpmd->canvas);
1233         }
1234         else if (tpmd->brush) {
1235                 DynamicPaintBrushSettings *brush = pmd->brush, *t_brush = tpmd->brush;
1236                 t_brush->pmd = tpmd;
1237
1238                 t_brush->flags = brush->flags;
1239                 t_brush->collision = brush->collision;
1240
1241                 t_brush->r = brush->r;
1242                 t_brush->g = brush->g;
1243                 t_brush->b = brush->b;
1244                 t_brush->alpha = brush->alpha;
1245                 t_brush->wetness = brush->wetness;
1246
1247                 t_brush->particle_radius = brush->particle_radius;
1248                 t_brush->particle_smooth = brush->particle_smooth;
1249                 t_brush->paint_distance = brush->paint_distance;
1250                 t_brush->psys = brush->psys;
1251
1252                 if (brush->paint_ramp)
1253                         memcpy(t_brush->paint_ramp, brush->paint_ramp, sizeof(ColorBand));
1254                 if (brush->vel_ramp)
1255                         memcpy(t_brush->vel_ramp, brush->vel_ramp, sizeof(ColorBand));
1256
1257                 t_brush->proximity_falloff = brush->proximity_falloff;
1258                 t_brush->wave_type = brush->wave_type;
1259                 t_brush->ray_dir = brush->ray_dir;
1260
1261                 t_brush->wave_factor = brush->wave_factor;
1262                 t_brush->wave_clamp = brush->wave_clamp;
1263                 t_brush->max_velocity = brush->max_velocity;
1264                 t_brush->smudge_strength = brush->smudge_strength;
1265         }
1266 }
1267
1268 /* allocates surface data depending on surface type */
1269 static void dynamicPaint_allocateSurfaceType(DynamicPaintSurface *surface)
1270 {
1271         PaintSurfaceData *sData = surface->data;
1272
1273         switch (surface->type) {
1274                 case MOD_DPAINT_SURFACE_T_PAINT:
1275                         sData->type_data = MEM_callocN(sizeof(PaintPoint) * sData->total_points, "DynamicPaintSurface Data");
1276                         break;
1277                 case MOD_DPAINT_SURFACE_T_DISPLACE:
1278                         sData->type_data = MEM_callocN(sizeof(float) * sData->total_points, "DynamicPaintSurface DepthData");
1279                         break;
1280                 case MOD_DPAINT_SURFACE_T_WEIGHT:
1281                         sData->type_data = MEM_callocN(sizeof(float) * sData->total_points, "DynamicPaintSurface WeightData");
1282                         break;
1283                 case MOD_DPAINT_SURFACE_T_WAVE:
1284                         sData->type_data = MEM_callocN(sizeof(PaintWavePoint) * sData->total_points, "DynamicPaintSurface WaveData");
1285                         break;
1286         }
1287
1288         if (sData->type_data == NULL)
1289                 setError(surface->canvas, N_("Not enough free memory"));
1290 }
1291
1292 static bool surface_usesAdjDistance(DynamicPaintSurface *surface)
1293 {
1294         return ((surface->type == MOD_DPAINT_SURFACE_T_PAINT && surface->effect) ||
1295                 (surface->type == MOD_DPAINT_SURFACE_T_WAVE));
1296 }
1297
1298 static bool surface_usesAdjData(DynamicPaintSurface *surface)
1299 {
1300         return (surface_usesAdjDistance(surface) ||
1301                 (surface->format == MOD_DPAINT_SURFACE_F_VERTEX && surface->flags & MOD_DPAINT_ANTIALIAS));
1302 }
1303
1304 /* initialize surface adjacency data */
1305 static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const bool force_init)
1306 {
1307         PaintSurfaceData *sData = surface->data;
1308         Mesh *mesh = surface->canvas->mesh;
1309         PaintAdjData *ad;
1310         int *temp_data;
1311         int neigh_points = 0;
1312
1313         if (!force_init && !surface_usesAdjData(surface))
1314                 return;
1315
1316         if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
1317                 /* For vertex format, neighbors are connected by edges */
1318                 neigh_points = 2 * mesh->totedge;
1319         }
1320         else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
1321                 neigh_points = sData->total_points * 8;
1322         }
1323
1324         if (!neigh_points)
1325                 return;
1326
1327         /* allocate memory */
1328         ad = sData->adj_data = MEM_callocN(sizeof(PaintAdjData), "Surface Adj Data");
1329         if (!ad)
1330                 return;
1331         ad->n_index = MEM_callocN(sizeof(int) * sData->total_points, "Surface Adj Index");
1332         ad->n_num = MEM_callocN(sizeof(int) * sData->total_points, "Surface Adj Counts");
1333         temp_data = MEM_callocN(sizeof(int) * sData->total_points, "Temp Adj Data");
1334         ad->n_target = MEM_callocN(sizeof(int) * neigh_points, "Surface Adj Targets");
1335         ad->flags = MEM_callocN(sizeof(int) * sData->total_points, "Surface Adj Flags");
1336         ad->total_targets = neigh_points;
1337         ad->border = NULL;
1338         ad->total_border = 0;
1339
1340         /* in case of allocation error, free memory */
1341         if (!ad->n_index || !ad->n_num || !ad->n_target || !temp_data) {
1342                 dynamicPaint_freeAdjData(sData);
1343                 if (temp_data)
1344                         MEM_freeN(temp_data);
1345                 setError(surface->canvas, N_("Not enough free memory"));
1346                 return;
1347         }
1348
1349         if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
1350                 int i;
1351                 int n_pos;
1352
1353                 /* For vertex format, count every vertex that is connected by an edge */
1354                 int numOfEdges = mesh->totedge;
1355                 int numOfPolys = mesh->totpoly;
1356                 struct MEdge *edge =  mesh->medge;
1357                 struct MPoly *mpoly = mesh->mpoly;
1358                 struct MLoop *mloop = mesh->mloop;
1359
1360                 /* count number of edges per vertex */
1361                 for (i = 0; i < numOfEdges; i++) {
1362                         ad->n_num[edge[i].v1]++;
1363                         ad->n_num[edge[i].v2]++;
1364
1365                         temp_data[edge[i].v1]++;
1366                         temp_data[edge[i].v2]++;
1367                 }
1368
1369                 /* also add number of vertices to temp_data
1370                  * to locate points on "mesh edge" */
1371                 for (i = 0; i < numOfPolys; i++) {
1372                         for (int j = 0; j < mpoly[i].totloop; j++) {
1373                                 temp_data[mloop[mpoly[i].loopstart + j].v]++;
1374                         }
1375                 }
1376
1377                 /* now check if total number of edges+faces for
1378                  * each vertex is even, if not -> vertex is on mesh edge */
1379                 for (i = 0; i < sData->total_points; i++) {
1380                         if ((temp_data[i] % 2) || (temp_data[i] < 4)) {
1381                                 ad->flags[i] |= ADJ_ON_MESH_EDGE;
1382                         }
1383
1384                         /* reset temp data */
1385                         temp_data[i] = 0;
1386                 }
1387
1388                 /* order n_index array */
1389                 n_pos = 0;
1390                 for (i = 0; i < sData->total_points; i++) {
1391                         ad->n_index[i] = n_pos;
1392                         n_pos += ad->n_num[i];
1393                 }
1394
1395                 /* and now add neighbor data using that info */
1396                 for (i = 0; i < numOfEdges; i++) {
1397                         /* first vertex */
1398                         int index = edge[i].v1;
1399                         n_pos = ad->n_index[index] + temp_data[index];
1400                         ad->n_target[n_pos] = edge[i].v2;
1401                         temp_data[index]++;
1402
1403                         /* second vertex */
1404                         index = edge[i].v2;
1405                         n_pos = ad->n_index[index] + temp_data[index];
1406                         ad->n_target[n_pos] = edge[i].v1;
1407                         temp_data[index]++;
1408                 }
1409         }
1410         else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
1411                 /* for image sequences, only allocate memory.
1412                  * bake initialization takes care of rest */
1413         }
1414
1415         MEM_freeN(temp_data);
1416 }
1417
1418 typedef struct DynamicPaintSetInitColorData {
1419         const DynamicPaintSurface *surface;
1420
1421         const MLoop *mloop;
1422         const MLoopUV *mloopuv;
1423         const MLoopTri *mlooptri;
1424         const MLoopCol *mloopcol;
1425         struct ImagePool *pool;
1426
1427         const bool scene_color_manage;
1428 } DynamicPaintSetInitColorData;
1429
1430 static void dynamic_paint_set_init_color_tex_to_vcol_cb(
1431         void *__restrict userdata,
1432         const int i,
1433         const ParallelRangeTLS *__restrict UNUSED(tls))
1434 {
1435         const DynamicPaintSetInitColorData *data = userdata;
1436
1437         const PaintSurfaceData *sData = data->surface->data;
1438         PaintPoint *pPoint = (PaintPoint *)sData->type_data;
1439
1440         const MLoop *mloop = data->mloop;
1441         const MLoopTri *mlooptri = data->mlooptri;
1442         const MLoopUV *mloopuv = data->mloopuv;
1443         struct ImagePool *pool = data->pool;
1444         Tex *tex = data->surface->init_texture;
1445
1446         const bool scene_color_manage = data->scene_color_manage;
1447
1448         float uv[3] = {0.0f};
1449
1450         for (int j = 3; j--;) {
1451                 TexResult texres = {0};
1452                 const unsigned int vert = mloop[mlooptri[i].tri[j]].v;
1453
1454                 /* remap to [-1.0, 1.0] */
1455                 uv[0] = mloopuv[mlooptri[i].tri[j]].uv[0] * 2.0f - 1.0f;
1456                 uv[1] = mloopuv[mlooptri[i].tri[j]].uv[1] * 2.0f - 1.0f;
1457
1458                 multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage, false);
1459
1460                 if (texres.tin > pPoint[vert].color[3]) {
1461                         copy_v3_v3(pPoint[vert].color, &texres.tr);
1462                         pPoint[vert].color[3] = texres.tin;
1463                 }
1464         }
1465 }
1466
1467 static void dynamic_paint_set_init_color_tex_to_imseq_cb(
1468         void *__restrict userdata,
1469         const int i,
1470         const ParallelRangeTLS *__restrict UNUSED(tls))
1471 {
1472         const DynamicPaintSetInitColorData *data = userdata;
1473
1474         const PaintSurfaceData *sData = data->surface->data;
1475         PaintPoint *pPoint = (PaintPoint *)sData->type_data;
1476
1477         const MLoopTri *mlooptri = data->mlooptri;
1478         const MLoopUV *mloopuv = data->mloopuv;
1479         Tex *tex = data->surface->init_texture;
1480         ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data;
1481         const int samples = (data->surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
1482
1483         const bool scene_color_manage = data->scene_color_manage;
1484
1485         float uv[9] = {0.0f};
1486         float uv_final[3] = {0.0f};
1487
1488         TexResult texres = {0};
1489
1490         /* collect all uvs */
1491         for (int j = 3; j--;) {
1492                 copy_v2_v2(&uv[j * 3], mloopuv[mlooptri[f_data->uv_p[i].tri_index].tri[j]].uv);
1493         }
1494
1495         /* interpolate final uv pos */
1496         interp_v3_v3v3v3(uv_final, &uv[0], &uv[3], &uv[6], f_data->barycentricWeights[i * samples].v);
1497         /* remap to [-1.0, 1.0] */
1498         uv_final[0] = uv_final[0] * 2.0f - 1.0f;
1499         uv_final[1] = uv_final[1] * 2.0f - 1.0f;
1500
1501         multitex_ext_safe(tex, uv_final, &texres, NULL, scene_color_manage, false);
1502
1503         /* apply color */
1504         copy_v3_v3(pPoint[i].color, &texres.tr);
1505         pPoint[i].color[3] = texres.tin;
1506 }
1507
1508 static void dynamic_paint_set_init_color_vcol_to_imseq_cb(
1509         void *__restrict userdata,
1510         const int i,
1511         const ParallelRangeTLS *__restrict UNUSED(tls))
1512 {
1513         const DynamicPaintSetInitColorData *data = userdata;
1514
1515         const PaintSurfaceData *sData = data->surface->data;
1516         PaintPoint *pPoint = (PaintPoint *)sData->type_data;
1517
1518         const MLoopTri *mlooptri = data->mlooptri;
1519         const MLoopCol *mloopcol = data->mloopcol;
1520         ImgSeqFormatData *f_data = (ImgSeqFormatData *)sData->format_data;
1521         const int samples = (data->surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
1522
1523         const int tri_idx = f_data->uv_p[i].tri_index;
1524         float colors[3][4];
1525         float final_color[4];
1526
1527         /* collect color values */
1528         for (int j = 3; j--;) {
1529                 rgba_uchar_to_float(colors[j], (const unsigned char *)&mloopcol[mlooptri[tri_idx].tri[j]].r);
1530         }
1531
1532         /* interpolate final color */
1533         interp_v4_v4v4v4(final_color, UNPACK3(colors), f_data->barycentricWeights[i * samples].v);
1534
1535         copy_v4_v4(pPoint[i].color, final_color);
1536 }
1537
1538 static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface *surface)
1539 {
1540         PaintSurfaceData *sData = surface->data;
1541         PaintPoint *pPoint = (PaintPoint *)sData->type_data;
1542         Mesh *mesh = surface->canvas->mesh;
1543         int i;
1544         const bool scene_color_manage = BKE_scene_check_color_management_enabled(scene);
1545
1546         if (surface->type != MOD_DPAINT_SURFACE_T_PAINT)
1547                 return;
1548
1549         if (surface->init_color_type == MOD_DPAINT_INITIAL_NONE)
1550                 return;
1551
1552         /* Single color */
1553         if (surface->init_color_type == MOD_DPAINT_INITIAL_COLOR) {
1554                 /* apply color to every surface point */
1555                 for (i = 0; i < sData->total_points; i++) {
1556                         copy_v4_v4(pPoint[i].color, surface->init_color);
1557                 }
1558         }
1559         /* UV mapped texture */
1560         else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) {
1561                 Tex *tex = surface->init_texture;
1562
1563                 const MLoop *mloop = mesh->mloop;
1564                 const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
1565                 const int tottri = BKE_mesh_runtime_looptri_len(mesh);
1566                 const MLoopUV *mloopuv = NULL;
1567
1568                 char uvname[MAX_CUSTOMDATA_LAYER_NAME];
1569
1570                 if (!tex)
1571                         return;
1572
1573                 /* get uv map */
1574                 CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, surface->init_layername, uvname);
1575                 mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname);
1576                 if (!mloopuv)
1577                         return;
1578
1579                 /* for vertex surface loop through tfaces and find uv color
1580                  * that provides highest alpha */
1581                 if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
1582                         struct ImagePool *pool = BKE_image_pool_new();
1583
1584                         DynamicPaintSetInitColorData data = {
1585                             .surface = surface,
1586                             .mloop = mloop, .mlooptri = mlooptri, .mloopuv = mloopuv, .pool = pool,
1587                             .scene_color_manage = scene_color_manage,
1588                         };
1589                         ParallelRangeSettings settings;
1590                         BLI_parallel_range_settings_defaults(&settings);
1591                         settings.use_threading = (tottri > 1000);
1592                         BLI_task_parallel_range(0, tottri,
1593                                                 &data,
1594                                                 dynamic_paint_set_init_color_tex_to_vcol_cb,
1595                                                 &settings);
1596                         BKE_image_pool_free(pool);
1597                 }
1598                 else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
1599                         DynamicPaintSetInitColorData data = {
1600                             .surface = surface,
1601                             .mlooptri = mlooptri, .mloopuv = mloopuv,
1602                             .scene_color_manage = scene_color_manage,
1603                         };
1604                         ParallelRangeSettings settings;
1605                         BLI_parallel_range_settings_defaults(&settings);
1606                         settings.use_threading = (sData->total_points > 1000);
1607                         BLI_task_parallel_range(0, sData->total_points,
1608                                                 &data,
1609                                                 dynamic_paint_set_init_color_tex_to_imseq_cb,
1610                                                 &settings);
1611                 }
1612         }
1613         /* vertex color layer */
1614         else if (surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR) {
1615
1616                 /* for vertex surface, just copy colors from mcol */
1617                 if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
1618                         const MLoop *mloop = mesh->mloop;
1619                         const int totloop = mesh->totloop;
1620                         const MLoopCol *col = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPCOL, surface->init_layername);
1621                         if (!col)
1622                                 return;
1623
1624                         for (i = 0; i < totloop; i++) {
1625                                 rgba_uchar_to_float(pPoint[mloop[i].v].color, (const unsigned char *)&col[mloop[i].v].r);
1626                         }
1627                 }
1628                 else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
1629                         const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
1630                         MLoopCol *col = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPCOL, surface->init_layername);
1631                         if (!col)
1632                                 return;
1633
1634                         DynamicPaintSetInitColorData data = {
1635                             .surface = surface,
1636                             .mlooptri = mlooptri, .mloopcol = col,
1637                         };
1638                         ParallelRangeSettings settings;
1639                         BLI_parallel_range_settings_defaults(&settings);
1640                         settings.use_threading = (sData->total_points > 1000);
1641                         BLI_task_parallel_range(0, sData->total_points,
1642                                                 &data,
1643                                                 dynamic_paint_set_init_color_vcol_to_imseq_cb,
1644                                                 &settings);
1645                 }
1646         }
1647 }
1648
1649 /* clears surface data back to zero */
1650 void dynamicPaint_clearSurface(const Scene *scene, DynamicPaintSurface *surface)
1651 {
1652         PaintSurfaceData *sData = surface->data;
1653         if (sData && sData->type_data) {
1654                 unsigned int data_size;
1655
1656                 if (surface->type == MOD_DPAINT_SURFACE_T_PAINT)
1657                         data_size = sizeof(PaintPoint);
1658                 else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE)
1659                         data_size = sizeof(PaintWavePoint);
1660                 else
1661                         data_size = sizeof(float);
1662
1663                 memset(sData->type_data, 0, data_size * sData->total_points);
1664
1665                 /* set initial color */
1666                 if (surface->type == MOD_DPAINT_SURFACE_T_PAINT)
1667                         dynamicPaint_setInitialColor(scene, surface);
1668
1669                 if (sData->bData)
1670                         sData->bData->clear = 1;
1671         }
1672 }
1673
1674 /* completely (re)initializes surface (only for point cache types)*/
1675 bool dynamicPaint_resetSurface(const Scene *scene, DynamicPaintSurface *surface)
1676 {
1677         int numOfPoints = dynamicPaint_surfaceNumOfPoints(surface);
1678         /* free existing data */
1679         if (surface->data)
1680                 dynamicPaint_freeSurfaceData(surface);
1681
1682         /* don't reallocate for image sequence types. they get handled only on bake */
1683         if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ)
1684                 return true;
1685         if (numOfPoints < 1)
1686                 return false;
1687
1688         /* allocate memory */
1689         surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData");
1690         if (!surface->data)
1691                 return false;
1692
1693         /* allocate data depending on surface type and format */
1694         surface->data->total_points = numOfPoints;
1695         dynamicPaint_allocateSurfaceType(surface);
1696         dynamicPaint_initAdjacencyData(surface, false);
1697
1698         /* set initial color */
1699         if (surface->type == MOD_DPAINT_SURFACE_T_PAINT)
1700                 dynamicPaint_setInitialColor(scene, surface);
1701
1702         return true;
1703 }
1704
1705 /* make sure allocated surface size matches current requirements */
1706 static bool dynamicPaint_checkSurfaceData(const Scene *scene, DynamicPaintSurface *surface)
1707 {
1708         if (!surface->data || ((dynamicPaint_surfaceNumOfPoints(surface) != surface->data->total_points))) {
1709                 return dynamicPaint_resetSurface(scene, surface);
1710         }
1711         return true;
1712 }
1713
1714
1715 /***************************** Modifier processing ******************************/
1716
1717 typedef struct DynamicPaintModifierApplyData {
1718         const DynamicPaintSurface *surface;
1719         Object *ob;
1720
1721         MVert *mvert;
1722         const MLoop *mloop;
1723         const MPoly *mpoly;
1724
1725         float (*fcolor)[4];
1726         MLoopCol *mloopcol;
1727         MLoopCol *mloopcol_wet;
1728         MLoopCol *mloopcol_preview;
1729 } DynamicPaintModifierApplyData;
1730
1731 static void dynamic_paint_apply_surface_displace_cb(
1732         void *__restrict userdata,
1733         const int i,
1734         const ParallelRangeTLS *__restrict UNUSED(tls))
1735 {
1736         const DynamicPaintModifierApplyData *data = userdata;
1737
1738         const DynamicPaintSurface *surface = data->surface;
1739         MVert *mvert = data->mvert;
1740
1741         float normal[3];
1742         const float *value = (float *)surface->data->type_data;
1743         const float val = value[i] * surface->disp_factor;
1744
1745         normal_short_to_float_v3(normal, mvert[i].no);
1746
1747         /* same as 'mvert[i].co[0] -= normal[0] * val' etc. */
1748         madd_v3_v3fl(mvert[i].co, normal, -val);
1749 }
1750
1751 /* apply displacing vertex surface to the derived mesh */
1752 static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Mesh *result)
1753 {
1754         PaintSurfaceData *sData = surface->data;
1755
1756         if (!sData || surface->format != MOD_DPAINT_SURFACE_F_VERTEX)
1757                 return;
1758
1759         /* displace paint */
1760         if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
1761                 MVert *mvert = result->mvert;
1762
1763                 DynamicPaintModifierApplyData data = { .surface = surface, .mvert = mvert, };
1764                 ParallelRangeSettings settings;
1765                 BLI_parallel_range_settings_defaults(&settings);
1766                 settings.use_threading = (sData->total_points > 10000);
1767                 BLI_task_parallel_range(0, sData->total_points,
1768                                         &data,
1769                                         dynamic_paint_apply_surface_displace_cb,
1770                                         &settings);
1771         }
1772 }
1773
1774 static void dynamic_paint_apply_surface_vpaint_blend_cb(
1775         void *__restrict userdata,
1776         const int i,
1777         const ParallelRangeTLS *__restrict UNUSED(tls))
1778 {
1779         const DynamicPaintModifierApplyData *data = userdata;
1780
1781         PaintPoint *pPoint = (PaintPoint *)data->surface->data->type_data;
1782         float (*fcolor)[4] = data->fcolor;
1783
1784         /* blend dry and wet layer */
1785         blendColors(pPoint[i].color, pPoint[i].color[3], pPoint[i].e_color, pPoint[i].e_color[3], fcolor[i]);
1786 }
1787
1788 static void dynamic_paint_apply_surface_vpaint_cb(
1789         void *__restrict userdata,
1790         const int p_index,
1791         const ParallelRangeTLS *__restrict UNUSED(tls))
1792 {
1793         const DynamicPaintModifierApplyData *data = userdata;
1794         Object *ob = data->ob;
1795
1796         const MLoop *mloop = data->mloop;
1797         const MPoly *mpoly = data->mpoly;
1798
1799         const DynamicPaintSurface *surface = data->surface;
1800         PaintPoint *pPoint = (PaintPoint *)surface->data->type_data;
1801         float (*fcolor)[4] = data->fcolor;
1802
1803         MLoopCol *mloopcol = data->mloopcol;
1804         MLoopCol *mloopcol_wet = data->mloopcol_wet;
1805         MLoopCol *mloopcol_preview = data->mloopcol_preview;
1806
1807         const Material *material = mloopcol_preview ?
1808                                        give_current_material(ob, mpoly[p_index].mat_nr + 1) : NULL;
1809
1810         for (int j = 0; j < mpoly[p_index].totloop; j++) {
1811                 const int l_index = mpoly[p_index].loopstart + j;
1812                 const int v_index = mloop[l_index].v;
1813
1814                 /* save layer data to output layer */
1815                 /* apply color */
1816                 if (mloopcol) {
1817                         rgba_float_to_uchar((unsigned char *)&mloopcol[l_index].r, fcolor[v_index]);
1818                 }
1819                 /* apply wetness */
1820                 if (mloopcol_wet) {
1821                         const char c = unit_float_to_uchar_clamp(pPoint[v_index].wetness);
1822                         mloopcol_wet[l_index].r = c;
1823                         mloopcol_wet[l_index].g = c;
1824                         mloopcol_wet[l_index].b = c;
1825                         mloopcol_wet[l_index].a = 255;
1826                 }
1827
1828                 /* viewport preview */
1829                 if (mloopcol_preview) {
1830                         if (surface->preview_id == MOD_DPAINT_SURFACE_PREV_PAINT) {
1831                                 float c[3];
1832
1833                                 /* Apply material color as base vertex color for preview */
1834                                 mloopcol_preview[l_index].a = 255;
1835                                 if (material) {
1836                                         c[0] = material->r;
1837                                         c[1] = material->g;
1838                                         c[2] = material->b;
1839                                 }
1840                                 else { /* default gray */
1841                                         c[0] = 0.65f;
1842                                         c[1] = 0.65f;
1843                                         c[2] = 0.65f;
1844                                 }
1845                                 /* mix surface color */
1846                                 interp_v3_v3v3(c, c, fcolor[v_index], fcolor[v_index][3]);
1847
1848                                 rgb_float_to_uchar((unsigned char *)&mloopcol_preview[l_index].r, c);
1849                         }
1850                         else {
1851                                 const char c = unit_float_to_uchar_clamp(pPoint[v_index].wetness);
1852                                 mloopcol_preview[l_index].r = c;
1853                                 mloopcol_preview[l_index].g = c;
1854                                 mloopcol_preview[l_index].b = c;
1855                                 mloopcol_preview[l_index].a = 255;
1856                         }
1857                 }
1858         }
1859 }
1860
1861 static void dynamic_paint_apply_surface_wave_cb(
1862         void *__restrict userdata,
1863         const int i,
1864         const ParallelRangeTLS *__restrict UNUSED(tls))
1865 {
1866         const DynamicPaintModifierApplyData *data = userdata;
1867
1868         PaintWavePoint *wPoint = (PaintWavePoint *)data->surface->data->type_data;
1869         MVert *mvert = data->mvert;
1870         float normal[3];
1871
1872         normal_short_to_float_v3(normal, mvert[i].no);
1873         madd_v3_v3fl(mvert[i].co, normal, wPoint[i].height);
1874 }
1875
1876 /*
1877  * Apply canvas data to the object derived mesh
1878  */
1879 static Mesh *dynamicPaint_Modifier_apply(
1880         DynamicPaintModifierData *pmd, Object *ob, Mesh *mesh)
1881 {
1882         Mesh *result = BKE_mesh_copy_for_eval(mesh, false);
1883
1884         if (pmd->canvas && !(pmd->canvas->flags & MOD_DPAINT_BAKING)) {
1885
1886                 DynamicPaintSurface *surface;
1887                 bool update_normals = false;
1888
1889                 /* loop through surfaces */
1890                 for (surface = pmd->canvas->surfaces.first; surface; surface = surface->next) {
1891                         PaintSurfaceData *sData = surface->data;
1892
1893                         if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && sData) {
1894                                 if (!(surface->flags & MOD_DPAINT_ACTIVE))
1895                                         continue;
1896
1897                                 /* process vertex surface previews */
1898                                 if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
1899
1900                                         /* vertex color paint */
1901                                         if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
1902                                                 MLoop *mloop = result->mloop;
1903                                                 const int totloop = result->totloop;
1904                                                 MPoly *mpoly = result->mpoly;
1905                                                 const int totpoly = result->totpoly;
1906
1907                                                 /* paint is stored on dry and wet layers, so mix final color first */
1908                                                 float (*fcolor)[4] = MEM_callocN(sizeof(*fcolor) * sData->total_points, "Temp paint color");
1909
1910                                                 DynamicPaintModifierApplyData data = { .surface = surface, .fcolor = fcolor, };
1911                                                 {
1912                                                         ParallelRangeSettings settings;
1913                                                         BLI_parallel_range_settings_defaults(&settings);
1914                                                         settings.use_threading = (sData->total_points > 1000);
1915                                                         BLI_task_parallel_range(
1916                                                                 0, sData->total_points,
1917                                                                 &data,
1918                                                                 dynamic_paint_apply_surface_vpaint_blend_cb,
1919                                                                 &settings);
1920                                                 }
1921
1922                                                 /* paint layer */
1923                                                 MLoopCol *mloopcol = CustomData_get_layer_named(&result->ldata, CD_MLOOPCOL, surface->output_name);
1924                                                 /* if output layer is lost from a constructive modifier, re-add it */
1925                                                 if (!mloopcol && dynamicPaint_outputLayerExists(surface, ob, 0)) {
1926                                                         mloopcol = CustomData_add_layer_named(
1927                                                                 &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, surface->output_name);
1928                                                 }
1929
1930                                                 /* wet layer */
1931                                                 MLoopCol *mloopcol_wet = CustomData_get_layer_named(&result->ldata, CD_MLOOPCOL, surface->output_name2);
1932                                                 /* if output layer is lost from a constructive modifier, re-add it */
1933                                                 if (!mloopcol_wet && dynamicPaint_outputLayerExists(surface, ob, 1)) {
1934                                                         mloopcol_wet = CustomData_add_layer_named(
1935                                                                 &result->ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, surface->output_name2);
1936                                                 }
1937
1938                                                 /* Save preview results to weight layer to be able to share same drawing methods */
1939                                                 MLoopCol *mloopcol_preview = NULL;
1940                                                 if (surface->flags & MOD_DPAINT_PREVIEW) {
1941                                                         mloopcol_preview = CustomData_get_layer(&result->ldata, CD_PREVIEW_MLOOPCOL);
1942                                                         if (!mloopcol_preview) {
1943                                                                 mloopcol_preview = CustomData_add_layer(
1944                                                                         &result->ldata, CD_PREVIEW_MLOOPCOL, CD_CALLOC, NULL, totloop);
1945                                                         }
1946                                                 }
1947
1948                                                 data.ob = ob;
1949                                                 data.mloop = mloop;
1950                                                 data.mpoly = mpoly;
1951                                                 data.mloopcol = mloopcol;
1952                                                 data.mloopcol_wet = mloopcol_wet;
1953                                                 data.mloopcol_preview = mloopcol_preview;
1954
1955                                                 {
1956                                                         ParallelRangeSettings settings;
1957                                                         BLI_parallel_range_settings_defaults(&settings);
1958                                                         settings.use_threading = (totpoly > 1000);
1959                                                         BLI_task_parallel_range(
1960                                                                 0, totpoly,
1961                                                                 &data,
1962                                                                 dynamic_paint_apply_surface_vpaint_cb,
1963                                                                 &settings);
1964                                                 }
1965
1966                                                 MEM_freeN(fcolor);
1967
1968                                                 /* Mark tessellated CD layers as dirty. */
1969                                                 //result->dirty |= DM_DIRTY_TESS_CDLAYERS;
1970                                         }
1971                                         /* vertex group paint */
1972                                         else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
1973                                                 int defgrp_index = defgroup_name_index(ob, surface->output_name);
1974                                                 MDeformVert *dvert = CustomData_get_layer(&result->vdata, CD_MDEFORMVERT);
1975                                                 float *weight = (float *)sData->type_data;
1976
1977                                                 /* viewport preview */
1978                                                 if (surface->flags & MOD_DPAINT_PREVIEW) {
1979                                                         /* Save preview results to weight layer to be
1980                                                          * able to share same drawing methods.
1981                                                          * Note this func also sets DM_DIRTY_TESS_CDLAYERS flag! */
1982                                                         //TODO port this function
1983                                                         //DM_update_weight_mcol(ob, result, 0, weight, 0, NULL);
1984                                                 }
1985
1986                                                 /* apply weights into a vertex group, if doesn't exists add a new layer */
1987                                                 if (defgrp_index != -1 && !dvert && (surface->output_name[0] != '\0')) {
1988                                                         dvert = CustomData_add_layer(&result->vdata, CD_MDEFORMVERT, CD_CALLOC,
1989                                                                                      NULL, sData->total_points);
1990                                                 }
1991                                                 if (defgrp_index != -1 && dvert) {
1992                                                         int i;
1993                                                         for (i = 0; i < sData->total_points; i++) {
1994                                                                 MDeformVert *dv = &dvert[i];
1995                                                                 MDeformWeight *def_weight = defvert_find_index(dv, defgrp_index);
1996
1997                                                                 /* skip if weight value is 0 and no existing weight is found */
1998                                                                 if ((def_weight != NULL) || (weight[i] != 0.0f)) {
1999                                                                         /* if not found, add a weight for it */
2000                                                                         if (def_weight == NULL) {
2001                                                                                 def_weight = defvert_verify_index(dv, defgrp_index);
2002                                                                         }
2003
2004                                                                         /* set weight value */
2005                                                                         def_weight->weight = weight[i];
2006                                                                 }
2007                                                         }
2008                                                 }
2009                                         }
2010                                         /* wave simulation */
2011                                         else if (surface->type == MOD_DPAINT_SURFACE_T_WAVE) {
2012                                                 MVert *mvert = result->mvert;
2013
2014                                                 DynamicPaintModifierApplyData data = { .surface = surface, .mvert = mvert, };
2015                                                 ParallelRangeSettings settings;
2016                                                 BLI_parallel_range_settings_defaults(&settings);
2017                                                 settings.use_threading = (sData->total_points > 1000);
2018                                                 BLI_task_parallel_range(
2019                                                         0, sData->total_points,
2020                                                         &data,
2021                                                         dynamic_paint_apply_surface_wave_cb,
2022                                                         &settings);
2023                                                 update_normals = true;
2024                                         }
2025
2026                                         /* displace */
2027                                         if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
2028                                                 dynamicPaint_applySurfaceDisplace(surface, result);
2029                                                 update_normals = true;
2030                                         }
2031                                 }
2032                         }
2033                 }
2034
2035                 if (update_normals) {
2036                         //result->dirty |= DM_DIRTY_NORMALS;
2037                 }
2038         }
2039         /* make a copy of mesh to use as brush data */
2040         if (pmd->brush) {
2041                 if (pmd->brush->mesh) {
2042                         BKE_id_free(NULL, pmd->brush->mesh);
2043                 }
2044                 pmd->brush->mesh = BKE_mesh_copy_for_eval(result, false);
2045         }
2046
2047         return result;
2048 }
2049
2050 /* update cache frame range */
2051 void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface)
2052 {
2053         if (surface->pointcache) {
2054                 surface->pointcache->startframe = surface->start_frame;
2055                 surface->pointcache->endframe = surface->end_frame;
2056         }
2057 }
2058
2059 static void canvas_copyMesh(DynamicPaintCanvasSettings *canvas, Mesh *mesh)
2060 {
2061         if (canvas->mesh) {
2062                 BKE_id_free(NULL, canvas->mesh);
2063         }
2064
2065         canvas->mesh = BKE_mesh_copy_for_eval(mesh, false);
2066 }
2067
2068 /*
2069  * Updates derived mesh copy and processes dynamic paint step / caches.
2070  */
2071 static void dynamicPaint_frameUpdate(
2072         DynamicPaintModifierData *pmd, struct Depsgraph *depsgraph, Scene *scene,
2073         Object *ob, Mesh *mesh)
2074 {
2075         if (pmd->canvas) {
2076                 DynamicPaintCanvasSettings *canvas = pmd->canvas;
2077                 DynamicPaintSurface *surface = canvas->surfaces.first;
2078
2079                 /* update derived mesh copy */
2080                 canvas_copyMesh(canvas, mesh);
2081
2082                 /* in case image sequence baking, stop here */
2083                 if (canvas->flags & MOD_DPAINT_BAKING)
2084                         return;
2085
2086                 /* loop through surfaces */
2087                 for (; surface; surface = surface->next) {
2088                         int current_frame = (int)scene->r.cfra;
2089                         bool no_surface_data;
2090
2091                         /* free bake data if not required anymore */
2092                         surface_freeUnusedData(surface);
2093
2094                         /* image sequences are handled by bake operator */
2095                         if ((surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) || !(surface->flags & MOD_DPAINT_ACTIVE))
2096                                 continue;
2097
2098                         /* make sure surface is valid */
2099                         no_surface_data = surface->data == NULL;
2100                         if (!dynamicPaint_checkSurfaceData(scene, surface))
2101                                 continue;
2102
2103                         /* limit frame range */
2104                         CLAMP(current_frame, surface->start_frame, surface->end_frame);
2105
2106                         if (no_surface_data || current_frame != surface->current_frame ||
2107                             (int)scene->r.cfra == surface->start_frame)
2108                         {
2109                                 PointCache *cache = surface->pointcache;
2110                                 PTCacheID pid;
2111                                 surface->current_frame = current_frame;
2112
2113                                 /* read point cache */
2114                                 BKE_ptcache_id_from_dynamicpaint(&pid, ob, surface);
2115                                 pid.cache->startframe = surface->start_frame;
2116                                 pid.cache->endframe = surface->end_frame;
2117                                 BKE_ptcache_id_time(&pid, scene, (float)scene->r.cfra, NULL, NULL, NULL);
2118
2119                                 /* reset non-baked cache at first frame */
2120                                 if ((int)scene->r.cfra == surface->start_frame && !(cache->flag & PTCACHE_BAKED)) {
2121                                         cache->flag |= PTCACHE_REDO_NEEDED;
2122                                         BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
2123                                         cache->flag &= ~PTCACHE_REDO_NEEDED;
2124                                 }
2125
2126                                 /* try to read from cache */
2127                                 bool can_simulate = ((int)scene->r.cfra == current_frame) && !(cache->flag & PTCACHE_BAKED);
2128
2129                                 if (BKE_ptcache_read(&pid, (float)scene->r.cfra, can_simulate)) {
2130                                         BKE_ptcache_validate(cache, (int)scene->r.cfra);
2131                                 }
2132                                 /* if read failed and we're on surface range do recalculate */
2133                                 else if (can_simulate) {
2134                                         /* calculate surface frame */
2135                                         canvas->flags |= MOD_DPAINT_BAKING;
2136                                         dynamicPaint_calculateFrame(surface, depsgraph, scene, ob, current_frame);
2137                                         canvas->flags &= ~MOD_DPAINT_BAKING;
2138
2139                                         /* restore canvas mesh if required */
2140                                         if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE &&
2141                                             surface->flags & MOD_DPAINT_DISP_INCREMENTAL && surface->next)
2142                                         {
2143                                                 canvas_copyMesh(canvas, mesh);
2144                                         }
2145
2146                                         BKE_ptcache_validate(cache, surface->current_frame);
2147                                         BKE_ptcache_write(&pid, surface->current_frame);
2148                                 }
2149                         }
2150                 }
2151         }
2152 }
2153
2154 /* Modifier call. Processes dynamic paint modifier step. */
2155 Mesh *dynamicPaint_Modifier_do(
2156         DynamicPaintModifierData *pmd, struct Depsgraph *depsgraph, Scene *scene,
2157         Object *ob, Mesh *mesh)
2158 {
2159         if (pmd->canvas) {
2160                 Mesh *ret;
2161
2162                 /* Update canvas data for a new frame */
2163                 dynamicPaint_frameUpdate(pmd, depsgraph, scene, ob, mesh);
2164
2165                 /* Return output mesh */
2166                 ret = dynamicPaint_Modifier_apply(pmd, ob, mesh);
2167
2168                 return ret;
2169         }
2170         else {
2171                 /* Update canvas data for a new frame */
2172                 dynamicPaint_frameUpdate(pmd, depsgraph, scene, ob, mesh);
2173
2174                 /* Return output mesh */
2175                 return dynamicPaint_Modifier_apply(pmd, ob, mesh);
2176         }
2177 }
2178
2179
2180 /***************************** Image Sequence / UV Image Surface Calls ******************************/
2181
2182 /*
2183  * Create a surface for uv image sequence format
2184  */
2185 #define JITTER_SAMPLES { \
2186         0.0f, 0.0f, \
2187         -0.2f, -0.4f, \
2188         0.2f, 0.4f, \
2189         0.4f, -0.2f, \
2190         -0.4f, 0.3f, \
2191 }
2192
2193 typedef struct DynamicPaintCreateUVSurfaceData {
2194         const DynamicPaintSurface *surface;
2195
2196         PaintUVPoint *tempPoints;
2197         Vec3f *tempWeights;
2198
2199         const MLoopTri *mlooptri;
2200         const MLoopUV *mloopuv;
2201         const MLoop *mloop;
2202         const int tottri;
2203
2204         const Bounds2D *faceBB;
2205         uint32_t *active_points;
2206 } DynamicPaintCreateUVSurfaceData;
2207
2208 static void dynamic_paint_create_uv_surface_direct_cb(
2209         void *__restrict userdata,
2210         const int ty,
2211         const ParallelRangeTLS *__restrict UNUSED(tls))
2212 {
2213         const DynamicPaintCreateUVSurfaceData *data = userdata;
2214
2215         const DynamicPaintSurface *surface = data->surface;
2216         PaintUVPoint *tempPoints = data->tempPoints;
2217         Vec3f *tempWeights = data->tempWeights;
2218
2219         const MLoopTri *mlooptri = data->mlooptri;
2220         const MLoopUV *mloopuv = data->mloopuv;
2221         const MLoop *mloop = data->mloop;
2222         const int tottri = data->tottri;
2223
2224         const Bounds2D *faceBB = data->faceBB;
2225
2226         const float jitter5sample[10] = JITTER_SAMPLES;
2227         const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
2228         const int w = surface->image_resolution;
2229         const int h = w;
2230
2231         for (int tx = 0; tx < w; tx++) {
2232                 const int index = tx + w * ty;
2233                 PaintUVPoint *tPoint = &tempPoints[index];
2234                 float point[5][2];
2235
2236                 /* Init per pixel settings */
2237                 tPoint->tri_index = -1;
2238                 tPoint->neighbour_pixel = -1;
2239                 tPoint->pixel_index = index;
2240
2241                 /* Actual pixel center, used when collision is found */
2242                 point[0][0] = ((float)tx + 0.5f) / w;
2243                 point[0][1] = ((float)ty + 0.5f) / h;
2244
2245                 /*
2246                  * A pixel middle sample isn't enough to find very narrow polygons
2247                  * So using 4 samples of each corner too
2248                  */
2249                 point[1][0] = ((float)tx) / w;
2250                 point[1][1] = ((float)ty) / h;
2251
2252                 point[2][0] = ((float)tx + 1) / w;
2253                 point[2][1] = ((float)ty) / h;
2254
2255                 point[3][0] = ((float)tx) / w;
2256                 point[3][1] = ((float)ty + 1) / h;
2257
2258                 point[4][0] = ((float)tx + 1) / w;
2259                 point[4][1] = ((float)ty + 1) / h;
2260
2261
2262                 /* Loop through samples, starting from middle point */
2263                 for (int sample = 0; sample < 5; sample++) {
2264                         /* Loop through every face in the mesh */
2265                         /* XXX TODO This is *horrible* with big meshes, should use a 2D BVHTree over UV tris here! */
2266                         for (int i = 0; i < tottri; i++) {
2267                                 /* Check uv bb */
2268                                 if ((faceBB[i].min[0] > point[sample][0]) ||
2269                                     (faceBB[i].min[1] > point[sample][1]) ||
2270                                     (faceBB[i].max[0] < point[sample][0]) ||
2271                                     (faceBB[i].max[1] < point[sample][1]))
2272                                 {
2273                                         continue;
2274                                 }
2275
2276                                 const float *uv1 = mloopuv[mlooptri[i].tri[0]].uv;
2277                                 const float *uv2 = mloopuv[mlooptri[i].tri[1]].uv;
2278                                 const float *uv3 = mloopuv[mlooptri[i].tri[2]].uv;
2279
2280                                 /* If point is inside the face */
2281                                 if (isect_point_tri_v2(point[sample], uv1, uv2, uv3) != 0) {
2282                                         float uv[2];
2283
2284                                         /* Add b-weights per anti-aliasing sample */
2285                                         for (int j = 0; j < aa_samples; j++) {
2286                                                 uv[0] = point[0][0] + jitter5sample[j * 2] / w;
2287                                                 uv[1] = point[0][1] + jitter5sample[j * 2 + 1] / h;
2288
2289                                                 barycentric_weights_v2(uv1, uv2, uv3, uv, tempWeights[index * aa_samples + j].v);
2290                                         }
2291
2292                                         /* Set surface point face values */
2293                                         tPoint->tri_index = i;
2294
2295                                         /* save vertex indexes */
2296                                         tPoint->v1 = mloop[mlooptri[i].tri[0]].v;
2297                                         tPoint->v2 = mloop[mlooptri[i].tri[1]].v;
2298                                         tPoint->v3 = mloop[mlooptri[i].tri[2]].v;
2299
2300                                         sample = 5; /* make sure we exit sample loop as well */
2301                                         break;
2302                                 }
2303                         }
2304                 }
2305         }
2306 }
2307
2308 static void dynamic_paint_create_uv_surface_neighbor_cb(
2309         void *__restrict userdata,
2310         const int ty,
2311         const ParallelRangeTLS *__restrict UNUSED(tls))
2312 {
2313         const DynamicPaintCreateUVSurfaceData *data = userdata;
2314
2315         const DynamicPaintSurface *surface = data->surface;
2316         PaintUVPoint *tempPoints = data->tempPoints;
2317         Vec3f *tempWeights = data->tempWeights;
2318
2319         const MLoopTri *mlooptri = data->mlooptri;
2320         const MLoopUV *mloopuv = data->mloopuv;
2321         const MLoop *mloop = data->mloop;
2322
2323         uint32_t *active_points = data->active_points;
2324
2325         const float jitter5sample[10] = JITTER_SAMPLES;
2326         const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
2327         const int w = surface->image_resolution;
2328         const int h = w;
2329
2330         for (int tx = 0; tx < w; tx++) {
2331                 const int index = tx + w * ty;
2332                 PaintUVPoint *tPoint = &tempPoints[index];
2333
2334                 /* If point isn't on canvas mesh */
2335                 if (tPoint->tri_index == -1) {
2336                         float point[2];
2337
2338                         /* get loop area */
2339                         const int u_min = (tx > 0) ? -1 : 0;
2340                         const int u_max = (tx < (w - 1)) ? 1 : 0;
2341                         const int v_min = (ty > 0) ? -1 : 0;
2342                         const int v_max = (ty < (h - 1)) ? 1 : 0;
2343
2344                         point[0] = ((float)tx + 0.5f) / w;
2345                         point[1] = ((float)ty + 0.5f) / h;
2346
2347                         /* search through defined area for neighbor, checking grid directions first */
2348                         for (int ni = 0; ni < 8; ni++) {
2349                                 int u = neighStraightX[ni];
2350                                 int v = neighStraightY[ni];
2351
2352                                 if (u >= u_min && u <= u_max && v >= v_min && v <= v_max) {
2353                                         /* if not this pixel itself */
2354                                         if (u != 0 || v != 0) {
2355                                                 const int ind = (tx + u) + w * (ty + v);
2356
2357                                                 /* if neighbor has index */
2358                                                 if (tempPoints[ind].neighbour_pixel == -1 && tempPoints[ind].tri_index != -1) {
2359                                                         float uv[2];
2360                                                         const int i = tempPoints[ind].tri_index;
2361                                                         const float *uv1 = mloopuv[mlooptri[i].tri[0]].uv;
2362                                                         const float *uv2 = mloopuv[mlooptri[i].tri[1]].uv;
2363                                                         const float *uv3 = mloopuv[mlooptri[i].tri[2]].uv;
2364
2365                                                         /* tri index */
2366                                                         /* There is a low possibility of actually having a neighbor point which tri is
2367                                                          * already set from another neighbor in a separate thread here.
2368                                                          * Checking for both tri_index and neighbour_pixel above reduces that probability
2369                                                          * but it remains possible.
2370                                                          * That atomic op (and its memory fence) ensures tPoint->neighbour_pixel is set
2371                                                          * to non--1 *before* its tri_index is set (i.e. that it cannot be used a neighbour).
2372                                                          */
2373                                                         tPoint->neighbour_pixel = ind - 1;
2374                                                         atomic_add_and_fetch_uint32(&tPoint->neighbour_pixel, 1);
2375                                                         tPoint->tri_index = i;
2376
2377                                                         /* Now calculate pixel data for this pixel as it was on polygon surface */
2378                                                         /* Add b-weights per anti-aliasing sample */
2379                                                         for (int j = 0; j < aa_samples; j++) {
2380                                                                 uv[0] = point[0] + jitter5sample[j * 2] / w;
2381                                                                 uv[1] = point[1] + jitter5sample[j * 2 + 1] / h;
2382                                                                 barycentric_weights_v2(uv1, uv2, uv3, uv, tempWeights[index * aa_samples + j].v);
2383                                                         }
2384
2385                                                         /* save vertex indexes */
2386                                                         tPoint->v1 = mloop[mlooptri[i].tri[0]].v;
2387                                                         tPoint->v2 = mloop[mlooptri[i].tri[1]].v;
2388                                                         tPoint->v3 = mloop[mlooptri[i].tri[2]].v;
2389
2390                                                         break;
2391                                                 }
2392                                         }
2393                                 }
2394                         }
2395                 }
2396
2397                 /* Increase the final number of active surface points if relevant. */
2398                 if (tPoint->tri_index != -1)
2399                         atomic_add_and_fetch_uint32(active_points, 1);
2400         }
2401 }
2402
2403 #undef JITTER_SAMPLES
2404
2405 static float dist_squared_to_looptri_uv_edges(const MLoopTri *mlooptri, const MLoopUV *mloopuv, int tri_index, const float point[2])
2406 {
2407         float min_distance = FLT_MAX;
2408
2409         for (int i = 0; i < 3; i++) {
2410                 const float dist_squared = dist_squared_to_line_segment_v2(
2411                         point,
2412                         mloopuv[mlooptri[tri_index].tri[(i + 0)]].uv,
2413                         mloopuv[mlooptri[tri_index].tri[(i + 1) % 3]].uv
2414                 );
2415
2416                 if (dist_squared < min_distance)
2417                         min_distance = dist_squared;
2418         }
2419
2420         return min_distance;
2421 }
2422
2423 typedef struct DynamicPaintFindIslandBorderData {
2424         const MeshElemMap *vert_to_looptri_map;
2425         int w, h, px, py;
2426
2427         int best_index;
2428         float best_weight;
2429 } DynamicPaintFindIslandBorderData;
2430
2431 static void dynamic_paint_find_island_border(
2432         const DynamicPaintCreateUVSurfaceData *data, DynamicPaintFindIslandBorderData *bdata,
2433         int tri_index, const float pixel[2], int in_edge, int depth);
2434
2435 /* Tries to find the neighboring pixel in given (uv space) direction.
2436  * Result is used by effect system to move paint on the surface.
2437  *
2438  * px, py : origin pixel x and y
2439  * n_index : lookup direction index (use neighX, neighY to get final index)
2440  */
2441 static int dynamic_paint_find_neighbour_pixel(
2442         const DynamicPaintCreateUVSurfaceData *data, const MeshElemMap *vert_to_looptri_map,
2443         const int w, const int h, const int px, const int py, const int n_index)
2444 {
2445         /* Note: Current method only uses polygon edges to detect neighboring pixels.
2446          *       -> It doesn't always lead to the optimum pixel but is accurate enough
2447          *          and faster/simpler than including possible face tip point links)
2448          */
2449
2450         /* shift position by given n_index */
2451         const int x = px + neighX[n_index];
2452         const int y = py + neighY[n_index];
2453
2454         if (x < 0 || x >= w || y < 0 || y >= h)
2455                 return OUT_OF_TEXTURE;
2456
2457         const PaintUVPoint *tempPoints = data->tempPoints;
2458         const PaintUVPoint *tPoint = &tempPoints[x + w * y];        /* UV neighbor */
2459         const PaintUVPoint *cPoint = &tempPoints[px + w * py];      /* Origin point */
2460
2461         /* Check if shifted point is on same face -> it's a correct neighbor (and if it isn't marked as an "edge pixel") */
2462         if ((tPoint->tri_index == cPoint->tri_index) && (tPoint->neighbour_pixel == -1))
2463                 return (x + w * y);
2464
2465         /* Even if shifted point is on another face
2466          * -> use this point.
2467          *
2468          * !! Replace with "is uv faces linked" check !!
2469          * This should work fine as long as uv island margin is > 1 pixel.
2470          */
2471         if ((tPoint->tri_index != -1) && (tPoint->neighbour_pixel == -1)) {
2472                 return (x + w * y);
2473         }
2474
2475         /* If we get here, the actual neighboring pixel is located on a non-linked uv face,
2476          * and we have to find its "real" position.
2477          *
2478          * Simple neighboring face finding algorithm:
2479          *   - find closest uv edge to shifted pixel and get the another face that shares that edge
2480          *   - find corresponding position of that new face edge in uv space
2481          *
2482          * TODO: Implement something more accurate / optimized?
2483          */
2484         {
2485                 DynamicPaintFindIslandBorderData bdata = {
2486                         .vert_to_looptri_map = vert_to_looptri_map,
2487                         .w = w, .h = h, .px = px, .py = py,
2488                         .best_index = NOT_FOUND, .best_weight = 1.0f,
2489                 };
2490
2491                 float pixel[2];
2492
2493                 pixel[0] = ((float)(px + neighX[n_index]) + 0.5f) / (float)w;
2494                 pixel[1] = ((float)(py + neighY[n_index]) + 0.5f) / (float)h;
2495
2496                 /* Do a small recursive search for the best island edge. */
2497                 dynamic_paint_find_island_border(data, &bdata, cPoint->tri_index, pixel, -1, 5);
2498
2499                 return bdata.best_index;
2500         }
2501 }
2502
2503 static void dynamic_paint_find_island_border(
2504         const DynamicPaintCreateUVSurfaceData *data, DynamicPaintFindIslandBorderData *bdata,
2505         int tri_index, const float pixel[2], int in_edge, int depth)
2506 {
2507         const MLoop *mloop = data->mloop;
2508         const MLoopTri *mlooptri = data->mlooptri;
2509         const MLoopUV *mloopuv = data->mloopuv;
2510
2511         const unsigned int *loop_idx = mlooptri[tri_index].tri;
2512
2513         /* Enumerate all edges of the triangle, rotating the vertex list accordingly. */
2514         for (int edge_idx = 0; edge_idx < 3; edge_idx++) {
2515                 /* but not the edge we have just recursed through */
2516                 if (edge_idx == in_edge)
2517                         continue;
2518
2519                 float uv0[2], uv1[2], uv2[2];
2520
2521                 copy_v2_v2(uv0, mloopuv[loop_idx[(edge_idx + 0)]].uv);
2522                 copy_v2_v2(uv1, mloopuv[loop_idx[(edge_idx + 1) % 3]].uv);
2523                 copy_v2_v2(uv2, mloopuv[loop_idx[(edge_idx + 2) % 3]].uv);
2524
2525                 /* Verify the target point is on the opposite side of the edge from the third triangle
2526                  * vertex, to ensure that we always move closer to the goal point. */
2527                 const float sidep = line_point_side_v2(uv0, uv1, pixel);
2528                 const float side2 = line_point_side_v2(uv0, uv1, uv2);
2529
2530                 if (side2 == 0.0f)
2531                         continue;
2532
2533                 /* Hack: allow all edges of the original triangle */
2534                 const bool correct_side = (in_edge == -1) || (sidep < 0 && side2 > 0) || (sidep > 0 && side2 < 0);
2535
2536                 /* Allow exactly on edge for the non-recursive case */
2537                 if (!correct_side && sidep != 0.0f)
2538                         continue;
2539
2540                 /* Now find another face that is linked to that edge. */
2541                 const int vert0 = mloop[loop_idx[(edge_idx + 0)]].v;
2542                 const int vert1 = mloop[loop_idx[(edge_idx + 1) % 3]].v;
2543
2544                 /* Use a pre-computed vert-to-looptri mapping, speeds up things a lot compared to looping over all loopti. */
2545                 const MeshElemMap *map = &bdata->vert_to_looptri_map[vert0];
2546
2547                 bool found_other = false;
2548                 int target_tri = -1;
2549                 int target_edge = -1;
2550
2551                 float ouv0[2], ouv1[2];
2552
2553                 for (int i = 0; i < map->count && !found_other; i++) {
2554                         const int lt_index = map->indices[i];
2555
2556                         if (lt_index == tri_index)
2557                                 continue;
2558
2559                         const unsigned int *other_loop_idx = mlooptri[lt_index].tri;
2560
2561                         /* Check edges for match, looping in the same order as the outer loop. */
2562                         for (int j = 0; j < 3; j++) {
2563                                 const int overt0 = mloop[other_loop_idx[(j + 0)]].v;
2564                                 const int overt1 = mloop[other_loop_idx[(j + 1) % 3]].v;
2565
2566                                 /* Allow for swapped vertex order */
2567                                 if (overt0 == vert0 && overt1 == vert1) {
2568                                         found_other = true;
2569                                         copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 0)]].uv);
2570                                         copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 1) % 3]].uv);
2571                                 }
2572                                 else if (overt0 == vert1 && overt1 == vert0) {
2573                                         found_other = true;
2574                                         copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 0)]].uv);
2575                                         copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 1) % 3]].uv);
2576                                 }
2577
2578                                 if (found_other) {
2579                                         target_tri = lt_index;
2580                                         target_edge = j;
2581                                         break;
2582                                 }
2583                         }
2584                 }
2585
2586                 if (!found_other) {
2587                         if (bdata->best_index < 0)
2588                                 bdata->best_index = ON_MESH_EDGE;
2589
2590                         continue;
2591                 }
2592
2593                 /* If this edge is connected in UV space too, recurse */
2594                 if (equals_v2v2(uv0, ouv0) && equals_v2v2(uv1, ouv1)) {
2595                         if (depth > 0 && correct_side) {
2596                                 dynamic_paint_find_island_border(data, bdata, target_tri, pixel, target_edge, depth - 1);
2597                         }
2598
2599                         continue;
2600                 }
2601
2602                 /* Otherwise try to map to the other side of the edge.
2603                  * First check if there already is a better solution. */
2604                 const float dist_squared = dist_squared_to_line_segment_v2(pixel, uv0, uv1);
2605
2606                 if (bdata->best_index >= 0 && dist_squared >= bdata->best_weight)
2607                         continue;
2608
2609                 /*
2610                  * Find a point that is relatively at same edge position
2611                  * on this other face UV
2612                  */
2613                 float closest_point[2], dir_vec[2], tgt_pixel[2];
2614
2615                 float lambda = closest_to_line_v2(closest_point, pixel, uv0, uv1);
2616                 CLAMP(lambda, 0.0f, 1.0f);
2617
2618                 sub_v2_v2v2(dir_vec, ouv1, ouv0);
2619                 madd_v2_v2v2fl(tgt_pixel, ouv0, dir_vec, lambda);
2620
2621                 int w = bdata->w, h = bdata->h, px = bdata->px, py = bdata->py;
2622
2623                 int final_pixel[2] = { (int)floorf(tgt_pixel[0] * w), (int)floorf(tgt_pixel[1] * h) };
2624
2625                 /* If current pixel uv is outside of texture */
2626                 if (final_pixel[0] < 0 || final_pixel[0] >= w || final_pixel[1] < 0 || final_pixel[1] >= h) {
2627                         if (bdata->best_index == NOT_FOUND)
2628                                 bdata->best_index = OUT_OF_TEXTURE;
2629
2630                         continue;
2631                 }
2632
2633                 const PaintUVPoint *tempPoints = data->tempPoints;
2634                 int final_index = final_pixel[0] + w * final_pixel[1];
2635
2636                 /* If we ended up to our origin point ( mesh has smaller than pixel sized faces) */
2637                 if (final_index == (px + w * py))
2638                         continue;
2639
2640                 /* If final point is an "edge pixel", use it's "real" neighbor instead */
2641                 if (tempPoints[final_index].neighbour_pixel != -1) {
2642                         final_index = tempPoints[final_index].neighbour_pixel;
2643
2644                         /* If we ended up to our origin point */
2645                         if (final_index == (px + w * py))
2646                                 continue;
2647                 }
2648
2649                 /* If found pixel still lies on wrong face ( mesh has smaller than pixel sized faces) */
2650                 if (tempPoints[final_index].tri_index != target_tri) {
2651                         /* Check if it's close enough to likely touch the intended triangle. Any triangle
2652                          * becomes thinner than a pixel at its vertices, so robustness requires some margin. */
2653                         const float final_pt[2] = { ((final_index % w) + 0.5f) / w, ((final_index / w) + 0.5f) / h };
2654                         const float threshold = SQUARE(0.7f) / (w * h);
2655
2656                         if (dist_squared_to_looptri_uv_edges(mlooptri, mloopuv, tempPoints[final_index].tri_index, final_pt) > threshold)
2657                                 continue;
2658                 }
2659
2660                 bdata->best_index = final_index;
2661                 bdata->best_weight = dist_squared;
2662         }
2663 }
2664
2665 static bool dynamicPaint_pointHasNeighbor(PaintAdjData *ed, int index, int neighbor)
2666 {
2667         const int idx = ed->n_index[index];
2668
2669         for (int i = 0; i < ed->n_num[index]; i++) {
2670                 if (ed->n_target[idx + i] == neighbor) {
2671                         return true;
2672                 }
2673         }
2674
2675         return false;
2676 }
2677
2678 /* Makes the adjacency data symmetric, except for border pixels. I.e. if A is neighbor of B, B is neighbor of A. */
2679 static bool dynamicPaint_symmetrizeAdjData(PaintAdjData *ed, int active_points)
2680 {
2681         int *new_n_index = MEM_callocN(sizeof(int) * active_points, "Surface Adj Index");
2682         int *new_n_num = MEM_callocN(sizeof(int) * active_points, "Surface Adj Counts");
2683
2684         if (new_n_num && new_n_index) {
2685                 /* Count symmetrized neigbors */
2686                 int total_targets = 0;
2687
2688                 for (int index = 0; index < active_points; index++) {
2689                         total_targets += ed->n_num[index];
2690                         new_n_num[index] = ed->n_num[index];
2691                 }
2692
2693                 for (int index = 0; index < active_points; index++) {
2694                         if (ed->flags[index] & ADJ_BORDER_PIXEL) {
2695                                 continue;
2696                         }
2697
2698                         for (int i = 0, idx = ed->n_index[index]; i < ed->n_num[index]; i++) {
2699                                 const int target = ed->n_target[idx + i];
2700
2701                                 assert(!(ed->flags[target] & ADJ_BORDER_PIXEL));
2702
2703                                 if (!dynamicPaint_pointHasNeighbor(ed, target, index)) {
2704                                         new_n_num[target]++;
2705                                         total_targets++;
2706                                 }
2707                         }
2708                 }
2709
2710                 /* Allocate a new target map */
2711                 int *new_n_target = MEM_callocN(sizeof(int) * total_targets, "Surface Adj Targets");
2712
2713                 if (new_n_target) {
2714                         /* Copy existing neighbors to the new map */
2715                         int n_pos = 0;
2716
2717                         for (int index = 0; index < active_points; index++) {
2718                                 new_n_index[index] = n_pos;
2719                                 memcpy(&new_n_target[n_pos], &ed->n_target[ed->n_index[index]], sizeof(int) * ed->n_num[index]);
2720
2721                                 /* Reset count to old, but advance position by new, leaving a gap to fill below. */
2722                                 n_pos += new_n_num[index];
2723                                 new_n_num[index] = ed->n_num[index];
2724                         }
2725
2726                         assert(n_pos == total_targets);
2727
2728                         /* Add symmetrized - this loop behavior must exactly match the count pass above */
2729                         for (int index = 0; index < active_points; index++) {
2730                                 if (ed->flags[index] & ADJ_BORDER_PIXEL) {
2731                                         continue;
2732                                 }
2733
2734                                 for (int i = 0, idx = ed->n_index[index]; i < ed->n_num[index]; i++) {
2735                                         const int target = ed->n_target[idx + i];
2736
2737                                         if (!dynamicPaint_pointHasNeighbor(ed, target, index)) {
2738                                                 const int num = new_n_num[target]++;
2739                                                 new_n_target[new_n_index[target] + num] = index;
2740                                         }
2741                                 }
2742                         }
2743
2744                         /* Swap maps */
2745                         MEM_freeN(ed->n_target);
2746                         ed->n_target = new_n_target;
2747
2748                         MEM_freeN(ed->n_index);
2749                         ed->n_index = new_n_index;
2750
2751                         MEM_freeN(ed->n_num);
2752                         ed->n_num = new_n_num;
2753
2754                         ed->total_targets = total_targets;
2755                         return true;
2756                 }
2757         }
2758
2759         if (new_n_index)
2760                 MEM_freeN(new_n_index);
2761         if (new_n_num)
2762                 MEM_freeN(new_n_num);
2763
2764         return false;
2765 }
2766
2767 int dynamicPaint_createUVSurface(Scene *scene, DynamicPaintSurface *surface, float *progress, short *do_update)
2768 {
2769         /* Antialias jitter point relative coords */
2770         const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
2771         char uvname[MAX_CUSTOMDATA_LAYER_NAME];
2772         uint32_t active_points = 0;
2773         bool error = false;
2774
2775         PaintSurfaceData *sData;
2776         DynamicPaintCanvasSettings *canvas = surface->canvas;
2777         Mesh *mesh = canvas->mesh;
2778
2779         PaintUVPoint *tempPoints = NULL;
2780         Vec3f *tempWeights = NULL;
2781         const MLoopTri *mlooptri = NULL;
2782         const MLoopUV *mloopuv = NULL;
2783         const MLoop *mloop = NULL;
2784
2785         Bounds2D *faceBB = NULL;
2786         int *final_index;
2787
2788         *progress = 0.0f;
2789         *do_update = true;
2790
2791         if (!mesh)
2792                 return setError(canvas, N_("Canvas mesh not updated"));
2793         if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ)
2794                 return setError(canvas, N_("Cannot bake non-'image sequence' formats"));
2795
2796         mloop = mesh->mloop;
2797         mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
2798         const int tottri = BKE_mesh_runtime_looptri_len(mesh);
2799
2800         /* get uv map */
2801         if (CustomData_has_layer(&mesh->ldata, CD_MLOOPUV)) {
2802                 CustomData_validate_layer_name(&mesh->ldata, CD_MLOOPUV, surface->uvlayer_name, uvname);
2803                 mloopuv = CustomData_get_layer_named(&mesh->ldata, CD_MLOOPUV, uvname);
2804         }
2805
2806         /* Check for validity */
2807         if (!mloopuv)
2808                 return setError(canvas, N_("No UV data on canvas"));
2809         if (surface->image_resolution < 16 || surface->image_resolution > 8192)
2810                 return setError(canvas, N_("Invalid resolution"));
2811
2812         const int w = surface->image_resolution;
2813         const int h = w;
2814
2815         /*
2816          * Start generating the surface
2817          */
2818         CLOG_INFO(&LOG, 1, "Preparing UV surface of %ix%i pixels and %i tris.", w, h, tottri);
2819
2820         /* Init data struct */
2821         if (surface->data)
2822                 dynamicPaint_freeSurfaceData(surface);
2823         sData = surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData");
2824         if (!surface->data)
2825                 return setError(canvas, N_("Not enough free memory"));
2826
2827         tempPoints = MEM_callocN(w * h * sizeof(*tempPoints), "Temp PaintUVPoint");
2828         if (!tempPoints)
2829                 error = true;
2830
2831         final_index = MEM_callocN(w * h * sizeof(*final_index), "Temp UV Final Indexes");
2832         if (!final_index)
2833                 error = true;
2834
2835         tempWeights = MEM_mallocN(w * h * aa_samples * sizeof(*tempWeights), "Temp bWeights");
2836         if (!tempWeights)
2837                 error = true;
2838
2839         /*
2840          * Generate a temporary bounding box array for UV faces to optimize
2841          * the pixel-inside-a-face search.
2842          */
2843         if (!error) {
2844                 faceBB = MEM_mallocN(tottri * sizeof(*faceBB), "MPCanvasFaceBB");
2845                 if (!faceBB)
2846                         error = true;
2847         }
2848
2849         *progress = 0.01f;
2850         *do_update = true;
2851
2852         if (!error) {
2853                 for (int i = 0; i < tottri; i++) {
2854                         copy_v2_v2(faceBB[i].min, mloopuv[mlooptri[i].tri[0]].uv);
2855                         copy_v2_v2(faceBB[i].max, mloopuv[mlooptri[i].tri[0]].uv);
2856
2857                         for (int j = 1; j < 3; j++) {
2858                                 minmax_v2v2_v2(faceBB[i].min, faceBB[i].max, mloopuv[mlooptri[i].tri[j]].uv);
2859                         }
2860                 }
2861
2862                 *progress = 0.02f;
2863                 *do_update = true;
2864
2865                 /* Loop through every pixel and check if pixel is uv-mapped on a canvas face. */
2866                 DynamicPaintCreateUVSurfaceData data = {
2867                     .surface = surface, .tempPoints = tempPoints, .tempWeights = tempWeights,
2868                     .mlooptri = mlooptri, .mloopuv = mloopuv, .mloop = mloop, .tottri = tottri,
2869                     .faceBB = faceBB,
2870                 };
2871                 {
2872                         ParallelRangeSettings settings;
2873                         BLI_parallel_range_settings_defaults(&settings);
2874                         settings.use_threading = (h > 64 || tottri > 1000);
2875                         BLI_task_parallel_range(0, h,
2876                                                 &data,
2877                                                 dynamic_paint_create_uv_surface_direct_cb,
2878                                                 &settings);
2879                 }
2880
2881                 *progress = 0.04f;
2882                 *do_update = true;
2883
2884                 /*
2885                  * Now loop through every pixel that was left without index
2886                  * and find if they have neighboring pixels that have an index.
2887                  * If so use that polygon as pixel surface.
2888                  * (To avoid seams on uv island edges)
2889                  */
2890                 data.active_points = &active_points;
2891                 {
2892                         ParallelRangeSettings settings;
2893                         BLI_parallel_range_settings_defaults(&settings);
2894                         settings.use_threading = (h > 64);
2895                         BLI_task_parallel_range(0, h,
2896                                                 &data,
2897                                                 dynamic_paint_create_uv_surface_neighbor_cb,
2898                                                 &settings);
2899                 }
2900
2901                 *progress = 0.06f;
2902                 *do_update = true;
2903
2904                 /* Generate surface adjacency data. */
2905                 {
2906                         int cursor = 0;
2907
2908                         /* Create a temporary array of final indexes (before unassigned
2909                          * pixels have been dropped) */
2910                         for (int i = 0; i < w * h; i++) {
2911                                 if (tempPoints[i].tri_index != -1) {
2912                                         final_index[i] = cursor;
2913                                         cursor++;
2914                                 }
2915                         }
2916                         /* allocate memory */
2917                         sData->total_points = w * h;
2918                         dynamicPaint_initAdjacencyData(surface, true);
2919
2920                         if (sData->adj_data) {
2921                                 PaintAdjData *ed = sData->adj_data;
2922                                 int n_pos = 0;
2923
2924                                 MeshElemMap *vert_to_looptri_map;
2925                                 int *vert_to_looptri_map_mem;
2926
2927                                 BKE_mesh_vert_looptri_map_create(
2928                                         &vert_to_looptri_map, &vert_to_looptri_map_mem,
2929                                         mesh->mvert, mesh->totvert, mlooptri, tottri, mloop, mesh->totloop);
2930
2931                                 int total_border = 0;
2932
2933                                 for (int ty = 0; ty < h; ty++) {
2934                                         for (int tx = 0; tx < w; tx++) {
2935                                                 const int index = tx + w * ty;
2936
2937                                                 if (tempPoints[index].tri_index != -1) {
2938                                                         ed->n_index[final_index[index]] = n_pos;
2939                                                         ed->n_num[final_index[index]] = 0;
2940
2941                                                         if (tempPoints[index].neighbour_pixel != -1) {
2942                                                                 ed->flags[final_index[index]] |= ADJ_BORDER_PIXEL;
2943                                                                 total_border++;
2944                                                         }
2945
2946                                                         for (int i = 0; i < 8; i++) {
2947                                                                 /* Try to find a neighboring pixel in defined direction. If not found, -1 is returned */
2948                                                                 const int n_target = dynamic_paint_find_neighbour_pixel(
2949                                                                                          &data, vert_to_looptri_map, w, h, tx, ty, i);
2950
2951                                                                 if (n_target >= 0 && n_target != index) {
2952                                                                         if (!dynamicPaint_pointHasNeighbor(ed, final_index[index], final_index[n_target])) {
2953                                                                                 ed->n_target[n_pos] = final_index[n_target];
2954                                                                                 ed->n_num[final_index[index]]++;
2955                                                                                 n_pos++;
2956                                                                         }
2957                                                                 }
2958                                                                 else if (n_target == ON_MESH_EDGE || n_target == OUT_OF_TEXTURE) {
2959                                                                         ed->flags[final_index[index]] |= ADJ_ON_MESH_EDGE;
2960                                                                 }
2961                                                         }
2962                                                 }
2963                                         }
2964                                 }
2965
2966                                 MEM_freeN(vert_to_looptri_map);
2967                                 MEM_freeN(vert_to_looptri_map_mem);
2968
2969                                 /* Make neighbors symmetric */
2970                                 if (!dynamicPaint_symmetrizeAdjData(ed, active_points)) {
2971                                         error = true;
2972                       &nbs