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