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