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