Merge with trunk r37546
[blender-staging.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  * Contributor(s): Miika Hämäläinen
10  *
11  * ***** END GPL LICENSE BLOCK *****
12  */
13
14
15 #include "MEM_guardedalloc.h"
16
17 #include <math.h>
18 #include <stdio.h>
19
20 #include "BLI_blenlib.h"
21 #include "BLI_math.h"
22 #include "BLI_kdtree.h"
23 #include "BLI_utildefines.h"
24
25 /* Platform independend time    */
26 #include "PIL_time.h"
27
28 #include "BKE_animsys.h"
29 #include "BKE_bvhutils.h"       /* bvh tree     */
30 #include "BKE_blender.h"
31 #include "BKE_cdderivedmesh.h"
32 #include "BKE_context.h"
33 #include "BKE_customdata.h"
34 #include "BKE_colortools.h"
35 #include "BKE_depsgraph.h"
36 #include "BKE_DerivedMesh.h"
37 #include "BKE_dynamicpaint.h"
38 #include "BKE_global.h"
39 #include "BKE_main.h"
40 #include "BKE_material.h"
41 #include "BKE_modifier.h"
42 #include "BKE_object.h"
43 #include "BKE_particle.h"
44 #include "BKE_pointcache.h"
45 #include "BKE_report.h"
46 #include "BKE_scene.h"
47 #include "BKE_texture.h"
48
49 #include "DNA_anim_types.h"
50 #include "DNA_dynamicpaint_types.h"
51 #include "DNA_group_types.h" /*GroupObject*/
52 #include "DNA_mesh_types.h"
53 #include "DNA_meshdata_types.h"
54 #include "DNA_modifier_types.h"
55 #include "DNA_object_types.h"
56 #include "DNA_scene_types.h"
57 #include "DNA_userdef_types.h"  /* to get temp file path        */
58
59 /* for bake operator    */
60 #include "ED_screen.h"
61 #include "WM_types.h"
62 #include "WM_api.h"
63
64 /* for image output     */
65 #include "IMB_imbuf_types.h"
66 #include "IMB_imbuf.h"
67 #include "BKE_image.h"
68 #include "intern/IMB_filetype.h"
69 #ifdef WITH_OPENEXR
70 #include "intern/openexr/openexr_api.h"
71 #endif
72
73 /* uv validate  */
74 #include "intern/MOD_util.h"
75
76 /* to read object material color        */
77 #include "DNA_texture_types.h"
78 #include "../render/intern/include/render_types.h"
79 #include "../render/intern/include/voxeldata.h"
80 #include "DNA_material_types.h"
81 #include "RE_render_ext.h"
82
83
84 #define DPOUTPUT_JPEG 0
85 #define DPOUTPUT_PNG 1
86 #define DPOUTPUT_OPENEXR 2
87
88 struct Object;
89 struct Scene;
90 struct DerivedMesh;
91 //struct DynamicPaintModifierData;
92
93 /*
94 *       Init predefined antialias jitter data
95 */
96 float jitterDistances[5] = {0.0f,
97                                                         0.447213595f,
98                                                         0.447213595f,
99                                                         0.447213595f,
100                                                         0.5f};
101
102 /* precalculated gaussian factors for 5x super sampling */
103 float gaussianFactors[5] = {    0.996849f,
104                                                                 0.596145f,
105                                                                 0.596145f,
106                                                                 0.596145f,
107                                                                 0.524141f};
108 float gaussianTotal = 3.309425f;
109
110 /*
111 *       UV Image neighbouring pixel table x and y list
112 */
113 int neighX[8] = {1,1,0,-1,-1,-1, 0, 1};
114 int neighY[8] = {0,1,1, 1, 0,-1,-1,-1};
115
116 static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe);
117 static int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, Scene *scene, Object *cObject, int frame);
118
119 /***************************** Internal Structs ***************************/
120
121 typedef struct FaceAdv {
122         float no[3];
123         float no_q[3];
124 } FaceAdv;
125
126 typedef struct BB2d {
127         float min[2], max[2];
128 } BB2d;
129
130 typedef struct Vec3f {
131         float v[3];
132 } Vec3f;
133
134 /* Surface data used while processing a frame   */
135 typedef struct PaintBakePoint {
136         float realCoord[3]; /* current pixel center world-space coordinates */
137         float invNorm[3];  /* current pixel world-space inverted normal. depends on face shading mode */
138         float normal_scale; /* normal directional scale for displace mapping */
139
140         /*
141         *       Effect / moving layer data
142         *       ! Only generated if effects enabled ! */                
143         float gravity_dir;      /* UV space direction of gravity */
144         float gravity_rate;             /* Gravity strength. (Depends on surface angle.) */
145 } PaintBakePoint;
146
147 /* UV Image sequence format point       */
148 typedef struct PaintTexturePoint {
149
150         int neighbour[8];       /* Indexes of 8 neighbouring pixels if exist */
151         float neighbour_dist[8];        /*      Distances to all 8 neighbouring pixels */       
152
153
154         /* Pixel / mesh data */
155         int face_index, pixel_index;            /* face index on domain derived mesh */
156         int v1, v2, v3;         /* vertex indexes */
157
158         int neighbour_pixel;    /* If this pixel isn't uv mapped to any face,
159                                                         but it's neighbouring pixel is */
160         short quad;
161         struct Vec3f *barycentricWeights;       /* b-weights for all pixel samples */
162
163 } PaintTexturePoint;
164
165 /***************************** General Utils ******************************/
166
167 /*
168 *       Output error message to both ui and console
169 */
170 static int printError(DynamicPaintCanvasSettings *canvas, char *string)
171 {
172         if (strlen(string)>64) string[63] = '\0';
173
174         /* Add error to canvas ui info label */
175         sprintf(canvas->error, string);
176
177         /* Print console output */
178         printf("DynamicPaint bake failed: %s\n", canvas->error);
179
180         return 0;
181 }
182
183 /* Get number of surface points for cached types */
184 static int dynamicPaint_surfaceNumOfPoints(DynamicPaintSurface *surface)
185 {
186         if (surface->format == MOD_DPAINT_SURFACE_F_PTEX) {
187                 return 0; /* not supported atm */
188         }
189         else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
190                 if (!surface->canvas->dm) return 0; /* invalid derived mesh */
191                 return surface->canvas->dm->getNumVerts(surface->canvas->dm);
192         }
193         else
194                 return 0;
195 }
196
197 /* checks whether surface's format/type has realtime preview */
198 int dynamicPaint_surfaceHasPreview(DynamicPaintSurface *surface) {
199         if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 0;
200         else if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
201                 if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) return 0;
202                 else return 1;
203         }
204         else return 1;
205 }
206
207 /* get currently active surface (in user interface) */
208 static DynamicPaintSurface *get_activeSurface(DynamicPaintCanvasSettings *canvas)
209 {
210         DynamicPaintSurface *surface = canvas->surfaces.first;
211         int i;
212
213         for(i=0; surface; surface=surface->next) {
214                 if(i == canvas->active_sur)
215                         return surface;
216                 i++;
217         }
218         return NULL;
219 }
220
221 /* set preview to first previewable surface */
222 static void dynamicPaint_resetPreview(DynamicPaintCanvasSettings *canvas)
223 {
224         DynamicPaintSurface *surface = canvas->surfaces.first;
225         int done=0;
226
227         for(; surface; surface=surface->next) {
228                 if (!done && dynamicPaint_surfaceHasPreview(surface)) {
229                         surface->flags |= MOD_DPAINT_PREVIEW;
230                         done=1;
231                 }
232                 else
233                         surface->flags &= ~MOD_DPAINT_PREVIEW;
234         }
235 }
236
237 /* set preview to first previewable surface */
238 static void dynamicPaint_setPreview(DynamicPaintSurface *t_surface)
239 {
240         DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
241         for(; surface; surface=surface->next) {
242                 if (surface == t_surface)
243                         surface->flags |= MOD_DPAINT_PREVIEW;
244                 else
245                         surface->flags &= ~MOD_DPAINT_PREVIEW;
246         }
247 }
248
249 /* change surface data to defaults on new type */
250 void dynamicPaintSurface_updateType(struct DynamicPaintSurface *surface) {
251         if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
252                 surface->output_name[0]='\0';
253                 surface->output_name2[0]='\0';
254         }
255         else {
256                 sprintf(surface->output_name, "dp_");
257                 strcpy(surface->output_name2,surface->output_name);
258         }
259
260         if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
261                 strcat(surface->output_name,"paintmap");
262                 strcat(surface->output_name2,"wetmap");
263         }
264         else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
265                 strcat(surface->output_name,"displace");
266         }
267         else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
268                 strcat(surface->output_name,"weight");
269         }
270         else if (surface->type == MOD_DPAINT_SURFACE_T_IWAVE) {
271                 strcat(surface->output_name,"iwave");
272                 strcat(surface->output_name2,"foam");
273         }
274
275         /* update preview */
276         if (dynamicPaint_surfaceHasPreview(surface))
277                 dynamicPaint_setPreview(surface);
278         else
279                 dynamicPaint_resetPreview(surface->canvas);
280 }
281
282 static int surfaceDublicateNameExists(void *arg, const char *name)
283 {
284         DynamicPaintSurface *t_surface = (DynamicPaintSurface*)arg;
285         DynamicPaintSurface *surface = t_surface->canvas->surfaces.first;
286
287         for(; surface; surface=surface->next) {
288                 if (surface!=t_surface && !strcmp(name, surface->name)) return 1;
289         }
290         return 0;
291 }
292
293 void dynamicPaintSurface_setUniqueName(DynamicPaintSurface *surface, char *basename) {
294         char name[64];
295         strncpy(name, basename, 62); /* in case basename is surface->name use a copy */
296         BLI_uniquename_cb(surfaceDublicateNameExists, surface, name, '.', surface->name, sizeof(surface->name));
297 }
298
299 /***************************** Freeing data ******************************/
300
301 /* Free brush data */
302 static void dynamicPaint_freeBrush(struct DynamicPaintModifierData *pmd)
303 {
304         if(pmd->brush) {
305                 if(pmd->brush->dm)
306                         pmd->brush->dm->release(pmd->brush->dm);
307                 pmd->brush->dm = NULL;
308
309                 if(pmd->brush->paint_ramp)
310                          MEM_freeN(pmd->brush->paint_ramp);
311                 pmd->brush->paint_ramp = NULL;
312
313                 MEM_freeN(pmd->brush);
314                 pmd->brush = NULL;
315         }
316 }
317
318 static void dynamicPaint_freeSurfaceData(DynamicPaintSurface *surface)
319 {
320         PaintSurfaceData *data = surface->data;
321         if (!data) return;
322
323         if (data->format_data) MEM_freeN(data->format_data);
324         if (data->type_data) MEM_freeN(data->type_data);
325
326         MEM_freeN(surface->data);
327         surface->data = NULL;
328 }
329
330 static void dynamicPaint_freeSurface(DynamicPaintSurface *surface)
331 {
332         if (!surface) return;
333
334         /* point cache */
335         BKE_ptcache_free_list(&(surface->ptcaches));
336         surface->pointcache = NULL;
337
338         BLI_remlink(&(surface->canvas->surfaces), surface);
339         dynamicPaint_freeSurfaceData(surface);
340         MEM_freeN(surface);
341 }
342
343 /* Free canvas data */
344 static void dynamicPaint_freeCanvas(DynamicPaintModifierData *pmd)
345 {
346         if(pmd->canvas) {
347                 /* Free surface data */
348                 DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
349                 DynamicPaintSurface *next_surface = NULL;
350
351                 while (surface) {
352                         next_surface = surface->next;
353                         dynamicPaint_freeSurface(surface);
354                         surface = next_surface;
355                 }
356
357                 /* free dm copy */
358                 if (pmd->canvas->dm)
359                         pmd->canvas->dm->release(pmd->canvas->dm);
360                 pmd->canvas->dm = NULL;
361
362                 MEM_freeN(pmd->canvas);
363                 pmd->canvas = NULL;
364         }
365 }
366
367 /* Free whole dp modifier */
368 void dynamicPaint_Modifier_free(struct DynamicPaintModifierData *pmd)
369 {
370         if(pmd) {
371                 dynamicPaint_freeCanvas(pmd);
372                 dynamicPaint_freeBrush(pmd);
373         }
374 }
375
376
377 /***************************** Initialize and reset ******************************/
378
379 /*
380 *       Creates a new surface and adds it to the list
381 *       A pointer to this surface is returned
382 */
383 static DynamicPaintSurface *dynamicPaint_createNewSurface(DynamicPaintCanvasSettings *canvas)
384 {
385         DynamicPaintSurface *surface= MEM_callocN(sizeof(DynamicPaintSurface), "DynamicPaintSurface");
386         if (!surface) return NULL;
387
388         surface->canvas = canvas;
389         surface->format = MOD_DPAINT_SURFACE_F_VERTEX;
390         surface->type = MOD_DPAINT_SURFACE_T_PAINT;
391
392         /* cache */
393         surface->pointcache = BKE_ptcache_add(&(surface->ptcaches));
394         surface->pointcache->flag |= PTCACHE_DISK_CACHE;
395         surface->pointcache->step = 1;
396
397         /* Set initial values */
398         surface->flags = MOD_DPAINT_ANTIALIAS | MOD_DPAINT_MULALPHA | MOD_DPAINT_DRY_LOG | MOD_DPAINT_ACTIVE | MOD_DPAINT_PREVIEW;
399         surface->effect = 0;
400         surface->effect_ui = 1;
401
402         surface->diss_speed = 300;
403         surface->dry_speed = 300;
404         surface->disp_depth = 1.0f;
405         surface->disp_type = MOD_DPAINT_DISP_DISPLACE;
406         surface->image_fileformat = MOD_DPAINT_IMGFORMAT_PNG;
407
408         surface->image_resolution = 256;
409         surface->start_frame = 1;
410         surface->end_frame = 250;
411         surface->substeps = 0;
412
413         surface->spread_speed = 1.0f;
414         surface->drip_speed = 1.0f;
415         surface->shrink_speed = 1.0f;
416
417         sprintf(surface->image_output_path, "%sdynamicpaint/", "/tmp/");
418         dynamicPaintSurface_setUniqueName(surface, "Surface");
419
420
421         dynamicPaintSurface_updateType(surface);
422
423         BLI_addtail(&canvas->surfaces, surface);
424
425         return surface;
426 }
427
428 /*
429 *       Initialize modifier data
430 */
431 void dynamicPaint_Modifier_createType(struct DynamicPaintModifierData *pmd)
432 {
433         if(pmd)
434         {
435                 if(pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS)
436                 {
437                         if(pmd->canvas)
438                                 dynamicPaint_freeCanvas(pmd);
439
440                         pmd->canvas = MEM_callocN(sizeof(DynamicPaintCanvasSettings), "DynamicPaint Canvas");
441                         pmd->canvas->pmd = pmd;
442                         pmd->canvas->dm = NULL;
443
444                         /* Create one surface */
445                         dynamicPaint_createNewSurface(pmd->canvas);
446
447                         pmd->canvas->ui_info[0] = '\0';
448
449                 }
450                 else if(pmd->type & MOD_DYNAMICPAINT_TYPE_BRUSH)
451                 {
452                         if(pmd->brush)
453                                 dynamicPaint_freeBrush(pmd);
454
455                         pmd->brush = MEM_callocN(sizeof(DynamicPaintBrushSettings), "DynamicPaint Paint");
456                         pmd->brush->pmd = pmd;
457
458                         pmd->brush->psys = NULL;
459
460                         pmd->brush->flags = 0;
461                         pmd->brush->collision = MOD_DPAINT_COL_VOLUME;
462                         
463                         pmd->brush->mat = NULL;
464                         pmd->brush->r = 1.0f;
465                         pmd->brush->g = 1.0f;
466                         pmd->brush->b = 1.0f;
467                         pmd->brush->alpha = 1.0f;
468                         pmd->brush->wetness = 1.0f;
469
470                         pmd->brush->paint_distance = 0.1f;
471                         pmd->brush->proximity_falloff = MOD_DPAINT_PRFALL_SHARP;
472
473                         pmd->brush->displace_distance = 0.5f;
474                         pmd->brush->prox_displace_strength = 0.5f;
475
476                         pmd->brush->particle_radius = 0.2;
477                         pmd->brush->particle_smooth = 0.05;
478
479                         pmd->brush->dm = NULL;
480
481                         /*
482                         *       Paint proximity falloff colorramp.
483                         */
484                         {
485                                 CBData *ramp;
486
487                                 pmd->brush->paint_ramp = add_colorband(0);
488                                 ramp = pmd->brush->paint_ramp->data;
489                                 /* Add default smooth-falloff ramp.     */
490                                 ramp[0].r = ramp[0].g = ramp[0].b = ramp[0].a = 1.0f;
491                                 ramp[0].pos = 0.0f;
492                                 ramp[1].r = ramp[1].g = ramp[1].b = ramp[1].pos = 1.0f;
493                                 ramp[1].a = 0.0f;
494                                 pmd->brush->paint_ramp->tot = 2;
495                         }
496                 }
497         }
498 }
499
500 void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tpmd)
501 {
502         /* Init modifier        */
503         tpmd->type = pmd->type;
504         dynamicPaint_Modifier_createType(tpmd);
505
506         /* Copy data    */
507         if (tpmd->canvas) {
508                 pmd->canvas->pmd = tpmd;
509
510                 tpmd->canvas->ui_info[0] = '\0';
511
512                 /*tpmd->canvas->flags = pmd->canvas->flags;
513                 tpmd->canvas->output = pmd->canvas->output;
514                 tpmd->canvas->disp_type = pmd->canvas->disp_type;
515                 tpmd->canvas->disp_format = pmd->canvas->disp_format;
516                 tpmd->canvas->effect = pmd->canvas->effect;
517                 tpmd->canvas->effect_ui = 1;
518
519                 tpmd->canvas->resolution = pmd->canvas->resolution;
520                 tpmd->canvas->start_frame = pmd->canvas->start_frame;
521                 tpmd->canvas->end_frame = pmd->canvas->end_frame;
522                 tpmd->canvas->substeps = pmd->canvas->substeps;
523
524                 tpmd->canvas->dry_speed = pmd->canvas->dry_speed;
525                 tpmd->canvas->diss_speed = pmd->canvas->diss_speed;
526                 tpmd->canvas->disp_depth = pmd->canvas->disp_depth;
527                 tpmd->canvas->dflat_speed = pmd->canvas->dflat_speed;
528
529                 strncpy(tpmd->canvas->paint_output_path, pmd->canvas->paint_output_path, 240);
530                 strncpy(tpmd->canvas->wet_output_path, pmd->canvas->wet_output_path, 240);
531                 strncpy(tpmd->canvas->displace_output_path, pmd->canvas->displace_output_path, 240);
532
533                 tpmd->canvas->spread_speed = pmd->canvas->spread_speed;
534                 tpmd->canvas->drip_speed = pmd->canvas->drip_speed;
535                 tpmd->canvas->shrink_speed = pmd->canvas->shrink_speed;
536
537                 strncpy(tpmd->canvas->uvlayer_name, tpmd->canvas->uvlayer_name, 32);*/
538
539         } else if (tpmd->brush) {
540                 pmd->brush->pmd = tpmd;
541
542                 tpmd->brush->flags = pmd->brush->flags;
543                 tpmd->brush->collision = pmd->brush->collision;
544
545                 tpmd->brush->r = pmd->brush->r;
546                 tpmd->brush->g = pmd->brush->g;
547                 tpmd->brush->b = pmd->brush->b;
548                 tpmd->brush->alpha = pmd->brush->alpha;
549                 tpmd->brush->wetness = pmd->brush->wetness;
550
551                 tpmd->brush->particle_radius = pmd->brush->particle_radius;
552                 tpmd->brush->particle_smooth = pmd->brush->particle_smooth;
553                 tpmd->brush->paint_distance = pmd->brush->paint_distance;
554                 tpmd->brush->psys = pmd->brush->psys;
555                 tpmd->brush->displace_distance = pmd->brush->displace_distance;
556                 tpmd->brush->prox_displace_strength = pmd->brush->prox_displace_strength;
557
558                 tpmd->brush->paint_ramp = pmd->brush->paint_ramp;
559
560                 tpmd->brush->proximity_falloff = pmd->brush->proximity_falloff;
561         }
562 }
563
564 /* allocates surface data depending on surface type */
565 static void dynamicPaint_allocateSurfaceType(DynamicPaintSurface *surface)
566 {
567         PaintSurfaceData *sData = surface->data;
568
569         if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
570                 sData->type_data = MEM_callocN(sizeof(PaintPoint)*sData->total_points, "DynamicPaintSurface Data");
571         }
572         else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
573                 sData->type_data = MEM_callocN(sizeof(float)*sData->total_points, "DynamicPaintSurface DepthData");
574         }
575         else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
576                 sData->type_data = MEM_callocN(sizeof(float)*sData->total_points, "DynamicPaintSurface WeightData");
577         }
578         else if (surface->type == MOD_DPAINT_SURFACE_T_IWAVE) {
579                 sData->type_data = MEM_callocN(sizeof(PaintIWavePoint)*sData->total_points, "DynamicPaintSurface iWaveData");
580         }
581         else return;
582
583         if (sData->type_data == NULL) printError(surface->canvas, "Not enough memory!");
584 }
585
586 static void dynamicPaint_surfaceSetInitialValues(DynamicPaintSurface *surface) {
587         if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
588                 PaintPoint* pPoint = (PaintPoint*)surface->data->type_data;
589                 int i;
590                 for (i=0; i<surface->data->total_points; i++) {
591                         memcpy(pPoint[i].color, surface->intitial_color, sizeof(float)*4);
592                 }
593         }
594 }
595
596 /* (re)initialize surface data (only for point cache types)*/
597 int dynamicPaint_resetSurface(DynamicPaintSurface *surface)
598 {
599         int numOfPoints = dynamicPaint_surfaceNumOfPoints(surface);
600         /* dont touch image sequence types. they get handled only on bake */
601         if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) return 1;
602
603         if (surface->data) dynamicPaint_freeSurfaceData(surface);
604         if (numOfPoints < 1) return 0;
605
606         /* allocate memory */
607         surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData");
608         if (!surface->data) return 0;
609
610         /* allocate data depending on surface type and format */
611         surface->data->total_points = numOfPoints;
612         dynamicPaint_allocateSurfaceType(surface);
613         dynamicPaint_surfaceSetInitialValues(surface);
614
615         return 1;
616 }
617
618 /* make sure allocated surface size matches current requirements */
619 static void dynamicPaint_checkSurfaceData(DynamicPaintSurface *surface)
620 {
621         if (!surface->data || ((dynamicPaint_surfaceNumOfPoints(surface) != surface->data->total_points))) {
622                 dynamicPaint_resetSurface(surface);
623         }
624 }
625
626
627 /***************************** Modifier processing ******************************/
628
629
630 /* update cache frame range */
631 void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface) {
632         if (surface->pointcache) {
633                 surface->pointcache->startframe = surface->start_frame;
634                 surface->pointcache->endframe = surface->end_frame;
635         }
636 }
637
638 /*
639 *       Updates derived mesh copy and processes dynamic paint step / caches.
640 */
641 static void dynamicPaint_canvasUpdate(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
642 {
643         if((pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS) && pmd->canvas) {
644                 DynamicPaintCanvasSettings *canvas = pmd->canvas;
645                 DynamicPaintSurface *surface = canvas->surfaces.first;
646
647                 /* update derived mesh copy */
648                 if (canvas->dm) canvas->dm->release(canvas->dm);
649                         canvas->dm = CDDM_copy(dm);
650
651                 /* in case image sequence baking, stop here */
652                 if (canvas->flags & MOD_DPAINT_BAKING) return;
653
654                 /* loop through surfaces */
655                 for (; surface; surface=surface->next) {
656                         int current_frame = (int)scene->r.cfra;
657
658                         /* image sequences are handled by bake operator */
659                         if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) continue;
660                         if (!(surface->flags & MOD_DPAINT_ACTIVE)) continue;
661
662                         /* make sure surface is valid */
663                         dynamicPaint_checkSurfaceData(surface);
664
665                         /* limit frame range */
666                         CLAMP(current_frame, surface->start_frame, surface->end_frame);
667
668                         if (current_frame != surface->current_frame || (int)scene->r.cfra == surface->start_frame) {
669                                 PointCache *cache = surface->pointcache;
670                                 PTCacheID pid;
671                                 surface->current_frame = current_frame;
672
673                                 /* read point cache */
674                                 BKE_ptcache_id_from_dynamicpaint(&pid, ob, surface);
675                                 pid.cache->startframe = surface->start_frame;
676                                 pid.cache->endframe = surface->end_frame;
677                                 BKE_ptcache_id_time(&pid, scene, scene->r.cfra, NULL, NULL, NULL);
678
679                                 /* reset non-baked cache at first frame */
680                                 if((int)scene->r.cfra == surface->start_frame && !(cache->flag & PTCACHE_BAKED))
681                                 {
682                                         cache->flag |= PTCACHE_REDO_NEEDED;
683                                         BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
684                                         cache->flag &= ~PTCACHE_REDO_NEEDED;
685                                 }
686
687                                 /* try to read from cache */
688                                 if(BKE_ptcache_read(&pid, (float)scene->r.cfra)) {
689                                         BKE_ptcache_validate(cache, (int)scene->r.cfra);
690                                 }
691                                 /* if read failed and we're on surface range do recalculate */
692                                 else if ((int)scene->r.cfra == current_frame) {
693                                         /* calculate surface frame */
694                                         dynamicPaint_calculateFrame(surface, scene, ob, current_frame);
695
696                                         BKE_ptcache_validate(cache, surface->current_frame);
697                                         BKE_ptcache_write(&pid, surface->current_frame);
698                                 }
699                         }
700                 }
701         }
702         else if((pmd->type & MOD_DYNAMICPAINT_TYPE_BRUSH) && pmd->brush) {
703
704                 if (pmd->brush->dm) pmd->brush->dm->release(pmd->brush->dm);
705                 pmd->brush->dm = CDDM_copy(dm);
706         }
707 }
708
709 /*
710 *       Apply canvas data to the object derived mesh
711 */
712 struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
713 {       
714         DerivedMesh *result = CDDM_copy(dm);
715
716         if((pmd->type & MOD_DYNAMICPAINT_TYPE_CANVAS) && pmd->canvas &&
717                 !(pmd->canvas->flags & MOD_DPAINT_BAKING)) {
718
719                 DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
720                 pmd->canvas->flags &= ~MOD_DPAINT_PREVIEW_READY;
721
722                 /* loop through surfaces */
723                 for (; surface; surface=surface->next) {
724
725                         if (surface && surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ && surface->data) {
726                                 if (!(surface->flags & (MOD_DPAINT_ACTIVE))) continue;
727
728                                 /* process vertex surface previews */
729                                 if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
730
731                                         /* vertex color paint */
732                                         if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
733
734                                                 MFace *mface = result->getFaceArray(result);
735                                                 int numOfFaces = result->getNumFaces(result);
736                                                 int i,j;
737                                                 PaintPoint* pPoint = (PaintPoint*)surface->data->type_data;
738                                                 MCol *col;
739
740                                                 /* paint is stored on dry and wet layers, so mix final color first */
741                                                 float *fcolor = MEM_callocN(sizeof(float)*surface->data->total_points*4, "Temp paint color");
742                                                 for (i=0; i<surface->data->total_points; i++) {
743                                                         j=i*4;
744                                                         /* If dry layer already has a color, blend it */
745                                                         if (pPoint[i].alpha) {
746                                                                 float invAlpha = 1.0f - pPoint[i].e_alpha;
747                                                                 fcolor[j]   = pPoint[i].color[0] * invAlpha + pPoint[i].e_color[0] * pPoint[i].e_alpha;
748                                                                 fcolor[j+1] = pPoint[i].color[1] * invAlpha + pPoint[i].e_color[1] * pPoint[i].e_alpha;
749                                                                 fcolor[j+2] = pPoint[i].color[2] * invAlpha + pPoint[i].e_color[2] * pPoint[i].e_alpha;
750                                                         }
751                                                         else {
752                                                                 /* Else use effect layer color  */
753                                                                 fcolor[j]   = pPoint[i].e_color[0];
754                                                                 fcolor[j+1] = pPoint[i].e_color[1];
755                                                                 fcolor[j+2] = pPoint[i].e_color[2];
756                                                         }
757                                                         /* Set use highest alpha        */
758                                                         fcolor[j+3] = (pPoint[i].e_alpha > pPoint[i].alpha) ? pPoint[i].e_alpha : pPoint[i].alpha;
759                                                 }
760
761                                                 /* viewport preview */
762                                                 if (surface->flags & MOD_DPAINT_PREVIEW) {
763                                                         /* Save preview results to weight layer, to be
764                                                         *   able to share same drawing methods */
765                                                         col = result->getFaceDataArray(result, CD_WEIGHT_MCOL);
766                                                         if (!col) col = CustomData_add_layer(&result->faceData, CD_WEIGHT_MCOL, CD_CALLOC, NULL, numOfFaces);
767
768                                                         if (col) {
769                                                                 for (i=0; i<numOfFaces; i++) {
770                                                                         int j=0;
771                                                                         float invAlpha;
772                                                                         Material *material = give_current_material(ob, mface[i].mat_nr+1);
773
774                                                                         for (; j<((mface[i].v4)?4:3); j++) {
775                                                                                 int index = (j==0)?mface[i].v1: (j==1)?mface[i].v2: (j==2)?mface[i].v3: mface[i].v4;
776                                                                                 index *= 4;
777                                                                                 invAlpha = 1.0f - fcolor[index+3];
778
779                                                                                 /* Apply material color as base vertex color for preview */
780                                                                                 col[i*4+j].a = 255;
781                                                                                 if (material) {
782                                                                                         col[i*4+j].r = (unsigned char)(material->b*255);
783                                                                                         col[i*4+j].g = (unsigned char)(material->g*255);
784                                                                                         col[i*4+j].b = (unsigned char)(material->r*255);
785                                                                                 }
786                                                                                 else {
787                                                                                         col[i*4+j].r = 165;
788                                                                                         col[i*4+j].g = 165;
789                                                                                         col[i*4+j].b = 165;
790                                                                                 }
791
792                                                                                 /* mix surface color */
793                                                                                 col[i*4+j].r = (char)(((float)col[i*4+j].r)*invAlpha + (fcolor[index+2]*255*fcolor[index+3]));
794                                                                                 col[i*4+j].g = (char)(((float)col[i*4+j].g)*invAlpha + (fcolor[index+1]*255*fcolor[index+3]));
795                                                                                 col[i*4+j].b = (char)(((float)col[i*4+j].b)*invAlpha + (fcolor[index]*255*fcolor[index+3]));
796                                                                         }
797                                                                 }
798                                                                 pmd->canvas->flags |= MOD_DPAINT_PREVIEW_READY;
799                                                         }
800                                                 }
801
802
803                                                 /* save layer data to output layer */
804
805                                                 /* paint layer */
806                                                 col = CustomData_get_layer_named(&dm->faceData, CD_MCOL, surface->output_name);
807                                                 if (col) {
808                                                         for (i=0; i<numOfFaces; i++) {
809                                                                 int j=0;
810                                                                 for (; j<((mface[i].v4)?4:3); j++) {
811                                                                         int index = (j==0)?mface[i].v1: (j==1)?mface[i].v2: (j==2)?mface[i].v3: mface[i].v4;
812                                                                         index *= 4;
813
814                                                                         col[i*4+j].a = (char)(fcolor[index+3]*255);
815                                                                         col[i*4+j].r = (char)(fcolor[index+2]*255);
816                                                                         col[i*4+j].g = (char)(fcolor[index+1]*255);
817                                                                         col[i*4+j].b = (char)(fcolor[index]*255);
818                                                                 }
819                                                         }
820                                                 }
821                                                 MEM_freeN(fcolor);
822
823                                                 /* wet layer */
824                                                 col = CustomData_get_layer_named(&dm->faceData, CD_MCOL, surface->output_name2);
825                                                 if (col) {
826                                                         for (i=0; i<numOfFaces; i++) {
827                                                                 int j=0;
828
829                                                                 for (; j<((mface[i].v4)?4:3); j++) {
830                                                                         int index = (j==0)?mface[i].v1: (j==1)?mface[i].v2: (j==2)?mface[i].v3: mface[i].v4;
831
832                                                                         col[i*4+j].a = 255;
833                                                                         col[i*4+j].r = (char)(pPoint[index].wetness*255);
834                                                                         col[i*4+j].g = (char)(pPoint[index].wetness*255);
835                                                                         col[i*4+j].b = (char)(pPoint[index].wetness*255);
836                                                                 }
837                                                         }
838                                                 }
839                                         }
840                                         /* displace paint */
841                                         else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
842                                                 MVert *mvert = result->getVertArray(result);
843                                                 int i;
844                                                 float normal[3];
845                                                 float* value = (float*)surface->data->type_data;
846
847                                                 for (i=0; i<surface->data->total_points; i++) {
848                                                         normal_short_to_float_v3(normal, mvert[i].no);
849                                                         normalize_v3(normal);
850
851                                                         mvert[i].co[0] -= normal[0]*value[i];
852                                                         mvert[i].co[1] -= normal[1]*value[i];
853                                                         mvert[i].co[2] -= normal[2]*value[i];
854                                                 }
855
856                                                 CDDM_calc_normals(result);
857                                         }
858                                         /* vertex group paint */
859                                         else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) {
860                                         }
861                                 }
862                         }
863                 }
864         }
865
866         return result;
867 }
868
869 /* Modifier call. Processes dynamic paint modifier step. */
870 struct DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, Scene *scene, Object *ob, DerivedMesh *dm)
871 {       
872         /* Update derived mesh data to modifier if baking       */
873         dynamicPaint_canvasUpdate(pmd, scene, ob, dm);
874
875         /* Return output mesh */
876         return dynamicPaint_Modifier_apply(pmd, scene, ob, dm);
877 }
878
879
880 /***************************** Image Sequence / UV Image Canvas Calls ******************************/
881
882 #if 0
883 /*
884 *       Tries to find the neighbouring pixel in given (uv space) direction.
885 *       Result is used by effect system to move paint on the surface.
886 *
887 *   px,py : origin pixel x and y
888 *       n_index : lookup direction index (use neighX,neighY to get final index)
889 */
890 static int dynamicPaint_findNeighbourPixel(DynamicPaintSurface *surface, int px, int py, int n_index)
891 {
892         /* Note: Current method only uses polygon edges to detect neighbouring pixels.
893         *  -> It doesn't always lead to the optimum pixel but is accurate enough
894         *  and faster/simplier than including possible face tip point links)
895         */
896
897         int x,y;
898         DynamicPaintSurfacePoint *tPoint = NULL;
899         DynamicPaintSurfacePoint *cPoint = NULL;
900         PaintSurfaceData *sData = surface->data;
901
902         x = px + neighX[n_index];
903         y = py + neighY[n_index];
904
905         if (x<0 || x>=surface->image_resolution) return -1;
906         if (y<0 || y>=surface->image_resolution) return -1;
907
908         tPoint = &((PaintTexturePoint*)sData->format_data)[x+surface->image_resolution*y];              /* UV neighbour */
909         
910         cPoint = &((PaintTexturePoint*)sData->format_data)[px+surface->image_resolution*py];            /* Origin point */
911
912         /*
913         *       Check if target point is on same face -> mark it as neighbour
914         *   (and if it isn't marked as an "edge pixel")
915         */
916         if ((tPoint->index == cPoint->index) && (tPoint->neighbour_pixel == -1)) {
917                 /* If it's on the same face, it has to be a correct neighbour   */
918                 return (x+surface->w*y);
919         }
920
921
922         /*
923         *       If the uv neighbour is mapped directly to
924         *       a face -> use this point.
925         *       
926         *       !! Replace with "is uv faces linked" check !!
927         *       This should work fine as long as uv island
928         *       margin is > 1 pixel.
929         */
930         if ((tPoint->index != -1) && (tPoint->neighbour_pixel == -1)) {
931                 return (x+surface->w*y);
932         }
933
934         /*
935         *       If we get here, the actual neighbouring pixel
936         *       points to a non-linked uv face, and we have to find
937         *       it's "real" neighbour.
938         *
939         *       Simple neighbouring face finding algorithm:
940         *       - find closest uv edge to that pixel and get
941         *         the other face connected to that edge on actual mesh
942         *       - find corresponding position of that new face edge
943         *         in uv space
944         *
945         *       TODO: Implement something more accurate / optimized?
946         */
947         {
948                 int numOfFaces = canvas->dm->getNumFaces(canvas->dm);
949                 MVert *mvert = NULL;
950                 MFace *mface = NULL;
951                 MTFace *tface = NULL;
952
953                 mvert = canvas->dm->getVertArray(canvas->dm);
954                 mface = canvas->dm->getFaceArray(canvas->dm);
955                 tface = DM_get_face_data_layer(canvas->dm, CD_MTFACE);
956
957                 /* Get closest edge to that subpixel on UV map  */
958                 {
959                         float pixel[2], dist, t_dist;
960                         int i, uindex[2], edge1_index, edge2_index, e1_index, e2_index, target_face;
961
962                         float closest_point[2], lambda, dir_vec[2];
963                         int target_uv1, target_uv2, final_pixel[2], final_index;
964
965                         float (*s_uv1),(*s_uv2), (*t_uv1), (*t_uv2);
966
967                         pixel[0] = ((float)(px + neighX[n_index]) + 0.5f) / (float)surface->w;
968                         pixel[1] = ((float)(py + neighY[n_index]) + 0.5f) / (float)surface->h;
969
970                         /* Get uv indexes for current face part */
971                         if (cPoint->quad) {
972                                 uindex[0] = 0; uindex[1] = 2; uindex[2] = 3;
973                         }
974                         else {
975                                 uindex[0] = 0; uindex[1] = 1; uindex[2] = 2;
976                         }
977
978                         /*
979                         *       Find closest edge to that pixel
980                         */
981                         /* Dist to first edge   */
982                         e1_index = cPoint->v1; e2_index = cPoint->v2; edge1_index = uindex[0]; edge2_index = uindex[1];
983                         dist = dist_to_line_segment_v2(pixel, tface[cPoint->index].uv[edge1_index], tface[cPoint->index].uv[edge2_index]);
984
985                         /* Dist to second edge  */
986                         t_dist = dist_to_line_segment_v2(pixel, tface[cPoint->index].uv[uindex[1]], tface[cPoint->index].uv[uindex[2]]);
987                         if (t_dist < dist) {e1_index = cPoint->v2; e2_index = cPoint->v3; edge1_index = uindex[1]; edge2_index = uindex[2]; dist = t_dist;}
988
989                         /* Dist to third edge   */
990                         t_dist = dist_to_line_segment_v2(pixel, tface[cPoint->index].uv[uindex[2]], tface[cPoint->index].uv[uindex[0]]);
991                         if (t_dist < dist) {e1_index = cPoint->v3; e2_index = cPoint->v1;  edge1_index = uindex[2]; edge2_index = uindex[0]; dist = t_dist;}
992
993
994                         /*
995                         *       Now find another face that is linked to that edge
996                         */
997                         target_face = -1;
998
999                         for (i=0; i<numOfFaces; i++) {
1000                                 /*
1001                                 *       Check if both edge vertices share this face
1002                                 */
1003                                 int v4 = -1;
1004                                 if (mface[i].v4) v4 = mface[i].v4;
1005
1006                                 if ((e1_index == mface[i].v1 || e1_index == mface[i].v2 || e1_index == mface[i].v3 || e1_index == v4) &&
1007                                         (e2_index == mface[i].v1 || e2_index == mface[i].v2 || e2_index == mface[i].v3 || e2_index == v4)) {
1008                                         if (i == cPoint->index) continue;
1009
1010                                         target_face = i;
1011
1012                                         /*
1013                                         *       Get edge UV index
1014                                         */
1015                                         if (e1_index == mface[i].v1) target_uv1 = 0;
1016                                         else if (e1_index == mface[i].v2) target_uv1 = 1;
1017                                         else if (e1_index == mface[i].v3) target_uv1 = 2;
1018                                         else target_uv1 = 3;
1019
1020                                         if (e2_index == mface[i].v1) target_uv2 = 0;
1021                                         else if (e2_index == mface[i].v2) target_uv2 = 1;
1022                                         else if (e2_index == mface[i].v3) target_uv2 = 2;
1023                                         else target_uv2 = 3;
1024
1025                                         break;
1026                                 }
1027                         }
1028
1029                         /* If none found return -1      */
1030                         if (target_face == -1) return -1;
1031
1032                         /*
1033                         *       If target face is connected in UV space as well, just use original index
1034                         */
1035                         s_uv1 = (float *)tface[cPoint->index].uv[edge1_index];
1036                         s_uv2 = (float *)tface[cPoint->index].uv[edge2_index];
1037                         t_uv1 = (float *)tface[target_face].uv[target_uv1];
1038                         t_uv2 = (float *)tface[target_face].uv[target_uv2];
1039
1040                         //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]);
1041
1042                         if (((s_uv1[0] == t_uv1[0] && s_uv1[1] == t_uv1[1]) &&
1043                                  (s_uv2[0] == t_uv2[0] && s_uv2[1] == t_uv2[1]) ) ||
1044                                 ((s_uv2[0] == t_uv1[0] && s_uv2[1] == t_uv1[1]) &&
1045                                  (s_uv1[0] == t_uv2[0] && s_uv1[1] == t_uv2[1]) )) return ((px+neighX[n_index]) + surface->w*(py+neighY[n_index]));
1046
1047                         /*
1048                         *       Find a point that is relatively at same edge position
1049                         *       on this other face UV
1050                         */
1051                         lambda = closest_to_line_v2(closest_point, pixel, tface[cPoint->index].uv[edge1_index], tface[cPoint->index].uv[edge2_index]);
1052                         if (lambda < 0.0f) lambda = 0.0f;
1053                         if (lambda > 1.0f) lambda = 1.0f;
1054
1055                         sub_v2_v2v2(dir_vec, tface[target_face].uv[target_uv2], tface[target_face].uv[target_uv1]);
1056
1057                         mul_v2_fl(dir_vec, lambda);
1058
1059                         copy_v2_v2(pixel, tface[target_face].uv[target_uv1]);
1060                         add_v2_v2(pixel, dir_vec);
1061                         pixel[0] = (pixel[0] * (float)surface->w) - 0.5f;
1062                         pixel[1] = (pixel[1] * (float)surface->h) - 0.5f;
1063
1064                         final_pixel[0] = (int)floor(pixel[0]);
1065                         final_pixel[1] = (int)floor(pixel[1]);
1066
1067                         /* If current pixel uv is outside of texture    */
1068                         if (final_pixel[0] < 0 || final_pixel[0] >= surface->w) return -1;
1069                         if (final_pixel[1] < 0 || final_pixel[1] >= surface->h) return -1;
1070
1071                         final_index = final_pixel[0] + surface->w * final_pixel[1];
1072
1073                         /* If we ended up to our origin point ( mesh has smaller than pixel sized faces)        */
1074                         if (final_index == (px+surface->w*py)) return -1;
1075                         /* If found pixel still lies on wrong face ( mesh has smaller than pixel sized faces)   */
1076                         if (surface->point[final_index].index != target_face) return -1;
1077
1078                         /*
1079                         *       If final point is an "edge pixel", use it's "real" neighbour instead
1080                         */
1081                         if (surface->point[final_index].neighbour_pixel != -1) final_index = cPoint->neighbour_pixel;
1082
1083                         return final_index;
1084                 }
1085         }
1086 }
1087 #endif
1088
1089 /*
1090 *       Create a surface for image sequence format
1091 */
1092 static int dynamicPaint_createUVSurface(DynamicPaintSurface *surface)
1093 {
1094         /* Antialias jitter point relative coords       */
1095         float jitter5sample[10] =  {0.0f, 0.0f,
1096                                                         -0.2f, -0.4f,
1097                                                         0.2f, 0.4f,
1098                                                         0.4f, -0.2f,
1099                                                         -0.4f, 0.3f};
1100         int yy;
1101         int w,h;
1102         int numOfFaces;
1103         char uvname[32];
1104         int active_points = 0;
1105
1106         PaintSurfaceData *sData;
1107         DynamicPaintCanvasSettings *canvas = surface->canvas;
1108         DerivedMesh *dm = canvas->dm;
1109
1110         PaintTexturePoint *tempPoints = NULL;
1111         MVert *mvert = NULL;
1112         MFace *mface = NULL;
1113         MTFace *tface = NULL;
1114         BB2d *faceBB = NULL;
1115
1116         if (!dm) return printError(canvas, "Canvas mesh not updated.");
1117         if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) return printError(canvas, "Can't bake non-\"image sequence\" formats.");
1118
1119         numOfFaces = dm->getNumFaces(dm);
1120         mvert = dm->getVertArray(dm);
1121         mface = dm->getFaceArray(dm);
1122
1123         /* get uv layer */
1124         validate_layer_name(&dm->faceData, CD_MTFACE, surface->uvlayer_name, uvname);
1125         tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, uvname);
1126
1127         /* Check for validity   */
1128         if (!tface) return printError(canvas, "No UV data on canvas.");
1129         if (surface->image_resolution < 16 || surface->image_resolution > 8096) return printError(canvas, "Invalid resolution.");
1130
1131         w = h = surface->image_resolution;
1132
1133         /*
1134         *       Start generating the surface
1135         */
1136         printf("DynamicPaint: Preparing UV surface of %ix%i pixels and %i faces.\n", w, h, numOfFaces);
1137
1138         /* Init data struct */
1139         if (surface->data) dynamicPaint_freeSurfaceData(surface);
1140         sData = surface->data = MEM_callocN(sizeof(PaintSurfaceData), "PaintSurfaceData");
1141         if (!surface->data) return printError(canvas, "Not enough free memory.");
1142
1143         sData->samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1;
1144         tempPoints = (struct PaintTexturePoint *) MEM_callocN(w*h*sizeof(struct PaintTexturePoint), "PaintTexturePoint");
1145         if (tempPoints == NULL) return printError(canvas, "Not enough free memory.");
1146
1147         /*
1148         *       Generate a temporary bounding box array for UV faces to optimize
1149         *       the pixel-inside-a-face search.
1150         */
1151         faceBB = (struct BB2d *) MEM_mallocN(numOfFaces*sizeof(struct BB2d), "MPCanvasFaceBB");
1152         if (faceBB == NULL) return printError(canvas, "Not enough free memory.");
1153
1154         for (yy=0; yy<numOfFaces; yy++) {
1155                 int numOfVert = (mface[yy].v4) ? 4 : 3;
1156                 int i;
1157
1158                 VECCOPY2D(faceBB[yy].min, tface[yy].uv[0]);
1159                 VECCOPY2D(faceBB[yy].max, tface[yy].uv[0]);
1160
1161                 for (i = 1; i<numOfVert; i++) {
1162                         if (tface[yy].uv[i][0] < faceBB[yy].min[0]) faceBB[yy].min[0] = tface[yy].uv[i][0];
1163                         if (tface[yy].uv[i][1] < faceBB[yy].min[1]) faceBB[yy].min[1] = tface[yy].uv[i][1];
1164                         if (tface[yy].uv[i][0] > faceBB[yy].max[0]) faceBB[yy].max[0] = tface[yy].uv[i][0];
1165                         if (tface[yy].uv[i][1] > faceBB[yy].max[1]) faceBB[yy].max[1] = tface[yy].uv[i][1];
1166
1167                 }
1168         }
1169
1170         /*
1171         *       Allocate antialias sample data (without threads due to malloc)
1172         *       (Non threadable?)
1173         */
1174         for (yy = 0; yy < h; yy++)
1175         {
1176                 int xx;
1177                 for (xx = 0; xx < w; xx++)
1178                 {
1179                         int index = xx+w*yy;
1180                         PaintTexturePoint *tPoint = &tempPoints[index];
1181
1182                         /* Initialize barycentricWeights        */
1183                         tPoint->barycentricWeights = (struct Vec3f *) malloc( sData->samples * sizeof(struct Vec3f ));
1184                         if (tPoint->barycentricWeights == NULL) return printError(canvas, "Not enough free memory.");
1185
1186                 }
1187         }
1188
1189         /*
1190         *       Loop through every pixel and check
1191         *       if pixel is uv-mapped on a canvas face.
1192         */
1193         #pragma omp parallel for schedule(static)
1194         for (yy = 0; yy < h; yy++)
1195         {
1196                 int xx;
1197                 for (xx = 0; xx < w; xx++)
1198                 {
1199                         int i, sample;
1200                         int index = xx+w*yy;
1201                         PaintTexturePoint *tPoint = (&tempPoints[index]);
1202
1203                         short isInside = 0;     /* if point is inside a uv face */
1204
1205                         float d1[2], d2[2], d3[2], point[5][2];
1206                         float dot00,dot01,dot02,dot11,dot12, invDenom, u,v;
1207
1208                         /* Init per pixel settings */
1209                         tPoint->face_index = -1;
1210                         tPoint->pixel_index = index;
1211
1212                         /* Actual pixel center, used when collision is found    */
1213                         point[0][0] = ((float)xx + 0.5f) / w;
1214                         point[0][1] = ((float)yy + 0.5f) / h;
1215
1216                         /*
1217                         * A pixel middle sample isn't enough to find very narrow polygons
1218                         * So using 4 samples of each corner too
1219                         */
1220                         point[1][0] = ((float)xx) / w;
1221                         point[1][1] = ((float)yy) / h;
1222
1223                         point[2][0] = ((float)xx+1) / w;
1224                         point[2][1] = ((float)yy) / h;
1225
1226                         point[3][0] = ((float)xx) / w;
1227                         point[3][1] = ((float)yy+1) / h;
1228
1229                         point[4][0] = ((float)xx+1) / w;
1230                         point[4][1] = ((float)yy+1) / h;
1231
1232
1233                         /* Loop through samples, starting from middle point     */
1234                         for (sample=0; sample<5; sample++) {
1235                                 
1236                                 /* Loop through every face in the mesh  */
1237                                 for (i=0; i<numOfFaces; i++) {
1238
1239                                         /* Check uv bb  */
1240                                         if (faceBB[i].min[0] > (point[sample][0])) continue;
1241                                         if (faceBB[i].min[1] > (point[sample][1])) continue;
1242                                         if (faceBB[i].max[0] < (point[sample][0])) continue;
1243                                         if (faceBB[i].max[1] < (point[sample][1])) continue;
1244
1245                                         /*  Calculate point inside a triangle check
1246                                         *       for uv0,1,2 */
1247                                         VECSUB2D(d1,  tface[i].uv[2], tface[i].uv[0]);  // uv2 - uv0
1248                                         VECSUB2D(d2,  tface[i].uv[1], tface[i].uv[0]);  // uv1 - uv0
1249                                         VECSUB2D(d3,  point[sample], tface[i].uv[0]);   // point - uv0
1250
1251                                         dot00 = d1[0]*d1[0] + d1[1]*d1[1];
1252                                         dot01 = d1[0]*d2[0] + d1[1]*d2[1];
1253                                         dot02 = d1[0]*d3[0] + d1[1]*d3[1];
1254                                         dot11 = d2[0]*d2[0] + d2[1]*d2[1];
1255                                         dot12 = d2[0]*d3[0] + d2[1]*d3[1];
1256
1257                                         invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
1258                                         u = (dot11 * dot02 - dot01 * dot12) * invDenom;
1259                                         v = (dot00 * dot12 - dot01 * dot02) * invDenom;
1260
1261                                         if ((u > 0) && (v > 0) && (u + v < 1)) {isInside=1;} /* is inside a triangle */
1262
1263                                         /*  If collision wasn't found but the face is a quad
1264                                         *       do another check for the second half */
1265                                         if ((!isInside) && mface[i].v4)
1266                                         {
1267
1268                                                 /* change d2 to test the other half     */
1269                                                 VECSUB2D(d2,  tface[i].uv[3], tface[i].uv[0]);  // uv3 - uv0
1270
1271                                                 /* test again   */
1272                                                 dot00 = d1[0]*d1[0] + d1[1]*d1[1];
1273                                                 dot01 = d1[0]*d2[0] + d1[1]*d2[1];
1274                                                 dot02 = d1[0]*d3[0] + d1[1]*d3[1];
1275                                                 dot11 = d2[0]*d2[0] + d2[1]*d2[1];
1276                                                 dot12 = d2[0]*d3[0] + d2[1]*d3[1];
1277
1278                                                 invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
1279                                                 u = (dot11 * dot02 - dot01 * dot12) * invDenom;
1280                                                 v = (dot00 * dot12 - dot01 * dot02) * invDenom;
1281
1282                                                 if ((u > 0) && (v > 0) && (u + v < 1)) {isInside=2;} /* is inside the second half of the quad */
1283
1284                                         }
1285
1286                                         /*
1287                                         *       If point was inside the face
1288                                         */
1289                                         if (isInside != 0) {
1290
1291                                                 float uv1co[2], uv2co[2], uv3co[2], uv[2];
1292                                                 int j;
1293
1294                                                 /* Get triagnle uvs     */
1295                                                 if (isInside==1) {
1296                                                         VECCOPY2D(uv1co, tface[i].uv[0]);
1297                                                         VECCOPY2D(uv2co, tface[i].uv[1]);
1298                                                         VECCOPY2D(uv3co, tface[i].uv[2]);
1299                                                 }
1300                                                 else {
1301                                                         VECCOPY2D(uv1co, tface[i].uv[0]);
1302                                                         VECCOPY2D(uv2co, tface[i].uv[2]);
1303                                                         VECCOPY2D(uv3co, tface[i].uv[3]);
1304                                                 }
1305
1306                                                 /* Add b-weights per anti-aliasing sample       */
1307                                                 for (j=0; j<sData->samples; j++) {
1308                                                         uv[0] = point[0][0] + jitter5sample[j*2] / w;
1309                                                         uv[1] = point[0][1] + jitter5sample[j*2+1] / h;
1310
1311                                                         barycentric_weights_v2(uv1co, uv2co, uv3co, uv, tPoint->barycentricWeights[j].v);
1312                                                 }
1313
1314                                                 /* Set surface point face values        */
1315                                                 tPoint->face_index = i;                                                 /* face index */
1316                                                 tPoint->quad = (isInside == 2) ? 1 : 0;         /* quad or tri part*/
1317
1318                                                 /* save vertex indexes  */
1319                                                 tPoint->v1 = (isInside == 2) ? mface[i].v1 : mface[i].v1;
1320                                                 tPoint->v2 = (isInside == 2) ? mface[i].v3 : mface[i].v2;
1321                                                 tPoint->v3 = (isInside == 2) ? mface[i].v4 : mface[i].v3;
1322                                                 
1323                                                 sample = 5;     /* make sure we exit sample loop as well */
1324                                                 break;
1325                                         }
1326                                 }
1327                         } /* sample loop */
1328                 }
1329         }
1330
1331
1332
1333         /*
1334         *       Now loop through every pixel that was left without index
1335         *       and find if they have neighbouring pixels that have an index.
1336         *       If so use that polygon as pixel surface.
1337         *       (To avoid seams on uv island edges)
1338         */
1339         #pragma omp parallel for schedule(static)
1340         for (yy = 0; yy < h; yy++)
1341         {
1342                 int xx;
1343                 for (xx = 0; xx < w; xx++)
1344                 {
1345                         int index = xx+w*yy;
1346                         PaintTexturePoint *tPoint = (&tempPoints[index]);
1347
1348                         /* If point isnt't on canvas mesh       */
1349                         if (tPoint->face_index == -1) {
1350                                 int u_min, u_max, v_min, v_max;
1351                                 int u,v, ind;
1352                                 float point[2];
1353
1354                                 /* get loop area        */
1355                                 u_min = (xx > 0) ? -1 : 0;
1356                                 u_max = (xx < (w-1)) ? 1 : 0;
1357                                 v_min = (yy > 0) ? -1 : 0;
1358                                 v_max = (yy < (h-1)) ? 1 : 0;
1359
1360                                 point[0] = ((float)xx + 0.5f) / w;
1361                                 point[1] = ((float)yy + 0.5f) / h;
1362
1363                                 /* search through defined area for neighbour    */
1364                                 for (u=u_min; u<=u_max; u++)
1365                                         for (v=v_min; v<=v_max; v++) {
1366                                                 /* if not this pixel itself     */
1367                                                 if (u!=0 || v!=0) {
1368                                                         ind = (xx+u)+w*(yy+v);
1369
1370                                                         /* if neighbour has index       */
1371                                                         if (tempPoints[ind].face_index != -1) {
1372
1373                                                                 float uv1co[2], uv2co[2], uv3co[2], uv[2];
1374                                                                 int i = tempPoints[ind].face_index, j;
1375
1376                                                                 /* Now calculate pixel data for this pixel as it was on polygon surface */
1377                                                                 if (!tempPoints[ind].quad) {
1378                                                                         VECCOPY2D(uv1co, tface[i].uv[0]);
1379                                                                         VECCOPY2D(uv2co, tface[i].uv[1]);
1380                                                                         VECCOPY2D(uv3co, tface[i].uv[2]);
1381                                                                 }
1382                                                                 else {
1383                                                                         VECCOPY2D(uv1co, tface[i].uv[0]);
1384                                                                         VECCOPY2D(uv2co, tface[i].uv[2]);
1385                                                                         VECCOPY2D(uv3co, tface[i].uv[3]);
1386                                                                 }
1387
1388                                                                 /* Add b-weights per anti-aliasing sample       */
1389                                                                 for (j=0; j<sData->samples; j++) {
1390
1391                                                                         uv[0] = point[0] + jitter5sample[j*2] / w;
1392                                                                         uv[1] = point[1] + jitter5sample[j*2+1] / h;
1393                                                                         barycentric_weights_v2(uv1co, uv2co, uv3co, uv, tPoint->barycentricWeights[j].v);
1394                                                                 }
1395
1396                                                                 /* Set values   */
1397                                                                 tPoint->neighbour_pixel = ind;                          // face index
1398                                                                 tPoint->quad = tempPoints[ind].quad;            // quad or tri
1399
1400                                                                 /* save vertex indexes  */
1401                                                                 tPoint->v1 = (tPoint->quad) ? mface[i].v1 : mface[i].v1;
1402                                                                 tPoint->v2 = (tPoint->quad) ? mface[i].v3 : mface[i].v2;
1403                                                                 tPoint->v3 = (tPoint->quad) ? mface[i].v4 : mface[i].v3;
1404
1405                                                                 u = u_max + 1;  /* make sure we exit outer loop as well */
1406                                                                 break;
1407                                                         }
1408                                         }
1409                                 }
1410                         }
1411                 }
1412         }
1413
1414         /*
1415         *       When base loop is over convert found neighbour indexes to real ones
1416         *       Also count the final number of active surface points
1417         */
1418
1419         #pragma omp parallel for schedule(static)
1420         for (yy = 0; yy < h; yy++)
1421         {
1422                 int xx;
1423                 for (xx = 0; xx < w; xx++)
1424                 {
1425                         int index = xx+w*yy;
1426                         PaintTexturePoint *tPoint = (&tempPoints[index]);
1427
1428                         if (tPoint->face_index == -1 && tPoint->neighbour_pixel != -1) tPoint->face_index = tempPoints[tPoint->neighbour_pixel].face_index;
1429                         if (tPoint->face_index != -1) active_points++;
1430                 }
1431         }
1432
1433 #if 0
1434         /*  -----------------------------------------------------------------
1435         *       For debug, output pixel statuses to the color map
1436         *       -----------------------------------------------------------------*/
1437         #pragma omp parallel for schedule(static)
1438         for (yy = 0; yy < h; yy++)
1439         {
1440                 int xx;
1441                 for (xx = 0; xx < w; xx++)
1442                 {
1443                         int index = xx+w*yy;
1444                         DynamicPaintSurfacePoint *cPoint = (&surface->point[index]);
1445                         cPoint->alpha=1.0f;
1446
1447                         /* Every pixel that is assigned as "edge pixel" gets blue color */
1448                         if (cPoint->neighbour_pixel != -1) cPoint->color[2] = 1.0f;
1449                         /* and every pixel that finally got an polygon gets red color   */
1450                         if (cPoint->index != -1) cPoint->color[0] = 1.0f;
1451                         /* green color shows pixel face index hash      */
1452                         if (cPoint->index != -1) cPoint->color[1] = (float)(cPoint->index % 255)/256.0f;
1453                 }
1454         }
1455
1456 #endif
1457
1458 #if 0 /* Currently disabled */
1459         /*      If any effect enabled, create surface effect / wet layer
1460         *       neighbour lists. Processes possibly moving data. */
1461         if (surface->effect) {
1462
1463                 #pragma omp parallel for schedule(static)
1464                 for (yy = 0; yy < h; yy++)
1465                 {
1466                         int xx;
1467                         for (xx = 0; xx < w; xx++)
1468                         {
1469                                 int i;
1470                                 DynamicPaintSurfacePoint *cPoint = (&surface->point[xx+w*yy]);
1471
1472                                 /* If current point exists find all it's neighbouring pixels    */
1473                                 if (cPoint->index != -1)
1474                                 for (i=0; i<8; i++) {
1475
1476                                         /* Try to find a neighbouring pixel in defined direction
1477                                         *  If not found, -1 is returned */
1478                                         cPoint->neighbours[i] = dynamicPaint_findNeighbourPixel(canvas, xx, yy, i);
1479                                 }
1480                         }
1481                 }
1482         }
1483 #endif
1484
1485         MEM_freeN(faceBB);
1486
1487         /* Create final surface data without inactive points */
1488         {
1489                 int index, cursor = 0;
1490                 PaintTexturePoint *tPoint = (struct PaintTexturePoint *) MEM_callocN(active_points*sizeof(struct PaintTexturePoint), "PaintTexturePoint");
1491
1492                 sData->format_data = tPoint;
1493                 if (sData->format_data == NULL) return printError(canvas, "Not enough free memory.");
1494                 sData->total_points = active_points;
1495
1496                 for(index = 0; index < (w*h); index++) {
1497                         if (tempPoints[index].face_index != -1) {
1498                                 memcpy(&tPoint[cursor], &tempPoints[index], sizeof(PaintTexturePoint));
1499                                 cursor++;
1500                         }
1501                 }
1502                 MEM_freeN(tempPoints);
1503         }
1504
1505         /* Init surface type data */
1506         dynamicPaint_allocateSurfaceType(surface);
1507
1508         return 1;
1509 }
1510
1511 #define DPOUTPUT_PAINT 0
1512 #define DPOUTPUT_WET 1
1513 #define DPOUTPUT_DISPLACE 2
1514 #define DPOUTPUT_IWAVE 3
1515
1516 /*
1517 *       Outputs an image file from uv surface data.
1518 */
1519 void dynamicPaint_outputImage(DynamicPaintSurface *surface, char* filename, short format, short type)
1520 {
1521         int index;
1522         ImBuf* mhImgB = NULL;
1523         PaintSurfaceData *sData = surface->data;
1524         PaintTexturePoint *tPoint = (PaintTexturePoint*)sData->format_data;
1525         char output_file[250];
1526
1527         if (sData == NULL || sData->type_data == NULL) {printError(surface->canvas, "Image save failed: Invalid surface.");return;}
1528
1529         if (format == DPOUTPUT_JPEG) sprintf(output_file,"%s.jpg",filename);
1530         else if (format == DPOUTPUT_OPENEXR) sprintf(output_file,"%s.exr",filename);
1531         else sprintf(output_file,"%s.png",filename);
1532
1533         /* Validate output file path    */
1534         BLI_path_abs(output_file, G.main->name);
1535         BLI_make_existing_file(output_file);
1536
1537         /* Init image buffer    */
1538         mhImgB = IMB_allocImBuf(surface->image_resolution, surface->image_resolution, 32, IB_rectfloat);
1539         if (mhImgB == NULL) {printError(surface->canvas, "Image save failed: Not enough free memory.");return;}
1540
1541         #pragma omp parallel for schedule(static)
1542         for (index = 0; index < sData->total_points; index++)
1543         {
1544                 int pos=tPoint[index].pixel_index*4;    /* image buffer position */
1545                 
1546
1547                 /* Set values of preferred type */
1548                 if (type == DPOUTPUT_WET) {
1549                         PaintPoint *point = &((PaintPoint*)sData->type_data)[index];
1550                         float value = (point->wetness > 1.0f) ? 1.0f : point->wetness;
1551
1552                         mhImgB->rect_float[pos]=value;
1553                         mhImgB->rect_float[pos+1]=value;
1554                         mhImgB->rect_float[pos+2]=value;
1555                         mhImgB->rect_float[pos+3]=1.0f;
1556                 }
1557                 else if (type == DPOUTPUT_PAINT) {
1558                         PaintPoint *point = &((PaintPoint*)sData->type_data)[index];
1559                         float invAlpha = 1.0f - point->e_alpha;
1560
1561                         /* If base layer already has a color, blend it  */
1562                         if (point->alpha) {
1563                                 mhImgB->rect_float[pos]   = point->color[0] * invAlpha + point->e_color[0] * point->e_alpha;
1564                                 mhImgB->rect_float[pos+1] = point->color[1] * invAlpha + point->e_color[1] * point->e_alpha;
1565                                 mhImgB->rect_float[pos+2] = point->color[2] * invAlpha + point->e_color[2] * point->e_alpha;
1566                         }
1567                         else {
1568                                 /* Else use effect layer color  */
1569                                 mhImgB->rect_float[pos]   = point->e_color[0];
1570                                 mhImgB->rect_float[pos+1] = point->e_color[1];
1571                                 mhImgB->rect_float[pos+2] = point->e_color[2];
1572                         }
1573
1574                         /* use highest alpha    */
1575                         mhImgB->rect_float[pos+3] = (point->e_alpha > point->alpha) ? point->e_alpha : point->alpha;
1576
1577                         /* Multiply color by alpha if enabled   */
1578                         if (surface->flags & MOD_DPAINT_MULALPHA) {
1579                                 mhImgB->rect_float[pos]   *= mhImgB->rect_float[pos+3];
1580                                 mhImgB->rect_float[pos+1] *= mhImgB->rect_float[pos+3];
1581                                 mhImgB->rect_float[pos+2] *= mhImgB->rect_float[pos+3];
1582                         }
1583                 }
1584                 else if (type == DPOUTPUT_DISPLACE) {
1585                         float depth = ((float*)sData->type_data)[index];
1586
1587                         if (surface->disp_type == MOD_DPAINT_DISP_DISPLACE) {
1588                                 depth = (0.5f - depth);
1589                                 if (depth < 0.0f) depth = 0.0f;
1590                                 if (depth > 1.0f) depth = 1.0f;
1591                         }
1592
1593                         mhImgB->rect_float[pos]=depth;
1594                         mhImgB->rect_float[pos+1]=depth;
1595                         mhImgB->rect_float[pos+2]=depth;
1596                         mhImgB->rect_float[pos+3]=1.0f;
1597                 }
1598         }
1599
1600         /* Save image buffer    */
1601         if (format == DPOUTPUT_JPEG) {  /* JPEG */
1602                 mhImgB->ftype= JPG|95;
1603                 IMB_rect_from_float(mhImgB);
1604                 imb_savejpeg(mhImgB, output_file, IB_rectfloat);
1605         }
1606 #ifdef WITH_OPENEXR
1607         else if (format == DPOUTPUT_OPENEXR) {  /* OpenEXR 32-bit float */
1608                 mhImgB->ftype = OPENEXR | OPENEXR_COMPRESS;
1609                 IMB_rect_from_float(mhImgB);
1610                 imb_save_openexr(mhImgB, output_file, IB_rectfloat);
1611         }
1612 #endif
1613         else {  /* DPOUTPUT_PNG */
1614                 mhImgB->ftype= PNG|95;
1615                 IMB_rect_from_float(mhImgB);
1616                 imb_savepng(mhImgB, output_file, IB_rectfloat);
1617         }
1618
1619         IMB_freeImBuf(mhImgB);
1620 }
1621
1622
1623 /***************************** Material / Texture Sampling ******************************/
1624
1625 /*
1626 *       Update animated textures and calculate inverse matrices
1627 *       for material related objects in case texture is mapped to an object.
1628 *       (obj->imat isn't auto-updated)
1629 */
1630 static void dynamicPaint_updateMaterial(Material *mat, int frame)
1631 {
1632         MTex *mtex = NULL;
1633         Tex *tex = NULL;
1634         int tex_nr;
1635         if (mat == NULL) return;
1636
1637         /*
1638         *       Loop through every material texture and check
1639         *       if they are mapped by other object
1640         */
1641         for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
1642                 /* separate tex switching */
1643                 if(mat->septex & (1<<tex_nr)) continue;
1644         
1645                 if(mat->mtex[tex_nr]) {
1646                         mtex= mat->mtex[tex_nr];
1647                         tex= mtex->tex;
1648
1649                         if(tex==0) continue;
1650                         
1651                         /* which coords */
1652                         if(mtex->texco==TEXCO_OBJECT) { 
1653                                 Object *ob= mtex->object;
1654                                 if(ob) {                                                
1655                                         invert_m4_m4(ob->imat, ob->obmat);
1656                                 }
1657                         }
1658
1659                         /* update cache if voxel data */
1660                         if(tex->id.us && tex->type==TEX_VOXELDATA) {
1661                                 cache_voxeldata(tex, frame);
1662                         }
1663                         /* update image sequences and movies */
1664                         if(tex->ima && ELEM(tex->ima->source, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE)) {
1665                                 if(tex->iuser.flag & IMA_ANIM_ALWAYS)
1666                                         BKE_image_user_calc_frame(&tex->iuser, frame, 0);
1667                         }
1668                 }
1669         }
1670 }
1671
1672 /* Initialize materials for object:
1673 *   Calculates inverce matrices for linked objects, updates
1674 *   volume caches etc. */
1675 static void dynamicPaint_initObjectMaterials(Object *brushOb, Material *ui_mat, int frame)
1676 {
1677         /* Calculate inverse transformation matrix
1678         *  for this object */
1679         invert_m4_m4(brushOb->imat, brushOb->obmat);
1680
1681         /* Now process every material linked to this brush object */
1682         if ((ui_mat == NULL) && brushOb->mat && brushOb->totcol) {
1683                 int i, tot=(*give_totcolp(brushOb))+1;
1684                 for (i=1; i<tot; i++) {
1685                         dynamicPaint_updateMaterial(give_current_material(brushOb,i), frame);
1686                 }
1687         }
1688         else {
1689                 dynamicPaint_updateMaterial(ui_mat, frame);
1690         }
1691 }
1692
1693 /* A modified part of shadeinput.c -> shade_input_set_uv() / shade_input_set_shade_texco()
1694 *  Used for sampling UV mapped texture color */
1695 static void textured_face_generate_uv(float *uv, float *normal, float *hit, float *v1, float *v2, float *v3)
1696 {
1697
1698         float detsh, t00, t10, t01, t11, xn, yn, zn;
1699         int axis1, axis2;
1700
1701         /* find most stable axis to project */
1702         xn= fabs(normal[0]);
1703         yn= fabs(normal[1]);
1704         zn= fabs(normal[2]);
1705
1706         if(zn>=xn && zn>=yn) { axis1= 0; axis2= 1; }
1707         else if(yn>=xn && yn>=zn) { axis1= 0; axis2= 2; }
1708         else { axis1= 1; axis2= 2; }
1709
1710         /* compute u,v and derivatives */
1711         t00= v3[axis1]-v1[axis1]; t01= v3[axis2]-v1[axis2];
1712         t10= v3[axis1]-v2[axis1]; t11= v3[axis2]-v2[axis2];
1713
1714         detsh= 1.0f/(t00*t11-t10*t01);
1715         t00*= detsh; t01*=detsh; 
1716         t10*=detsh; t11*=detsh;
1717
1718         uv[0] = (hit[axis1]-v3[axis1])*t11-(hit[axis2]-v3[axis2])*t10;
1719         uv[1] = (hit[axis2]-v3[axis2])*t00-(hit[axis1]-v3[axis1])*t01;
1720
1721         /* u and v are in range -1 to 0, we allow a little bit extra but not too much, screws up speedvectors */
1722         CLAMP(uv[0], -2.0f, 1.0f);
1723         CLAMP(uv[1], -2.0f, 1.0f);
1724 }
1725
1726 /* a modified part of shadeinput.c -> shade_input_set_uv() / shade_input_set_shade_texco()
1727 *  Used for sampling UV mapped texture color */
1728 static void textured_face_get_uv(float *uv_co, float *normal, float *uv, int faceIndex, short quad, MTFace *tface)
1729 {
1730         float *uv1, *uv2, *uv3;
1731         float l;
1732
1733         l= 1.0f+uv[0]+uv[1];
1734                 
1735         uv1= tface[faceIndex].uv[0];
1736         uv2= (quad) ? tface[faceIndex].uv[2] : tface[faceIndex].uv[1];
1737         uv3= (quad) ? tface[faceIndex].uv[3] : tface[faceIndex].uv[2];
1738                                 
1739         uv_co[0]= -1.0f + 2.0f*(l*uv3[0]-uv[0]*uv1[0]-uv[1]*uv2[0]);
1740         uv_co[1]= -1.0f + 2.0f*(l*uv3[1]-uv[0]*uv1[1]-uv[1]*uv2[1]);
1741         uv_co[2]= 0.0f; /* texture.c assumes there are 3 coords */
1742 }
1743
1744 /*
1745 *       Edited version of do_material_tex()
1746 *
1747 *       Samples color and alpha from a "Surface" type material
1748 *       on a given point, without need for ShadeInput.
1749 *
1750 *       Keep up-to-date with new mapping settings
1751 *
1752 *       also see shade_input_set_shade_texco() for ORCO settings
1753 *       and shade_input_set_uv() for face uv calculation
1754 */
1755 void dynamicPaint_sampleSolidMaterial(float color[3], float *alpha, Material *mat, Object *brushOb, float xyz[3], int faceIndex, short isQuad, DerivedMesh *orcoDm)
1756 {
1757         MTex *mtex = NULL;
1758         Tex *tex = NULL;
1759         TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
1760         float co[3], xyz_local[3];
1761         float fact, stencilTin=1.0;
1762         float texvec[3];
1763         int tex_nr, rgbnor= 0;
1764         float uv[3], normal[3];
1765         MFace *mface;
1766         int v1, v2, v3;
1767         MVert *mvert;
1768         
1769         /* Get face data        */
1770         mvert = orcoDm->getVertArray(orcoDm);
1771         mface = orcoDm->getFaceArray(orcoDm);
1772         v1=mface[faceIndex].v1, v2=mface[faceIndex].v2, v3=mface[faceIndex].v3;
1773         if (isQuad) {v2=mface[faceIndex].v3; v3=mface[faceIndex].v4;}
1774         normal_tri_v3( normal, mvert[v1].co, mvert[v2].co, mvert[v3].co);
1775
1776         /* Assign material base values  */
1777         color[0] = mat->r;
1778         color[1] = mat->g;
1779         color[2] = mat->b;
1780         *alpha = mat->alpha;
1781
1782         VECCOPY(xyz_local, xyz);
1783         mul_m4_v3(brushOb->imat, xyz_local);
1784
1785         for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
1786                 
1787                 /* separate tex switching */
1788                 if(mat->septex & (1<<tex_nr)) continue;
1789                 
1790                 if(mat->mtex[tex_nr]) {
1791                         mtex= mat->mtex[tex_nr];
1792                         tex= mtex->tex;
1793                         
1794                         tex= mtex->tex;
1795                         if(tex==0) continue;
1796
1797                         /* which coords */
1798                         if(mtex->texco==TEXCO_ORCO) {
1799                                 float l;
1800                                 /* Get generated UV */
1801                                 textured_face_generate_uv(uv, normal, xyz_local, mvert[v1].co, mvert[v2].co, mvert[v3].co);
1802                                 l= 1.0f+uv[0]+uv[1];
1803
1804                                 /* calculate generated coordinate
1805                                 *  ** Keep up-to-date with shadeinput.c -> shade_input_set_shade_texco() **/
1806                                 co[0]= l*mvert[v3].co[0]-uv[0]*mvert[v1].co[0]-uv[1]*mvert[v2].co[0];
1807                                 co[1]= l*mvert[v3].co[1]-uv[0]*mvert[v1].co[1]-uv[1]*mvert[v2].co[1];
1808                                 co[2]= l*mvert[v3].co[2]-uv[0]*mvert[v1].co[2]-uv[1]*mvert[v2].co[2];
1809                         }
1810                         else if(mtex->texco==TEXCO_OBJECT) {
1811                                 Object *ob= mtex->object;
1812
1813                                 VECCOPY(co, xyz);
1814                                 /* convert from world space to paint space */
1815                                 mul_m4_v3(brushOb->imat, co);
1816                                 if(ob) {
1817                                         mul_m4_v3(ob->imat, co);
1818                                 }
1819                         }
1820                         else if(mtex->texco==TEXCO_GLOB) {
1821                                 VECCOPY(co, xyz);
1822                         }
1823                         else if(mtex->texco==TEXCO_UV) {
1824                                 MTFace *tface;
1825
1826                                 /* Get UV layer */
1827                                 if(mtex->uvname[0] != 0)
1828                                         tface = CustomData_get_layer_named(&orcoDm->faceData, CD_MTFACE, mtex->uvname);
1829                                 else
1830                                         tface = DM_get_face_data_layer(orcoDm, CD_MTFACE);
1831                                 /* Get generated coordinates to calculate UV from */
1832                                 textured_face_generate_uv(uv, normal, xyz_local, mvert[v1].co, mvert[v2].co, mvert[v3].co);
1833                                 /* Get UV mapping coordinate */
1834                                 textured_face_get_uv(co, normal, uv, faceIndex, isQuad, tface);
1835                         }
1836                         else continue;  /* non-supported types get just skipped:
1837                                                         TEXCO_REFL, TEXCO_NORM, TEXCO_TANGENT
1838                                                         TEXCO_WINDOW, TEXCO_STRAND, TEXCO_STRESS etc.
1839                                                         */
1840
1841                         /* get texture mapping */
1842                         texco_mapping_ext(normal, tex, mtex, co, 0, 0, texvec);
1843
1844                         if(tex->use_nodes && tex->nodetree) {
1845                                 /* No support for nodes (yet). */
1846                                 continue;
1847                         }
1848                         else {
1849                                 rgbnor = multitex_ext(mtex->tex, co, 0, 0, 0, &texres);
1850                         }
1851
1852                         /* texture output */
1853                         if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
1854                                 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
1855                                 rgbnor-= TEX_RGB;
1856                         }
1857
1858                         /* Negate and stencil masks */
1859                         if(mtex->texflag & MTEX_NEGATIVE) {
1860                                 if(rgbnor & TEX_RGB) {
1861                                         texres.tr= 1.0-texres.tr;
1862                                         texres.tg= 1.0-texres.tg;
1863                                         texres.tb= 1.0-texres.tb;
1864                                 }
1865                                 texres.tin= 1.0-texres.tin;
1866                         }
1867                         if(mtex->texflag & MTEX_STENCIL) {
1868                                 if(rgbnor & TEX_RGB) {
1869                                         fact= texres.ta;
1870                                         texres.ta*= stencilTin;
1871                                         stencilTin*= fact;
1872                                 }
1873                                 else {
1874                                         fact= texres.tin;
1875                                         texres.tin*= stencilTin;
1876                                         stencilTin*= fact;
1877                                 }
1878                         }
1879
1880                         /* mapping */
1881                         if(mtex->mapto & (MAP_COL)) {
1882                                 float tcol[3];
1883                                 /* stencil maps on the texture control slider, not texture intensity value */
1884                                 tcol[0]=texres.tr; tcol[1]=texres.tg; tcol[2]=texres.tb;
1885                                 if((rgbnor & TEX_RGB)==0) {
1886                                         tcol[0]= mtex->r;
1887                                         tcol[1]= mtex->g;
1888                                         tcol[2]= mtex->b;
1889                                 }
1890                                 else if(mtex->mapto & MAP_ALPHA) {
1891                                         texres.tin= stencilTin;
1892                                 }
1893                                 else texres.tin= texres.ta;
1894                                 if(mtex->mapto & MAP_COL) {
1895                                         float colfac= mtex->colfac*stencilTin;
1896                                         texture_rgb_blend(color, tcol, color, texres.tin, colfac, mtex->blendtype);
1897                                 }
1898                         }
1899
1900                         if(mtex->mapto & MAP_VARS) {
1901                                 /* stencil maps on the texture control slider, not texture intensity value */
1902                                 if(rgbnor & TEX_RGB) {
1903                                         if(texres.talpha) texres.tin= texres.ta;
1904                                         else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
1905                                 }
1906
1907                                 if(mtex->mapto & MAP_ALPHA) {
1908                                         float alphafac= mtex->alphafac*stencilTin;
1909                                         *alpha= texture_value_blend(mtex->def_var, *alpha, texres.tin, alphafac, mtex->blendtype);
1910                                         if(*alpha<0.0) *alpha= 0.0;
1911                                         else if(*alpha>1.0) *alpha= 1.0;
1912                                 }
1913                         }
1914                 }
1915         }
1916 }
1917
1918
1919 /*
1920 *       Edited version of texture.c -> do_volume_tex()
1921 *
1922 *       Samples color and density from a volume type texture
1923 *       without need for ShadeInput.
1924 *
1925 *       Keep up-to-date with new mapping settings
1926 */
1927 void dynamicPaint_sampleVolumeMaterial(float color[3], float *alpha, Material *mat, Object *brushOb, float xyz[3])
1928 {
1929         int mapto_flag  = MAP_DENSITY | MAP_REFLECTION_COL | MAP_TRANSMISSION_COL;
1930         float *col = color;
1931
1932         MTex *mtex = NULL;
1933         Tex *tex = NULL;
1934         TexResult texres= {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0, NULL};
1935         int tex_nr, rgbnor= 0;
1936         float co[3], texvec[3];
1937         float fact, stencilTin=1.0;
1938
1939         /* set base color */
1940         color[0] = mat->vol.reflection_col[0];
1941         color[1] = mat->vol.reflection_col[1];
1942         color[2] = mat->vol.reflection_col[2];
1943         *alpha = mat->vol.density;
1944         
1945         for(tex_nr=0; tex_nr<MAX_MTEX; tex_nr++) {
1946
1947                 /* separate tex switching */
1948                 if(mat->septex & (1<<tex_nr)) continue;
1949                 
1950                 if(mat->mtex[tex_nr]) {
1951                         mtex= mat->mtex[tex_nr];
1952                         tex= mtex->tex;
1953                         if(tex==0) continue;
1954
1955                         /* only process if this texture is mapped 
1956                                 * to one that we're interested in */
1957                         if (!(mtex->mapto & mapto_flag)) continue;
1958                         texres.nor= NULL;
1959                         
1960                         /* which coords */
1961                         if(mtex->texco==TEXCO_OBJECT) { 
1962                                 Object *ob= mtex->object;
1963                                 ob= mtex->object;
1964                                 if(ob) {                                                
1965                                         VECCOPY(co, xyz);
1966                                         mul_m4_v3(ob->imat, co);
1967                                 }
1968                         }
1969                         else if(mtex->texco==TEXCO_ORCO) {
1970                                 {
1971                                         Object *ob= brushOb;
1972                                         VECCOPY(co, xyz);
1973                                         mul_m4_v3(ob->imat, co);
1974                                 }
1975                         }
1976                         else if(mtex->texco==TEXCO_GLOB) {                                                      
1977                                 VECCOPY(co, xyz);
1978                         }
1979                         else continue;  /* Skip unsupported types */
1980
1981                         if(tex->type==TEX_IMAGE) {
1982                                 continue;       /* not supported yet */                         
1983                         }
1984                         else {
1985                                 /* placement */
1986                                 if(mtex->projx) texvec[0]= mtex->size[0]*(co[mtex->projx-1]+mtex->ofs[0]);
1987                                 else texvec[0]= mtex->size[0]*(mtex->ofs[0]);
1988
1989                                 if(mtex->projy) texvec[1]= mtex->size[1]*(co[mtex->projy-1]+mtex->ofs[1]);
1990                                 else texvec[1]= mtex->size[1]*(mtex->ofs[1]);
1991
1992                                 if(mtex->projz) texvec[2]= mtex->size[2]*(co[mtex->projz-1]+mtex->ofs[2]);
1993                                 else texvec[2]= mtex->size[2]*(mtex->ofs[2]);
1994                         }
1995                         rgbnor= multitex_ext(tex, texvec, NULL, NULL, 0, &texres);
1996                         
1997                         /* texture output */
1998                         if( (rgbnor & TEX_RGB) && (mtex->texflag & MTEX_RGBTOINT)) {
1999                                 texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
2000                                 rgbnor-= TEX_RGB;
2001                         }
2002                         /* Negate and stencil */
2003                         if(mtex->texflag & MTEX_NEGATIVE) {
2004                                 if(rgbnor & TEX_RGB) {
2005                                         texres.tr= 1.0-texres.tr;
2006                                         texres.tg= 1.0-texres.tg;
2007                                         texres.tb= 1.0-texres.tb;
2008                                 }
2009                                 texres.tin= 1.0-texres.tin;
2010                         }
2011                         if(mtex->texflag & MTEX_STENCIL) {
2012                                 if(rgbnor & TEX_RGB) {
2013                                         fact= texres.ta;
2014                                         texres.ta*= stencilTin;
2015                                         stencilTin*= fact;
2016                                 }
2017                                 else {
2018                                         fact= texres.tin;
2019                                         texres.tin*= stencilTin;
2020                                         stencilTin*= fact;
2021                                 }
2022                         }
2023                         
2024                         /* Map values */
2025                         if((mapto_flag & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL)) && (mtex->mapto & (MAP_EMISSION_COL+MAP_TRANSMISSION_COL+MAP_REFLECTION_COL))) {
2026                                 float tcol[3];
2027                                 /* stencil maps on the texture control slider, not texture intensity value */
2028                                 if((rgbnor & TEX_RGB)==0) {
2029                                         tcol[0]= mtex->r;
2030                                         tcol[1]= mtex->g;
2031                                         tcol[2]= mtex->b;
2032                                 } else {
2033                                         tcol[0]=texres.tr;
2034                                         tcol[1]=texres.tg;
2035                                         tcol[2]=texres.tb;
2036                                         if(texres.talpha)
2037                                                 texres.tin= texres.ta;
2038                                 }
2039                                 
2040                                 /* used for emit */
2041                                 if((mapto_flag & MAP_EMISSION_COL) && (mtex->mapto & MAP_EMISSION_COL)) {
2042                                         float colemitfac= mtex->colemitfac*stencilTin;
2043                                         texture_rgb_blend(col, tcol, col, texres.tin, colemitfac, mtex->blendtype);
2044                                 }
2045                                 if((mapto_flag & MAP_REFLECTION_COL) && (mtex->mapto & MAP_REFLECTION_COL)) {
2046                                         float colreflfac= mtex->colreflfac*stencilTin;
2047                                         texture_rgb_blend(col, tcol, col, texres.tin, colreflfac, mtex->blendtype);
2048                                 }
2049                                 if((mapto_flag & MAP_TRANSMISSION_COL) && (mtex->mapto & MAP_TRANSMISSION_COL)) {
2050                                         float coltransfac= mtex->coltransfac*stencilTin;
2051                                         texture_rgb_blend(col, tcol, col, texres.tin, coltransfac, mtex->blendtype);
2052                                 }
2053                         }
2054                         
2055                         if((mapto_flag & MAP_VARS) && (mtex->mapto & MAP_VARS)) {
2056                                 /* stencil maps on the texture control slider, not texture intensity value */
2057                                 
2058                                 /* convert RGB to intensity if intensity info isn't provided */
2059                                 if (!(rgbnor & TEX_INT)) {
2060                                         if (rgbnor & TEX_RGB) {
2061                                                 if(texres.talpha) texres.tin= texres.ta;
2062                                                 else texres.tin= (0.35*texres.tr+0.45*texres.tg+0.2*texres.tb);
2063                                         }
2064                                 }
2065                                 if((mapto_flag & MAP_DENSITY) && (mtex->mapto & MAP_DENSITY)) {
2066                                         float densfac= mtex->densfac*stencilTin;
2067
2068                                         *alpha = texture_value_blend(mtex->def_var, *alpha, texres.tin, densfac, mtex->blendtype);
2069                                         CLAMP(*alpha, 0.0, 1.0);
2070                                 }
2071                         }
2072                 }
2073         }
2074 }
2075
2076 /*
2077 *       Get material diffuse color and alpha (including linked textures) in given coordinates
2078 *       
2079 *       color,paint : input/output color values
2080 *       pixelCoord : canvas pixel coordinates in global space. used if material is volumetric
2081 *       paintHit : ray hit point on paint object surface in global space. used by "surface" type materials
2082 *       faceIndex : ray hit face index
2083 *       orcoDm : orco state derived mesh of paint object
2084 *       ui_mat : force material. if NULL, material linked to mesh face is used.
2085 *
2086 *       *"brush object" = object to sample material color from
2087 */
2088 void dynamicPaint_getMaterialColor(float *color, float *alpha, Object *brushOb, float pixelCoord[3], float paintHit[3], int faceIndex, short isQuad, DerivedMesh *orcoDm, Material *ui_mat)
2089 {
2090         Material *material = ui_mat;
2091
2092         /* Get face material */
2093         if (material == NULL) {
2094                 MFace *mface = NULL;
2095                 mface = orcoDm->getFaceArray(orcoDm);
2096                 material = give_current_material(brushOb, mface[faceIndex].mat_nr+1);
2097
2098                 if (material == NULL) return;   /* No material assigned */
2099         }
2100
2101         /* Sample textured material color in given position depending on material type */
2102         if (material->material_type == MA_TYPE_SURFACE) {
2103                 /* Solid material */
2104                 dynamicPaint_sampleSolidMaterial(color, alpha, material, brushOb, paintHit, faceIndex, isQuad, orcoDm);
2105         }
2106         else if (material->material_type == MA_TYPE_VOLUME) {
2107                 /* Volumetric material */
2108                 dynamicPaint_sampleVolumeMaterial(color, alpha, material, brushOb, pixelCoord);
2109         }
2110         else if (material->material_type == MA_TYPE_HALO) {
2111                 /* Halo type not supported */
2112         }
2113 }
2114
2115
2116 /***************************** Ray / Nearest Point Utils ******************************/
2117
2118
2119 /*  A modified callback to bvh tree raycast. The tree must bust have been built using bvhtree_from_mesh_faces.
2120 *   userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
2121 *  
2122 *       To optimize brush detection speed this doesn't calculate hit coordinates or normal.
2123 *       If ray hit the second half of a quad, no[0] is set to 1.0f.
2124 */
2125 static void mesh_faces_spherecast_dp(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
2126 {
2127         const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
2128         MVert *vert     = data->vert;
2129         MFace *face = data->face + index;
2130         short quad = 0;
2131
2132         float *t0, *t1, *t2, *t3;
2133         t0 = vert[ face->v1 ].co;
2134         t1 = vert[ face->v2 ].co;
2135         t2 = vert[ face->v3 ].co;
2136         t3 = face->v4 ? vert[ face->v4].co : NULL;
2137
2138         do
2139         {       
2140                 float dist;
2141                 dist = ray_tri_intersection(ray, hit->dist, t0, t1, t2);
2142
2143                 if(dist >= 0 && dist < hit->dist)
2144                 {
2145                         hit->index = index;
2146                         hit->dist = dist;
2147                         hit->no[0] = (quad) ? 1.0f : 0.0f;
2148                 }
2149
2150                 t1 = t2;
2151                 t2 = t3;
2152                 t3 = NULL;
2153                 quad = 1;
2154
2155         } while(t2);
2156 }
2157
2158 /* A modified callback to bvh tree nearest point. The tree must bust have been built using bvhtree_from_mesh_faces.
2159 *  userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree.
2160 *  
2161 *       To optimize brush detection speed this doesn't calculate hit normal.
2162 *       If ray hit the second half of a quad, no[0] is set to 1.0f, else 0.0f
2163 */
2164 static void mesh_faces_nearest_point_dp(void *userdata, int index, const float *co, BVHTreeNearest *nearest)
2165 {
2166         const BVHTreeFromMesh *data = (BVHTreeFromMesh*) userdata;
2167         MVert *vert     = data->vert;
2168         MFace *face = data->face + index;
2169         short quad = 0;
2170
2171         float *t0, *t1, *t2, *t3;
2172         t0 = vert[ face->v1 ].co;
2173         t1 = vert[ face->v2 ].co;
2174         t2 = vert[ face->v3 ].co;
2175         t3 = face->v4 ? vert[ face->v4].co : NULL;
2176
2177         do
2178         {       
2179                 float nearest_tmp[3], dist;
2180                 int vertex, edge;
2181                 
2182                 dist = nearest_point_in_tri_surface(t0, t1, t2, co, &vertex, &edge, nearest_tmp);
2183                 if(dist < nearest->dist)
2184                 {
2185                         nearest->index = index;
2186                         nearest->dist = dist;
2187                         VECCOPY(nearest->co, nearest_tmp);
2188                         nearest->no[0] = (quad) ? 1.0f : 0.0f;
2189                 }
2190
2191                 t1 = t2;
2192                 t2 = t3;
2193                 t3 = NULL;
2194                 quad = 1;
2195
2196         } while(t2);
2197 }
2198
2199
2200 /***************************** Painting Calls ******************************/
2201
2202 /*
2203 *       Mix color values to canvas point.
2204 *
2205 *       surface : canvas surface
2206 *       index : surface point index
2207 *       paintFlags : paint object flags
2208 *   paintColor,Alpha,Wetness : to be mixed paint values
2209 *       timescale : value used to adjust time dependand
2210 *                           operations when using substeps
2211 */
2212 void dynamicPaint_mixPaintColors(DynamicPaintSurface *surface, int index, int paintFlags, float *paintColor, float *paintAlpha, float *paintWetness, float *timescale)
2213 {
2214         PaintPoint *pPoint = &((PaintPoint*)surface->data->type_data)[index];
2215
2216         /* Add paint    */
2217         if (!(paintFlags & MOD_DPAINT_ERASE)) {
2218                 float wetness;
2219
2220                 /* If point has previous paint  */
2221                 if (pPoint->e_alpha > 0)
2222                 {
2223                         /*
2224                         *       Mix colors by the factor, use timescale
2225                         */
2226                         float factor = (*paintAlpha) * (*timescale);
2227                         float invFact = 1.0f - factor;
2228                         pPoint->e_color[0] = pPoint->e_color[0]*invFact + paintColor[0]*factor;
2229                         pPoint->e_color[1] = pPoint->e_color[1]*invFact + paintColor[1]*factor;
2230                         pPoint->e_color[2] = pPoint->e_color[2]*invFact + paintColor[2]*factor;
2231                 }
2232                 else
2233                 {
2234                         /* else set first color value straight to paint color   */
2235                         pPoint->e_color[0] = paintColor[0];
2236                         pPoint->e_color[1] = paintColor[1];
2237                         pPoint->e_color[2] = paintColor[2];
2238                 }
2239
2240                 /* alpha */
2241                 if (paintFlags & MOD_DPAINT_ABS_ALPHA) {
2242                         if (pPoint->e_alpha < (*paintAlpha)) pPoint->e_alpha = (*paintAlpha);
2243                 }
2244                 else {
2245                         pPoint->e_alpha += (*paintAlpha) * (*timescale);
2246                         if (pPoint->e_alpha > 1.0f) pPoint->e_alpha = 1.0f;
2247                 }
2248
2249                 /* only increase wetness if it's below paint level      */
2250                 wetness = (*paintWetness) * pPoint->e_alpha;
2251                 if (pPoint->wetness < wetness) pPoint->wetness = wetness;
2252         }
2253         /* Erase paint  */
2254         else {
2255                 float a_ratio, a_highest;
2256                 float wetness;
2257                 float invFact = 1.0f - (*paintAlpha);
2258
2259                 /*
2260                 *       Make highest alpha to match erased value
2261                 *       but maintain alpha ratio
2262                 */
2263                 if (paintFlags & MOD_DPAINT_ABS_ALPHA) {
2264                         a_highest = (pPoint->e_alpha > pPoint->alpha) ? pPoint->e_alpha : pPoint->alpha;
2265                         if (a_highest > invFact) {
2266                                 a_ratio = invFact / a_highest;
2267
2268                                 pPoint->e_alpha *= a_ratio;
2269                                 pPoint->alpha *= a_ratio;
2270                         }
2271                 }
2272                 else {
2273                         pPoint->e_alpha -= (*paintAlpha) * (*timescale);
2274                         if (pPoint->e_alpha < 0.0f) pPoint->e_alpha = 0.0f;
2275                         pPoint->alpha -= (*paintAlpha) * (*timescale);
2276                         if (pPoint->alpha < 0.0f) pPoint->alpha = 0.0f;
2277                 }
2278
2279                 wetness = (1.0f - (*paintWetness)) * pPoint->e_alpha;
2280                 if (pPoint->wetness > wetness) pPoint->wetness = wetness;
2281         }
2282 }
2283
2284 /*
2285 *       Paint a brush object mesh to the surface
2286 */
2287 static int dynamicPaint_paintMesh(DynamicPaintSurface *surface, PaintBakePoint *bPoint, DynamicPaintBrushSettings *brush, Object *canvasOb, Object *brushOb, float timescale)
2288 {
2289         DerivedMesh *dm = NULL;
2290         MVert *mvert = NULL;
2291         MFace *mface = NULL;
2292         PaintSurfaceData *sData = surface->data;
2293
2294         if (!brush->dm) return 0;
2295
2296         /* If using material color, we prepare required stuff on texture related objects first  */
2297         if (brush->flags & MOD_DPAINT_USE_MATERIAL) dynamicPaint_initObjectMaterials(brushOb, brush->mat, surface->current_frame);
2298
2299         {
2300                 BVHTreeFromMesh treeData = {0};
2301                 int index;
2302
2303                 int numOfVerts;
2304                 int ii;
2305
2306                 /*
2307                 *       Transform collider vertices to world space
2308                 *       (Faster than transforming per pixel
2309                 *   coordinates and normals to object space)
2310                 */
2311                 dm = CDDM_copy(brush->dm);
2312                 mvert = dm->getVertArray(dm);
2313                 mface = dm->getFaceArray(dm);
2314                 numOfVerts = dm->getNumVerts(dm);
2315
2316                 for (ii=0; ii<numOfVerts; ii++) {
2317                         mul_m4_v3(brushOb->obmat, mvert[ii].co);
2318                 }
2319
2320                 /* Build a bvh tree from transformed vertices   */
2321                 bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6);
2322
2323                 if(treeData.tree) {
2324                         #pragma omp parallel for schedule(static)
2325                         for (index = 0; index < sData->total_points; index++)
2326                         {
2327                                 {
2328                                         //DynamicPaintSurfacePoint *cPoint = (&surface->point[xx+tWidth*yy]);
2329
2330                                         int ss;
2331                                         float ssFactor = 0.0f;  /* super-sampling factor */
2332                                         float depth = 0.0f;             /* displace depth */
2333
2334                                         float paintColor[3] = {0.0f, 0.0f, 0.0f};
2335                                         int numOfHits = 0;
2336                                         float paintAlpha = 0.0f;
2337
2338                                         /* Supersampling        */
2339                                         for (ss=0; ss<1; ss++)
2340                                         {
2341
2342                                                 float ray_start[3], ray_dir[3];
2343                                                 float gaus_factor;
2344                                                 BVHTreeRayHit hit;
2345                                                 BVHTreeNearest nearest;
2346                                                 short hit_found = 0;
2347
2348                                                 /* If it's a proximity hit, store distance rate */
2349                                                 float distRate = -1.0f;
2350
2351                                                 /* hit data     */
2352                                                 float hitCoord[3];              /* mid-sample hit coordinate */
2353                                                 int hitFace = -1;               /* mid-sample hit face */
2354                                                 short hitQuad;                  /* mid-sample hit quad status */
2355
2356                                                 /* Supersampling factor */
2357                                                 /*if (surface->pixelSamples > 1) {
2358                                                         gaus_factor = gaussianFactors[ss];
2359                                                 }
2360                                                 else */{
2361                                                         gaus_factor = 1.0f;
2362                                                 }
2363
2364                                                 /* Get current sample position in world coordinates     */
2365                                                 /*interp_v3_v3v3v3(realPos,
2366                                                                                 canvasVerts[cPoint->v1].v,
2367                                                                                 canvasVerts[cPoint->v2].v,
2368                                                                                 canvasVerts[cPoint->v3].v, cPoint->barycentricWeights[ss].v);*/
2369                                                 VECCOPY(ray_start, bPoint[index].realCoord);
2370                                                 VECCOPY(ray_dir, bPoint[index].invNorm);
2371
2372                                                 hit.index = -1;
2373                                                 hit.dist = 9999;
2374                                                 nearest.index = -1;
2375                                                 nearest.dist = brush->paint_distance * brush->paint_distance; /* find_nearest search uses squared distance */
2376
2377                                                 /* Check volume collision       */
2378                                                 if (brush->collision == MOD_DPAINT_COL_VOLUME || brush->collision == MOD_DPAINT_COL_VOLDIST)
2379                                                 if(BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData) != -1)
2380                                                 {
2381                                                         /* We hit a triangle, now check if collision point normal is facing the point   */
2382
2383
2384                                                         /*      For optimization sake, hit point normal isn't calculated in ray cast loop       */
2385                                                         int v1=mface[hit.index].v1, v2=mface[hit.index].v2, v3=mface[hit.index].v3, quad=(hit.no[0] == 1.0f);
2386                                                         float dot;
2387
2388                                                         if (quad) {v2=mface[hit.index].v3; v3=mface[hit.index].v4;}
2389                                                 
2390                                                         /* Get hit normal       */
2391                                                         normal_tri_v3( hit.no, mvert[v1].co, mvert[v2].co, mvert[v3].co);
2392                                                         dot = ray_dir[0]*hit.no[0] + ray_dir[1]*hit.no[1] + ray_dir[2]*hit.no[2];
2393
2394                                                         /*
2395                                                         *       If ray and hit normal are facing same direction
2396                                                         *       hit point is inside a closed mesh.
2397                                                         */
2398                                                         if (dot>=0)
2399                                                         {
2400                                                                 /* Add factor on supersample filter     */
2401                                                                 ssFactor += gaus_factor;
2402                                                                 depth += hit.dist;
2403                                                                 hit_found = 1;
2404
2405                                                                 /*
2406                                                                 *       Mark hit info
2407                                                                 */
2408                                                                 if (hitFace == -1) {
2409                                                                         VECADDFAC(hitCoord, ray_start, ray_dir, hit.dist);      /* Calculate final hit coordinates */
2410                                                                         hitQuad = quad;
2411                                                                         hitFace = hit.index;
2412                                                                 }
2413                                                         }
2414                                                 }       // end of raycast
2415                                         
2416                                                 /* Check proximity collision    */
2417                                                 if ((brush->collision == MOD_DPAINT_COL_DIST || brush->collision == MOD_DPAINT_COL_VOLDIST) && (!hit_found))
2418                                                 {
2419                                                         float proxDist = -1.0f;
2420                                                         float hitCo[3];
2421                                                         short hQuad;
2422                                                         int face;
2423
2424                                                         /*
2425                                                         *       If pure distance proximity, find the nearest point on the mesh
2426                                                         */
2427                                                         if (!(brush->flags & MOD_DPAINT_PROX_FACEALIGNED)) {
2428                                                                 if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, mesh_faces_nearest_point_dp, &treeData) != -1) {
2429                                                                         proxDist = sqrt(nearest.dist);  /* find_nearest returns a squared distance, so gotta change it back to real distance */
2430                                                                         copy_v3_v3(hitCo, nearest.co);
2431                                                                         hQuad = (nearest.no[0] == 1.0f);
2432                                                                         face = nearest.index;
2433                                                                 }
2434                                                         }
2435                                                         else { /*  else cast a ray in surface normal direction  */
2436                                                                 negate_v3(ray_dir);
2437                                                                 hit.index = -1;
2438                                                                 hit.dist = brush->paint_distance;
2439
2440                                                                 /* Do a face normal directional raycast, and use that distance  */
2441                                                                 if(BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, mesh_faces_spherecast_dp, &treeData) != -1)
2442                                                                 {
2443                                                                         proxDist = hit.dist;
2444                                                                         VECADDFAC(hitCo, ray_start, ray_dir, hit.dist); /* Calculate final hit coordinates */
2445                                                                         hQuad = (hit.no[0] == 1.0f);
2446                                                                         face = hit.index;
2447                                                                 }
2448                                                         }
2449
2450                                                         /* If a hit was found, calculate required values        */
2451                                                         if (proxDist >= 0.0f) {
2452                                                                 float dist_rate = proxDist / brush->paint_distance;
2453
2454                                                                         /* Smooth range or color ramp   */
2455                                                                         if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH ||
2456                                                                                 brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP) {
2457
2458                                                                                 /* Limit distance to 0.0 - 1.0 */
2459                                                                                 if (dist_rate > 1.0f) dist_rate = 1.0f;
2460                                                                                 if (dist_rate < 0.0f) dist_rate = 0.0f;
2461
2462                                                                                 /* if using smooth falloff, multiply gaussian factor */
2463                                                                                 if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH) {
2464                                                                                         ssFactor += (1.0f - dist_rate) * gaus_factor;
2465                                                                                 }
2466                                                                                 else ssFactor += gaus_factor;
2467
2468                                                                                 if (hitFace == -1) {
2469                                                                                         distRate = dist_rate;
2470                                                                                 }
2471                                                                         }
2472                                                                         else ssFactor += gaus_factor;
2473
2474                                                                         hit_found = 1;
2475
2476                                                                         if (hitFace == -1) {
2477                                                                                 copy_v3_v3(hitCoord, hitCo);
2478                                                                                 hitQuad = hQuad;
2479                                                                                 hitFace = face;
2480                                                                         }
2481                                                         }       // proxDist
2482                                                 }       // end proximity check
2483
2484                                                 /*
2485                                                 *       Process color and alpha
2486                                                 */
2487                                                 if (hit_found)
2488                                                 {
2489                                                         float sampleColor[3];
2490                                                         float sampleAlpha = 1.0f;
2491                                                         float bandres[4];
2492
2493                                                         sampleColor[0] = brush->r;
2494                                                         sampleColor[1] = brush->g;
2495                                                         sampleColor[2] = brush->b;
2496                                                 
2497                                                         /* Get material+textures color on hit point if required */
2498                                                         if (brush->flags & MOD_DPAINT_USE_MATERIAL) dynamicPaint_getMaterialColor(sampleColor, &sampleAlpha, brushOb, bPoint[index].realCoord, hitCoord, hitFace, hitQuad, brush->dm, brush->mat);
2499
2500                                                         /* Sample colorband if required */
2501                                                         if ((distRate >= 0.0f) && (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP) && do_colorband(brush->paint_ramp, distRate, bandres)) {
2502                                                                 if (!(brush->flags & MOD_DPAINT_RAMP_ALPHA)) {
2503                                                                         sampleColor[0] = bandres[0];
2504                                                                         sampleColor[1] = bandres[1];
2505                                                                         sampleColor[2] = bandres[2];
2506                                                                 }
2507                                                                 sampleAlpha *= bandres[3];
2508                                                         }
2509
2510                                                         /* Add AA sample */
2511                                                         paintColor[0] += sampleColor[0];
2512                                                         paintColor[1] += sampleColor[1];
2513                                                         paintColor[2] += sampleColor[2];
2514
2515                                                         paintAlpha += sampleAlpha;
2516                                                         numOfHits++;
2517                                                 }
2518                                         } // end supersampling
2519
2520
2521                                         /* if any sample was inside paint range */
2522                                         if (ssFactor > 0.01f) {
2523
2524                                                 /* apply supersampling results  */
2525                                                 /*if (surface->pixelSamples > 1) {
2526                                                         ssFactor /= gaussianTotal;
2527                                                 }*/
2528
2529                                                 //cPoint->state = 2;
2530
2531                                                 if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
2532
2533                                                         float paintWetness = brush->wetness * ssFactor;
2534
2535                                                         /* Get final pixel color and alpha      */
2536                                                         paintColor[0] /= numOfHits;
2537                                                         paintColor[1] /= numOfHits;
2538                                                         paintColor[2] /= numOfHits;
2539                                                         paintAlpha /= numOfHits;
2540
2541                                                         /* Multiply alpha value by the ui multiplier    */
2542                                                         paintAlpha = paintAlpha * ssFactor * brush->alpha;
2543                                                         if (paintAlpha > 1.0f) paintAlpha = 1.0f;
2544
2545                                                         /*
2546                                                         *       Mix paint to the surface
2547                                                         */
2548                                                         dynamicPaint_mixPaintColors(surface, index, brush->flags, paintColor, &paintAlpha, &paintWetness, &timescale);
2549                                                 }
2550                                                 else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE) {
2551                                                         float *value = (float*)sData->type_data;
2552
2553                                                         if (brush->flags & MOD_DPAINT_ERASE) {
2554                                                                 value[index] *= (1.0f - ssFactor);
2555                                                                 if (value[index] < 0.0f) value[index] = 0.0f;
2556                                                         }
2557                                                         else {
2558                                                                 depth /= bPoint[index].normal_scale;
2559                                                                 /* do displace  */
2560                                                                 if (value[index] < depth) value[index] = depth;
2561                                                         }
2562                                                 }
2563                                         }
2564                                 }
2565                         }
2566                 }
2567                 /* free bhv tree */
2568                 free_bvhtree_from_mesh(&treeData);
2569                 dm->release(dm);
2570
2571         }
2572
2573         return 1;
2574 }
2575
2576 /*
2577 *       Paint a particle system to the surface
2578 */
2579 static int dynamicPaint_paintParticles(DynamicPaintSurface *surface, PaintBakePoint *bPoint, ParticleSystem *psys, DynamicPaintBrushSettings *brush, Object *canvasOb, float timescale)
2580 {
2581         int index;
2582         ParticleSettings *part=psys->part;
2583         ParticleData *pa = NULL;
2584         PaintSurfaceData *sData = surface->data;
2585
2586         KDTree *tree;
2587         int particlesAdded = 0;
2588         int invalidParticles = 0;
2589         int p = 0;
2590
2591         if (psys->totpart < 1) return 1;
2592
2593         /*
2594         *       Build a kd-tree to optimize distance search
2595         */
2596         tree= BLI_kdtree_new(psys->totpart);
2597
2598         /* loop through particles and insert valid ones to the tree     */
2599         for(p=0, pa=psys->particles; p<psys->totpart; p++, pa++)        {
2600
2601                 /* Proceed only if particle is active   */
2602                 if(pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN)==0) continue;                                                                 
2603                 else if(pa->alive == PARS_DEAD && (part->flag & PART_DIED)==0) continue;                                                                        
2604                 else if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue;
2605
2606                 /*      for debug purposes check if any NAN particle proceeds
2607                 *       For some reason they get past activity check, this should rule most of them out */
2608                 if (isnan(pa->state.co[0]) || isnan(pa->state.co[1]) || isnan(pa->state.co[2])) {invalidParticles++;continue;}
2609
2610                 BLI_kdtree_insert(tree, p, pa->state.co, NULL);
2611                 particlesAdded++;
2612         }
2613         if (invalidParticles)
2614                 printf("Warning: Invalid particle(s) found!\n");
2615
2616         /* If no suitable particles were found, exit    */
2617         if (particlesAdded < 1) {
2618                 BLI_kdtree_free(tree);
2619                 return 1;
2620         }
2621         /* balance tree */
2622         BLI_kdtree_balance(tree);
2623
2624         /*
2625         *       Loop through every surface point
2626         */
2627         #pragma omp parallel for schedule(static)
2628         for (index = 0; index < sData->total_points; index++)
2629         {
2630                 float disp_intersect = 0;
2631                 float radius;
2632                 float solidradius = brush->particle_radius;
2633                 float smooth = brush->particle_smooth;
2634                 float strength = 0.0f;
2635
2636                 /* If using per particle radius */
2637                 if (brush->flags & MOD_DPAINT_PART_RAD) {
2638                         /*
2639                         *       If we use per particle radius, we have to sample all particles
2640                         *       within max radius range
2641                         */
2642                         KDTreeNearest *nearest = NULL;
2643                         int n, particles = 0;
2644                         float range = psys->part->size + smooth;
2645
2646                         particles = BLI_kdtree_range_search(tree, range, bPoint[index].realCoord, NULL, &nearest);
2647                         for(n=0; n<particles; n++) {
2648
2649                                 /*