f84fcf9dd8b517e7024c599a33e8e359ffb1968e
[blender.git] / source / blender / render / intern / source / multires_bake.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2012 by Blender Foundation
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Morten Mikkelsen,
24  *                 Sergey Sharybin
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file blender/render/intern/source/multires_bake.c
30  *  \ingroup render
31  */
32
33 #include <string.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_object_types.h"
38 #include "DNA_mesh_types.h"
39
40 #include "BLI_math.h"
41 #include "BLI_listbase.h"
42
43 #include "BKE_ccg.h"
44 #include "BKE_context.h"
45 #include "BKE_global.h"
46 #include "BKE_image.h"
47 #include "BKE_multires.h"
48 #include "BKE_modifier.h"
49 #include "BKE_subsurf.h"
50
51 #include "RE_multires_bake.h"
52 #include "RE_pipeline.h"
53 #include "RE_shader_ext.h"
54
55 #include "IMB_imbuf_types.h"
56 #include "IMB_imbuf.h"
57
58 typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
59                                ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
60                                float tangmat[3][3], const int x, const int y);
61
62 typedef void * (*MInitBakeData)(MultiresBakeRender *bkr, Image *ima);
63 typedef void   (*MApplyBakeData)(void *bake_data);
64 typedef void   (*MFreeBakeData)(void *bake_data);
65
66 typedef struct {
67         MVert *mvert;
68         MFace *mface;
69         MTFace *mtface;
70         float *pvtangent;
71         float *precomputed_normals;
72         int w, h;
73         int face_index;
74         int i0, i1, i2;
75         DerivedMesh *lores_dm, *hires_dm;
76         int lvl;
77         void *bake_data;
78         ImBuf *ibuf;
79         MPassKnownData pass_data;
80 } MResolvePixelData;
81
82 typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
83
84 typedef struct {
85         int w, h;
86         char *texels;
87         const MResolvePixelData *data;
88         MFlushPixel flush_pixel;
89 } MBakeRast;
90
91 typedef struct {
92         float *heights;
93         float height_min, height_max;
94         Image *ima;
95         DerivedMesh *ssdm;
96         const int *orig_index_mf_to_mpoly;
97         const int *orig_index_mp_to_orig;
98 } MHeightBakeData;
99
100 typedef struct {
101         const int *orig_index_mf_to_mpoly;
102         const int *orig_index_mp_to_orig;
103 } MNormalBakeData;
104
105 static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
106 {
107         unsigned int indices[] = {data->mface[face_num].v1, data->mface[face_num].v2,
108                                   data->mface[face_num].v3, data->mface[face_num].v4};
109         const int smoothnormal = (data->mface[face_num].flag & ME_SMOOTH);
110
111         if (!smoothnormal) { /* flat */
112                 if (data->precomputed_normals) {
113                         copy_v3_v3(norm, &data->precomputed_normals[3 * face_num]);
114                 }
115                 else {
116                         float nor[3];
117                         float *p0, *p1, *p2;
118                         const int iGetNrVerts = data->mface[face_num].v4 != 0 ? 4 : 3;
119
120                         p0 = data->mvert[indices[0]].co;
121                         p1 = data->mvert[indices[1]].co;
122                         p2 = data->mvert[indices[2]].co;
123
124                         if (iGetNrVerts == 4) {
125                                 float *p3 = data->mvert[indices[3]].co;
126                                 normal_quad_v3(nor, p0, p1, p2, p3);
127                         }
128                         else {
129                                 normal_tri_v3(nor, p0, p1, p2);
130                         }
131
132                         copy_v3_v3(norm, nor);
133                 }
134         }
135         else {
136                 short *no = data->mvert[indices[vert_index]].no;
137
138                 normal_short_to_float_v3(norm, no);
139                 normalize_v3(norm);
140         }
141 }
142
143 static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel)
144 {
145         memset(bake_rast, 0, sizeof(MBakeRast));
146
147         bake_rast->texels = ibuf->userdata;
148         bake_rast->w = ibuf->x;
149         bake_rast->h = ibuf->y;
150         bake_rast->data = data;
151         bake_rast->flush_pixel = flush_pixel;
152 }
153
154 static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
155 {
156         float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h};
157         float *st0, *st1, *st2;
158         float *tang0, *tang1, *tang2;
159         float no0[3], no1[3], no2[3];
160         float fUV[2], from_tang[3][3], to_tang[3][3];
161         float u, v, w, sign;
162         int r;
163
164         const int i0 = data->i0;
165         const int i1 = data->i1;
166         const int i2 = data->i2;
167
168         st0 = data->mtface[data->face_index].uv[i0];
169         st1 = data->mtface[data->face_index].uv[i1];
170         st2 = data->mtface[data->face_index].uv[i2];
171
172         tang0 = data->pvtangent + data->face_index * 16 + i0 * 4;
173         tang1 = data->pvtangent + data->face_index * 16 + i1 * 4;
174         tang2 = data->pvtangent + data->face_index * 16 + i2 * 4;
175
176         multiresbake_get_normal(data, no0, data->face_index, i0);   /* can optimize these 3 into one call */
177         multiresbake_get_normal(data, no1, data->face_index, i1);
178         multiresbake_get_normal(data, no2, data->face_index, i2);
179
180         resolve_tri_uv(fUV, st, st0, st1, st2);
181
182         u = fUV[0];
183         v = fUV[1];
184         w = 1 - u - v;
185
186         /* the sign is the same at all face vertices for any non degenerate face.
187          * Just in case we clamp the interpolated value though. */
188         sign = (tang0[3] * u + tang1[3] * v + tang2[3] * w) < 0 ? (-1.0f) : 1.0f;
189
190         /* this sequence of math is designed specifically as is with great care
191          * to be compatible with our shader. Please don't change without good reason. */
192         for (r = 0; r < 3; r++) {
193                 from_tang[0][r] = tang0[r] * u + tang1[r] * v + tang2[r] * w;
194                 from_tang[2][r] = no0[r] * u + no1[r] * v + no2[r] * w;
195         }
196
197         cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]);  /* B = sign * cross(N, T)  */
198         mul_v3_fl(from_tang[1], sign);
199         invert_m3_m3(to_tang, from_tang);
200         /* sequence end */
201
202         data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
203                         data->ibuf, data->face_index, data->lvl, st, to_tang, x, y);
204 }
205
206 static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
207 {
208         const int w = bake_rast->w;
209         const int h = bake_rast->h;
210
211         if (x >= 0 && x < w && y >= 0 && y < h) {
212                 if ((bake_rast->texels[y * w + x]) == 0) {
213                         flush_pixel(bake_rast->data, x, y);
214                         bake_rast->texels[y * w + x] = FILTER_MASK_USED;
215                 }
216         }
217 }
218
219 static void rasterize_half(const MBakeRast *bake_rast,
220                            const float s0_s, const float t0_s, const float s1_s, const float t1_s,
221                            const float s0_l, const float t0_l, const float s1_l, const float t1_l,
222                            const int y0_in, const int y1_in, const int is_mid_right)
223 {
224         const int s_stable = fabsf(t1_s - t0_s) > FLT_EPSILON ? 1 : 0;
225         const int l_stable = fabsf(t1_l - t0_l) > FLT_EPSILON ? 1 : 0;
226         const int w = bake_rast->w;
227         const int h = bake_rast->h;
228         int y, y0, y1;
229
230         if (y1_in <= 0 || y0_in >= h)
231                 return;
232
233         y0 = y0_in < 0 ? 0 : y0_in;
234         y1 = y1_in >= h ? h : y1_in;
235
236         for (y = y0; y < y1; y++) {
237                 /*-b(x-x0) + a(y-y0) = 0 */
238                 int iXl, iXr, x;
239                 float x_l = s_stable != 0 ? (s0_s + (((s1_s - s0_s) * (y - t0_s)) / (t1_s - t0_s))) : s0_s;
240                 float x_r = l_stable != 0 ? (s0_l + (((s1_l - s0_l) * (y - t0_l)) / (t1_l - t0_l))) : s0_l;
241
242                 if (is_mid_right != 0)
243                         SWAP(float, x_l, x_r);
244
245                 iXl = (int)ceilf(x_l);
246                 iXr = (int)ceilf(x_r);
247
248                 if (iXr > 0 && iXl < w) {
249                         iXl = iXl < 0 ? 0 : iXl;
250                         iXr = iXr >= w ? w : iXr;
251
252                         for (x = iXl; x < iXr; x++)
253                                 set_rast_triangle(bake_rast, x, y);
254                 }
255         }
256 }
257
258 static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2])
259 {
260         const int w = bake_rast->w;
261         const int h = bake_rast->h;
262         float slo = st0_in[0] * w - 0.5f;
263         float tlo = st0_in[1] * h - 0.5f;
264         float smi = st1_in[0] * w - 0.5f;
265         float tmi = st1_in[1] * h - 0.5f;
266         float shi = st2_in[0] * w - 0.5f;
267         float thi = st2_in[1] * h - 0.5f;
268         int is_mid_right = 0, ylo, yhi, yhi_beg;
269
270         /* skip degenerates */
271         if ((slo == smi && tlo == tmi) || (slo == shi && tlo == thi) || (smi == shi && tmi == thi))
272                 return;
273
274         /* sort by T */
275         if (tlo > tmi && tlo > thi) {
276                 SWAP(float, shi, slo);
277                 SWAP(float, thi, tlo);
278         }
279         else if (tmi > thi) {
280                 SWAP(float, shi, smi);
281                 SWAP(float, thi, tmi);
282         }
283
284         if (tlo > tmi) {
285                 SWAP(float, slo, smi);
286                 SWAP(float, tlo, tmi);
287         }
288
289         /* check if mid point is to the left or to the right of the lo-hi edge */
290         is_mid_right = (-(shi - slo) * (tmi - thi) + (thi - tlo) * (smi - shi)) > 0 ? 1 : 0;
291         ylo = (int) ceilf(tlo);
292         yhi_beg = (int) ceilf(tmi);
293         yhi = (int) ceilf(thi);
294
295         /*if (fTmi>ceilf(fTlo))*/
296         rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right);
297         rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right);
298 }
299
300 static int multiresbake_test_break(MultiresBakeRender *bkr)
301 {
302         if (!bkr->stop) {
303                 /* this means baker is executed outside from job system */
304                 return 0;
305         }
306
307         return G.is_break;
308 }
309
310 static void do_multires_bake(MultiresBakeRender *bkr, Image *ima, MPassKnownData passKnownData,
311                              MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
312 {
313         DerivedMesh *dm = bkr->lores_dm;
314         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
315         const int lvl = bkr->lvl;
316         const int tot_face = dm->getNumTessFaces(dm);
317         MVert *mvert = dm->getVertArray(dm);
318         MFace *mface = dm->getTessFaceArray(dm);
319         MTFace *mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
320         float *pvtangent = NULL;
321
322         if (CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
323                 DM_add_tangent_layer(dm);
324
325         pvtangent = DM_get_tessface_data_layer(dm, CD_TANGENT);
326
327         if (tot_face > 0) {  /* sanity check */
328                 int f = 0;
329                 MBakeRast bake_rast;
330                 MResolvePixelData data = {NULL};
331
332                 data.mface = mface;
333                 data.mvert = mvert;
334                 data.mtface = mtface;
335                 data.pvtangent = pvtangent;
336                 data.precomputed_normals = dm->getTessFaceDataArray(dm, CD_NORMAL);  /* don't strictly need this */
337                 data.w = ibuf->x;
338                 data.h = ibuf->y;
339                 data.lores_dm = dm;
340                 data.hires_dm = bkr->hires_dm;
341                 data.lvl = lvl;
342                 data.pass_data = passKnownData;
343
344                 if (initBakeData)
345                         data.bake_data = initBakeData(bkr, ima);
346
347                 init_bake_rast(&bake_rast, ibuf, &data, flush_pixel);
348
349                 for (f = 0; f < tot_face; f++) {
350                         MTFace *mtfate = &mtface[f];
351                         int verts[3][2], nr_tris, t;
352
353                         if (multiresbake_test_break(bkr))
354                                 break;
355
356                         if (mtfate->tpage != ima)
357                                 continue;
358
359                         data.face_index = f;
360                         data.ibuf = ibuf;
361
362                         /* might support other forms of diagonal splits later on such as
363                          * split by shortest diagonal.*/
364                         verts[0][0] = 0;
365                         verts[1][0] = 1;
366                         verts[2][0] = 2;
367
368                         verts[0][1] = 0;
369                         verts[1][1] = 2;
370                         verts[2][1] = 3;
371
372                         nr_tris = mface[f].v4 != 0 ? 2 : 1;
373                         for (t = 0; t < nr_tris; t++) {
374                                 data.i0 = verts[0][t];
375                                 data.i1 = verts[1][t];
376                                 data.i2 = verts[2][t];
377
378                                 bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]);
379                         }
380
381                         bkr->baked_faces++;
382
383                         if (bkr->do_update)
384                                 *bkr->do_update = TRUE;
385
386                         if (bkr->progress)
387                                 *bkr->progress = ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj;
388                 }
389
390                 if (applyBakeData)
391                         applyBakeData(data.bake_data);
392
393                 if (freeBakeData)
394                         freeBakeData(data.bake_data);
395         }
396
397         BKE_image_release_ibuf(ima, ibuf, NULL);
398 }
399
400 /* mode = 0: interpolate normals,
401  * mode = 1: interpolate coord */
402 static void interp_bilinear_grid(CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3])
403 {
404         int x0, x1, y0, y1;
405         float u, v;
406         float data[4][3];
407
408         x0 = (int) crn_x;
409         x1 = x0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (x0 + 1);
410
411         y0 = (int) crn_y;
412         y1 = y0 >= (key->grid_size - 1) ? (key->grid_size - 1) : (y0 + 1);
413
414         u = crn_x - x0;
415         v = crn_y - y0;
416
417         if (mode == 0) {
418                 copy_v3_v3(data[0], CCG_grid_elem_no(key, grid, x0, y0));
419                 copy_v3_v3(data[1], CCG_grid_elem_no(key, grid, x1, y0));
420                 copy_v3_v3(data[2], CCG_grid_elem_no(key, grid, x1, y1));
421                 copy_v3_v3(data[3], CCG_grid_elem_no(key, grid, x0, y1));
422         }
423         else {
424                 copy_v3_v3(data[0], CCG_grid_elem_co(key, grid, x0, y0));
425                 copy_v3_v3(data[1], CCG_grid_elem_co(key, grid, x1, y0));
426                 copy_v3_v3(data[2], CCG_grid_elem_co(key, grid, x1, y1));
427                 copy_v3_v3(data[3], CCG_grid_elem_co(key, grid, x0, y1));
428         }
429
430         interp_bilinear_quad_v3(data, u, v, res);
431 }
432
433 static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm,
434                            const int *index_mf_to_mpoly, const int *index_mp_to_orig,
435                            const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
436 {
437         MFace mface;
438         CCGElem **grid_data;
439         CCGKey key;
440         float crn_x, crn_y;
441         int grid_size, S, face_side;
442         int *grid_offset, g_index;
443
444         lodm->getTessFace(lodm, face_index, &mface);
445
446         grid_size = hidm->getGridSize(hidm);
447         grid_data = hidm->getGridData(hidm);
448         grid_offset = hidm->getGridOffset(hidm);
449         hidm->getGridKey(hidm, &key);
450
451         face_side = (grid_size << 1) - 1;
452
453         if (lvl == 0) {
454                 g_index = grid_offset[face_index];
455                 S = mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u * (face_side - 1), v * (face_side - 1), &crn_x, &crn_y);
456         }
457         else {
458                 int side = (1 << (lvl - 1)) + 1;
459                 int grid_index = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, face_index);
460                 int loc_offs = face_index % (1 << (2 * lvl));
461                 int cell_index = loc_offs % ((side - 1) * (side - 1));
462                 int cell_side = (grid_size - 1) / (side - 1);
463                 int row = cell_index / (side - 1);
464                 int col = cell_index % (side - 1);
465
466                 S = face_index / (1 << (2 * (lvl - 1))) - grid_offset[grid_index];
467                 g_index = grid_offset[grid_index];
468
469                 crn_y = (row * cell_side) + u * cell_side;
470                 crn_x = (col * cell_side) + v * cell_side;
471         }
472
473         CLAMP(crn_x, 0.0f, grid_size);
474         CLAMP(crn_y, 0.0f, grid_size);
475
476         if (n != NULL)
477                 interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n);
478
479         if (co != NULL)
480                 interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co);
481 }
482
483 /* mode = 0: interpolate normals,
484  * mode = 1: interpolate coord */
485 static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
486 {
487         float data[4][3];
488
489         if (mode == 0) {
490                 dm->getVertNo(dm, mface->v1, data[0]);
491                 dm->getVertNo(dm, mface->v2, data[1]);
492                 dm->getVertNo(dm, mface->v3, data[2]);
493                 dm->getVertNo(dm, mface->v4, data[3]);
494         }
495         else {
496                 dm->getVertCo(dm, mface->v1, data[0]);
497                 dm->getVertCo(dm, mface->v2, data[1]);
498                 dm->getVertCo(dm, mface->v3, data[2]);
499                 dm->getVertCo(dm, mface->v4, data[3]);
500         }
501
502         interp_bilinear_quad_v3(data, u, v, res);
503 }
504
505 /* mode = 0: interpolate normals,
506  * mode = 1: interpolate coord */
507 static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
508 {
509         float data[3][3];
510
511         if (mode == 0) {
512                 dm->getVertNo(dm, mface->v1, data[0]);
513                 dm->getVertNo(dm, mface->v2, data[1]);
514                 dm->getVertNo(dm, mface->v3, data[2]);
515         }
516         else {
517                 dm->getVertCo(dm, mface->v1, data[0]);
518                 dm->getVertCo(dm, mface->v2, data[1]);
519                 dm->getVertCo(dm, mface->v3, data[2]);
520         }
521
522         interp_barycentric_tri_v3(data, u, v, res);
523 }
524
525 /* **************** Displacement Baker **************** */
526
527 static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
528 {
529         MHeightBakeData *height_data;
530         ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
531         DerivedMesh *lodm = bkr->lores_dm;
532
533         height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
534
535         height_data->ima = ima;
536         height_data->heights = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, "MultiresBake heights");
537         height_data->height_max = -FLT_MAX;
538         height_data->height_min = FLT_MAX;
539
540         if (!bkr->use_lores_mesh) {
541                 SubsurfModifierData smd = {{NULL}};
542                 int ss_lvl = bkr->tot_lvl - bkr->lvl;
543
544                 CLAMP(ss_lvl, 0, 6);
545
546                 if (ss_lvl > 0) {
547                         smd.levels = smd.renderLevels = ss_lvl;
548                         smd.flags |= eSubsurfModifierFlag_SubsurfUv;
549
550                         if (bkr->simple)
551                                 smd.subdivType = ME_SIMPLE_SUBSURF;
552
553                         height_data->ssdm = subsurf_make_derived_from_derived(bkr->lores_dm, &smd, NULL, 0);
554                 }
555         }
556
557         height_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
558         height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
559
560         BKE_image_release_ibuf(ima, ibuf, NULL);
561
562         return (void *)height_data;
563 }
564
565 static void apply_heights_data(void *bake_data)
566 {
567         MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
568         ImBuf *ibuf = BKE_image_acquire_ibuf(height_data->ima, NULL, NULL);
569         int x, y, i;
570         float height, *heights = height_data->heights;
571         float min = height_data->height_min, max = height_data->height_max;
572
573         for (x = 0; x < ibuf->x; x++) {
574                 for (y = 0; y < ibuf->y; y++) {
575                         i = ibuf->x * y + x;
576
577                         if (((char *)ibuf->userdata)[i] != FILTER_MASK_USED)
578                                 continue;
579
580                         if (ibuf->rect_float) {
581                                 float *rrgbf = ibuf->rect_float + i * 4;
582
583                                 if (max - min > 1e-5f) height = (heights[i] - min) / (max - min);
584                                 else height = 0;
585
586                                 rrgbf[0] = rrgbf[1] = rrgbf[2] = height;
587                         }
588                         else {
589                                 char *rrgb = (char *)ibuf->rect + i * 4;
590
591                                 if (max - min > 1e-5f) height = (heights[i] - min) / (max - min);
592                                 else height = 0;
593
594                                 rrgb[0] = rrgb[1] = rrgb[2] = FTOCHAR(height);
595                         }
596                 }
597         }
598
599         ibuf->userflags = IB_RECT_INVALID | IB_DISPLAY_BUFFER_INVALID;
600
601         BKE_image_release_ibuf(height_data->ima, ibuf, NULL);
602 }
603
604 static void free_heights_data(void *bake_data)
605 {
606         MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
607
608         if (height_data->ssdm)
609                 height_data->ssdm->release(height_data->ssdm);
610
611         MEM_freeN(height_data->heights);
612         MEM_freeN(height_data);
613 }
614
615 /* MultiresBake callback for heights baking
616  * general idea:
617  *   - find coord of point with specified UV in hi-res mesh (let's call it p1)
618  *   - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
619  *     mesh to make texture smoother) let's call this point p0 and n.
620  *   - height wound be dot(n, p1-p0) */
621 static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
622                                    ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
623                                    float UNUSED(tangmat[3][3]), const int x, const int y)
624 {
625         MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
626         MFace mface;
627         MHeightBakeData *height_data = (MHeightBakeData *)bake_data;
628         float uv[2], *st0, *st1, *st2, *st3;
629         int pixel = ibuf->x * y + x;
630         float vec[3], p0[3], p1[3], n[3], len;
631
632         lores_dm->getTessFace(lores_dm, face_index, &mface);
633
634         st0 = mtface[face_index].uv[0];
635         st1 = mtface[face_index].uv[1];
636         st2 = mtface[face_index].uv[2];
637
638         if (mface.v4) {
639                 st3 = mtface[face_index].uv[3];
640                 resolve_quad_uv(uv, st, st0, st1, st2, st3);
641         }
642         else
643                 resolve_tri_uv(uv, st, st0, st1, st2);
644
645         CLAMP(uv[0], 0.0f, 1.0f);
646         CLAMP(uv[1], 0.0f, 1.0f);
647
648         get_ccgdm_data(lores_dm, hires_dm,
649                        height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly,
650                        lvl, face_index, uv[0], uv[1], p1, 0);
651
652         if (height_data->ssdm) {
653                 get_ccgdm_data(lores_dm, height_data->ssdm,
654                                height_data->orig_index_mf_to_mpoly, height_data->orig_index_mf_to_mpoly,
655                                0, face_index, uv[0], uv[1], p0, n);
656         }
657         else {
658                 lores_dm->getTessFace(lores_dm, face_index, &mface);
659
660                 if (mface.v4) {
661                         interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
662                         interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
663                 }
664                 else {
665                         interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
666                         interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
667                 }
668         }
669
670         sub_v3_v3v3(vec, p1, p0);
671         len = dot_v3v3(n, vec);
672
673         height_data->heights[pixel] = len;
674         if (len < height_data->height_min) height_data->height_min = len;
675         if (len > height_data->height_max) height_data->height_max = len;
676
677         if (ibuf->rect_float) {
678                 float *rrgbf = ibuf->rect_float + pixel * 4;
679                 rrgbf[3] = 1.0f;
680
681                 ibuf->userflags = IB_RECT_INVALID;
682         }
683         else {
684                 char *rrgb = (char *)ibuf->rect + pixel * 4;
685                 rrgb[3] = 255;
686         }
687
688         ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
689 }
690
691 /* **************** Normal Maps Baker **************** */
692
693 static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
694 {
695         MNormalBakeData *normal_data;
696         DerivedMesh *lodm = bkr->lores_dm;
697
698         normal_data = MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData");
699
700         normal_data->orig_index_mf_to_mpoly = lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
701         normal_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
702
703         return (void *)normal_data;
704 }
705
706 static void free_normal_data(void *bake_data)
707 {
708         MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
709
710         MEM_freeN(normal_data);
711 }
712
713 /* MultiresBake callback for normals' baking
714  * general idea:
715  *   - find coord and normal of point with specified UV in hi-res mesh
716  *   - multiply it by tangmat
717  *   - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
718 static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
719                                    ImBuf *ibuf, const int face_index, const int lvl, const float st[2],
720                                    float tangmat[3][3], const int x, const int y)
721 {
722         MTFace *mtface = CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
723         MFace mface;
724         MNormalBakeData *normal_data = (MNormalBakeData *)bake_data;
725         float uv[2], *st0, *st1, *st2, *st3;
726         int pixel = ibuf->x * y + x;
727         float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5};
728
729         lores_dm->getTessFace(lores_dm, face_index, &mface);
730
731         st0 = mtface[face_index].uv[0];
732         st1 = mtface[face_index].uv[1];
733         st2 = mtface[face_index].uv[2];
734
735         if (mface.v4) {
736                 st3 = mtface[face_index].uv[3];
737                 resolve_quad_uv(uv, st, st0, st1, st2, st3);
738         }
739         else
740                 resolve_tri_uv(uv, st, st0, st1, st2);
741
742         CLAMP(uv[0], 0.0f, 1.0f);
743         CLAMP(uv[1], 0.0f, 1.0f);
744
745         get_ccgdm_data(lores_dm, hires_dm,
746                        normal_data->orig_index_mf_to_mpoly, normal_data->orig_index_mp_to_orig,
747                        lvl, face_index, uv[0], uv[1], NULL, n);
748
749         mul_v3_m3v3(vec, tangmat, n);
750         normalize_v3(vec);
751         mul_v3_fl(vec, 0.5);
752         add_v3_v3(vec, tmp);
753
754         if (ibuf->rect_float) {
755                 float *rrgbf = ibuf->rect_float + pixel * 4;
756                 rrgbf[0] = vec[0];
757                 rrgbf[1] = vec[1];
758                 rrgbf[2] = vec[2];
759                 rrgbf[3] = 1.0f;
760
761                 ibuf->userflags = IB_RECT_INVALID;
762         }
763         else {
764                 unsigned char *rrgb = (unsigned char *)ibuf->rect + pixel * 4;
765                 rgb_float_to_uchar(rrgb, vec);
766                 rrgb[3] = 255;
767         }
768
769         ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
770 }
771
772 /* **************** Common functions public API relates on **************** */
773
774 static void count_images(MultiresBakeRender *bkr)
775 {
776         int a, totface;
777         DerivedMesh *dm = bkr->lores_dm;
778         MTFace *mtface = CustomData_get_layer(&dm->faceData, CD_MTFACE);
779
780         bkr->image.first = bkr->image.last = NULL;
781         bkr->tot_image = 0;
782
783         totface = dm->getNumTessFaces(dm);
784
785         for (a = 0; a < totface; a++)
786                 mtface[a].tpage->id.flag &= ~LIB_DOIT;
787
788         for (a = 0; a < totface; a++) {
789                 Image *ima = mtface[a].tpage;
790                 if ((ima->id.flag & LIB_DOIT) == 0) {
791                         LinkData *data = BLI_genericNodeN(ima);
792                         BLI_addtail(&bkr->image, data);
793                         bkr->tot_image++;
794                         ima->id.flag |= LIB_DOIT;
795                 }
796         }
797
798         for (a = 0; a < totface; a++)
799                 mtface[a].tpage->id.flag &= ~LIB_DOIT;
800 }
801
802 static void bake_images(MultiresBakeRender *bkr)
803 {
804         LinkData *link;
805
806         for (link = bkr->image.first; link; link = link->next) {
807                 Image *ima = (Image *)link->data;
808                 ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
809
810                 if (ibuf->x > 0 && ibuf->y > 0) {
811                         ibuf->userdata = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
812
813                         switch (bkr->mode) {
814                                 case RE_BAKE_NORMALS:
815                                         do_multires_bake(bkr, ima, apply_tangmat_callback, init_normal_data, NULL, free_normal_data);
816                                         break;
817                                 case RE_BAKE_DISPLACEMENT:
818                                         do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data,
819                                                          apply_heights_data, free_heights_data);
820                                         break;
821                         }
822                 }
823
824                 BKE_image_release_ibuf(ima, ibuf, NULL);
825
826                 ima->id.flag |= LIB_DOIT;
827         }
828 }
829
830 static void finish_images(MultiresBakeRender *bkr)
831 {
832         LinkData *link;
833
834         for (link = bkr->image.first; link; link = link->next) {
835                 Image *ima = (Image *)link->data;
836                 ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
837
838                 if (ibuf->x <= 0 || ibuf->y <= 0)
839                         continue;
840
841                 RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter);
842
843                 ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;
844
845                 if (ibuf->rect_float)
846                         ibuf->userflags |= IB_RECT_INVALID;
847
848                 if (ibuf->mipmap[0]) {
849                         ibuf->userflags |= IB_MIPMAP_INVALID;
850                         imb_freemipmapImBuf(ibuf);
851                 }
852
853                 if (ibuf->userdata) {
854                         MEM_freeN(ibuf->userdata);
855                         ibuf->userdata = NULL;
856                 }
857
858                 BKE_image_release_ibuf(ima, ibuf, NULL);
859         }
860 }
861
862 void RE_multires_bake_images(MultiresBakeRender *bkr)
863 {
864         count_images(bkr);
865         bake_images(bkr);
866         finish_images(bkr);
867 }