went over all uses of mesh->mface and added BMESH_TODO comments for
[blender.git] / source / blender / editors / object / object_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) 2004 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/editors/object/object_bake.c
30  *  \ingroup edobj
31  */
32
33
34 /*
35         meshtools.c: no editmode (violated already :), tools operating on meshes
36 */
37
38 #include <string.h>
39
40 #include "MEM_guardedalloc.h"
41
42 #include "DNA_scene_types.h"
43 #include "DNA_screen_types.h"
44 #include "DNA_space_types.h"
45 #include "DNA_world_types.h"
46 #include "DNA_object_types.h"
47 #include "DNA_mesh_types.h"
48 #include "DNA_meshdata_types.h"
49
50 #include "BLI_blenlib.h"
51 #include "BLI_threads.h"
52 #include "BLI_utildefines.h"
53 #include "BLI_math.h"
54 #include "BLI_math_geom.h"
55
56 #include "BKE_blender.h"
57 #include "BKE_screen.h"
58 #include "BKE_context.h"
59 #include "BKE_global.h"
60 #include "BKE_image.h"
61 #include "BKE_main.h"
62 #include "BKE_multires.h"
63 #include "BKE_report.h"
64 #include "BKE_cdderivedmesh.h"
65 #include "BKE_modifier.h"
66 #include "BKE_DerivedMesh.h"
67 #include "BKE_subsurf.h"
68
69 #include "RE_pipeline.h"
70 #include "RE_shader_ext.h"
71
72 #include "PIL_time.h"
73
74 #include "IMB_imbuf_types.h"
75 #include "IMB_imbuf.h"
76
77 #include "GPU_draw.h" /* GPU_free_image */
78
79 #include "WM_api.h"
80 #include "WM_types.h"
81
82 #include "ED_object.h"
83
84 #include "object_intern.h"
85
86 /* ****************** multires BAKING ********************** */
87
88 /* holder of per-object data needed for bake job
89    needed to make job totally thread-safe */
90 typedef struct MultiresBakerJobData {
91         struct MultiresBakerJobData *next, *prev;
92         DerivedMesh *lores_dm, *hires_dm;
93         int simple, lvl, tot_lvl;
94 } MultiresBakerJobData;
95
96 /* data passing to multires-baker job */
97 typedef struct {
98         ListBase data;
99         int bake_clear, bake_filter;
100         short mode, use_lores_mesh;
101 } MultiresBakeJob;
102
103 /* data passing to multires baker */
104 typedef struct {
105         DerivedMesh *lores_dm, *hires_dm;
106         int simple, lvl, tot_lvl, bake_filter;
107         short mode, use_lores_mesh;
108
109         int tot_obj, tot_image;
110         ListBase image;
111
112         int baked_objects, baked_faces;
113
114         short *stop;
115         short *do_update;
116         float *progress;
117 } MultiresBakeRender;
118
119 typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
120                                const int face_index, const int lvl, const float st[2],
121                                float tangmat[3][3], const int x, const int y);
122
123 typedef void* (*MInitBakeData)(MultiresBakeRender *bkr, Image* ima);
124 typedef void (*MApplyBakeData)(void *bake_data);
125 typedef void (*MFreeBakeData)(void *bake_data);
126
127 typedef struct {
128         MVert *mvert;
129         MFace *mface;
130         MTFace *mtface;
131         float *pvtangent;
132         float *precomputed_normals;
133         int w, h;
134         int face_index;
135         int i0, i1, i2;
136         DerivedMesh *lores_dm, *hires_dm;
137         int lvl;
138         void *bake_data;
139         MPassKnownData pass_data;
140 } MResolvePixelData;
141
142 typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
143
144 typedef struct {
145         int w, h;
146         char *texels;
147         const MResolvePixelData *data;
148         MFlushPixel flush_pixel;
149 } MBakeRast;
150
151 typedef struct {
152         float *heights;
153         float height_min, height_max;
154         Image *ima;
155         DerivedMesh *ssdm;
156         const int *origindex;
157 } MHeightBakeData;
158
159 typedef struct {
160         const int *origindex;
161 } MNormalBakeData;
162
163 static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
164 {
165         unsigned int indices[]= {data->mface[face_num].v1, data->mface[face_num].v2,
166                                  data->mface[face_num].v3, data->mface[face_num].v4};
167         const int smoothnormal= (data->mface[face_num].flag & ME_SMOOTH);
168
169         if(!smoothnormal)  { /* flat */
170                 if(data->precomputed_normals) {
171                         copy_v3_v3(norm, &data->precomputed_normals[3*face_num]);
172                 } else {
173                         float nor[3];
174                         float *p0, *p1, *p2;
175                         const int iGetNrVerts= data->mface[face_num].v4!=0 ? 4 : 3;
176
177                         p0= data->mvert[indices[0]].co;
178                         p1= data->mvert[indices[1]].co;
179                         p2= data->mvert[indices[2]].co;
180
181                         if(iGetNrVerts==4) {
182                                 float *p3= data->mvert[indices[3]].co;
183                                 normal_quad_v3(nor, p0, p1, p2, p3);
184                         } else {
185                                 normal_tri_v3(nor, p0, p1, p2);
186                         }
187
188                         copy_v3_v3(norm, nor);
189                 }
190         } else {
191                 short *no= data->mvert[indices[vert_index]].no;
192
193                 normal_short_to_float_v3(norm, no);
194                 normalize_v3(norm);
195         }
196 }
197
198 static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel)
199 {
200         memset(bake_rast, 0, sizeof(MBakeRast));
201
202         bake_rast->texels = ibuf->userdata;
203         bake_rast->w= ibuf->x;
204         bake_rast->h= ibuf->y;
205         bake_rast->data= data;
206         bake_rast->flush_pixel= flush_pixel;
207 }
208
209 static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
210 {
211         float st[2]= {(x+0.5f)/data->w, (y+0.5f)/data->h};
212         float *st0, *st1, *st2;
213         float *tang0, *tang1, *tang2;
214         float no0[3], no1[3], no2[3];
215         float fUV[2], from_tang[3][3], to_tang[3][3];
216         float u, v, w, sign;
217         int r;
218
219         const int i0= data->i0;
220         const int i1= data->i1;
221         const int i2= data->i2;
222
223         st0= data->mtface[data->face_index].uv[i0];
224         st1= data->mtface[data->face_index].uv[i1];
225         st2= data->mtface[data->face_index].uv[i2];
226
227         tang0= data->pvtangent + data->face_index*16 + i0*4;
228         tang1= data->pvtangent + data->face_index*16 + i1*4;
229         tang2= data->pvtangent + data->face_index*16 + i2*4;
230
231         multiresbake_get_normal(data, no0, data->face_index, i0);       /* can optimize these 3 into one call */
232         multiresbake_get_normal(data, no1, data->face_index, i1);
233         multiresbake_get_normal(data, no2, data->face_index, i2);
234
235         resolve_tri_uv(fUV, st, st0, st1, st2);
236
237         u= fUV[0];
238         v= fUV[1];
239         w= 1-u-v;
240
241         /* the sign is the same at all face vertices for any non degenerate face.
242            Just in case we clamp the interpolated value though. */
243         sign= (tang0[3]*u + tang1[3]*v + tang2[3]*w)<0 ? (-1.0f) : 1.0f;
244
245         /* this sequence of math is designed specifically as is with great care
246            to be compatible with our shader. Please don't change without good reason. */
247         for(r= 0; r<3; r++) {
248                 from_tang[0][r]= tang0[r]*u + tang1[r]*v + tang2[r]*w;
249                 from_tang[2][r]= no0[r]*u + no1[r]*v + no2[r]*w;
250         }
251
252         cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]);  /* B = sign * cross(N, T)  */
253         mul_v3_fl(from_tang[1], sign);
254         invert_m3_m3(to_tang, from_tang);
255         /* sequence end */
256
257         data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
258                         data->face_index, data->lvl, st, to_tang, x, y);
259 }
260
261 static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
262 {
263         const int w= bake_rast->w;
264         const int h= bake_rast->h;
265
266         if(x>=0 && x<w && y>=0 && y<h) {
267                 if((bake_rast->texels[y*w+x])==0) {
268                         flush_pixel(bake_rast->data, x, y);
269                         bake_rast->texels[y*w+x]= FILTER_MASK_USED;
270                 }
271         }
272 }
273
274 static void rasterize_half(const MBakeRast *bake_rast,
275                            const float s0_s, const float t0_s, const float s1_s, const float t1_s,
276                            const float s0_l, const float t0_l, const float s1_l, const float t1_l,
277                            const int y0_in, const int y1_in, const int is_mid_right)
278 {
279         const int s_stable= fabsf(t1_s-t0_s)>FLT_EPSILON ? 1 : 0;
280         const int l_stable= fabsf(t1_l-t0_l)>FLT_EPSILON ? 1 : 0;
281         const int w= bake_rast->w;
282         const int h= bake_rast->h;
283         int y, y0, y1;
284
285         if(y1_in<=0 || y0_in>=h)
286                 return;
287
288         y0= y0_in<0 ? 0 : y0_in;
289         y1= y1_in>=h ? h : y1_in;
290
291         for(y= y0; y<y1; y++) {
292                 /*-b(x-x0) + a(y-y0) = 0 */
293                 int iXl, iXr, x;
294                 float x_l= s_stable!=0 ? (s0_s + (((s1_s-s0_s)*(y-t0_s))/(t1_s-t0_s))) : s0_s;
295                 float x_r= l_stable!=0 ? (s0_l + (((s1_l-s0_l)*(y-t0_l))/(t1_l-t0_l))) : s0_l;
296
297                 if(is_mid_right!=0)
298                         SWAP(float, x_l, x_r);
299
300                 iXl= (int)ceilf(x_l);
301                 iXr= (int)ceilf(x_r);
302
303                 if(iXr>0 && iXl<w) {
304                         iXl= iXl<0?0:iXl;
305                         iXr= iXr>=w?w:iXr;
306
307                         for(x= iXl; x<iXr; x++)
308                                 set_rast_triangle(bake_rast, x, y);
309                 }
310         }
311 }
312
313 static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2])
314 {
315         const int w= bake_rast->w;
316         const int h= bake_rast->h;
317         float slo= st0_in[0]*w - 0.5f;
318         float tlo= st0_in[1]*h - 0.5f;
319         float smi= st1_in[0]*w - 0.5f;
320         float tmi= st1_in[1]*h - 0.5f;
321         float shi= st2_in[0]*w - 0.5f;
322         float thi= st2_in[1]*h - 0.5f;
323         int is_mid_right= 0, ylo, yhi, yhi_beg;
324
325         /* skip degenerates */
326         if((slo==smi && tlo==tmi) || (slo==shi && tlo==thi) || (smi==shi && tmi==thi))
327                 return;
328
329         /* sort by T */
330         if(tlo>tmi && tlo>thi) {
331                 SWAP(float, shi, slo);
332                 SWAP(float, thi, tlo);
333         } else if(tmi>thi) {
334                 SWAP(float, shi, smi);
335                 SWAP(float, thi, tmi);
336         }
337
338         if(tlo>tmi) {
339                 SWAP(float, slo, smi);
340                 SWAP(float, tlo, tmi);
341         }
342
343         /* check if mid point is to the left or to the right of the lo-hi edge */
344         is_mid_right= (-(shi-slo)*(tmi-thi) + (thi-tlo)*(smi-shi))>0 ? 1 : 0;
345         ylo= (int) ceilf(tlo);
346         yhi_beg= (int) ceilf(tmi);
347         yhi= (int) ceilf(thi);
348
349         /*if(fTmi>ceilf(fTlo))*/
350         rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right);
351         rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right);
352 }
353
354 static int multiresbake_test_break(MultiresBakeRender *bkr)
355 {
356         if(!bkr->stop) {
357                 /* this means baker is executed outside from job system */
358                 return 0;
359         }
360
361         return G.afbreek;
362 }
363
364 static void do_multires_bake(MultiresBakeRender *bkr, Image* ima, MPassKnownData passKnownData,
365                              MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
366 {
367         DerivedMesh *dm= bkr->lores_dm;
368         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
369         const int lvl= bkr->lvl;
370         const int tot_face= dm->getNumTessFaces(dm);
371         MVert *mvert= dm->getVertArray(dm);
372         MFace *mface= dm->getTessFaceArray(dm);
373         MTFace *mtface= dm->getTessFaceDataArray(dm, CD_MTFACE);
374         float *pvtangent= NULL;
375
376         if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
377                 DM_add_tangent_layer(dm);
378
379         pvtangent= DM_get_tessface_data_layer(dm, CD_TANGENT);
380
381         if(tot_face > 0) {  /* sanity check */
382                 int f= 0;
383                 MBakeRast bake_rast;
384                 MResolvePixelData data={NULL};
385
386                 data.mface= mface;
387                 data.mvert= mvert;
388                 data.mtface= mtface;
389                 data.pvtangent= pvtangent;
390                 data.precomputed_normals= dm->getTessFaceDataArray(dm, CD_NORMAL);      /* don't strictly need this */
391                 data.w= ibuf->x;
392                 data.h= ibuf->y;
393                 data.lores_dm= dm;
394                 data.hires_dm= bkr->hires_dm;
395                 data.lvl= lvl;
396                 data.pass_data= passKnownData;
397
398                 if(initBakeData)
399                         data.bake_data= initBakeData(bkr, ima);
400
401                 init_bake_rast(&bake_rast, ibuf, &data, flush_pixel);
402
403                 for(f= 0; f<tot_face; f++) {
404                         MTFace *mtfate= &mtface[f];
405                         int verts[3][2], nr_tris, t;
406
407                         if(multiresbake_test_break(bkr))
408                                 break;
409
410                         if(mtfate->tpage!=ima)
411                                 continue;
412
413                         data.face_index= f;
414
415                         /* might support other forms of diagonal splits later on such as
416                            split by shortest diagonal.*/
417                         verts[0][0]=0;
418                         verts[1][0]=1;
419                         verts[2][0]=2;
420
421                         verts[0][1]=0;
422                         verts[1][1]=2;
423                         verts[2][1]=3;
424
425                         nr_tris= mface[f].v4!=0 ? 2 : 1;
426                         for(t= 0; t<nr_tris; t++) {
427                                 data.i0= verts[0][t];
428                                 data.i1= verts[1][t];
429                                 data.i2 =verts[2][t];
430
431                                 bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]);
432                         }
433
434                         bkr->baked_faces++;
435
436                         if(bkr->do_update)
437                                 *bkr->do_update= 1;
438
439                         if(bkr->progress)
440                                 *bkr->progress= ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj;
441                 }
442
443                 if(applyBakeData)
444                         applyBakeData(data.bake_data);
445
446                 if(freeBakeData)
447                         freeBakeData(data.bake_data);
448         }
449 }
450
451 static void interp_bilinear_quad_data(float data[4][3], float u, float v, float res[3])
452 {
453         float vec[3];
454
455         copy_v3_v3(res, data[0]);
456         mul_v3_fl(res, (1-u)*(1-v));
457         copy_v3_v3(vec, data[1]);
458         mul_v3_fl(vec, u*(1-v)); add_v3_v3(res, vec);
459         copy_v3_v3(vec, data[2]);
460         mul_v3_fl(vec, u*v); add_v3_v3(res, vec);
461         copy_v3_v3(vec, data[3]);
462         mul_v3_fl(vec, (1-u)*v); add_v3_v3(res, vec);
463 }
464
465 static void interp_barycentric_tri_data(float data[3][3], float u, float v, float res[3])
466 {
467         float vec[3];
468
469         copy_v3_v3(res, data[0]);
470         mul_v3_fl(res, u);
471         copy_v3_v3(vec, data[1]);
472         mul_v3_fl(vec, v); add_v3_v3(res, vec);
473         copy_v3_v3(vec, data[2]);
474         mul_v3_fl(vec, 1.0f-u-v); add_v3_v3(res, vec);
475 }
476
477 /* mode = 0: interpolate normals,
478    mode = 1: interpolate coord */
479 static void interp_bilinear_grid(DMGridData *grid, int grid_size, float crn_x, float crn_y, int mode, float res[3])
480 {
481         int x0, x1, y0, y1;
482         float u, v;
483         float data[4][3];
484
485         x0= (int) crn_x;
486         x1= x0>=(grid_size-1) ? (grid_size-1) : (x0+1);
487
488         y0= (int) crn_y;
489         y1= y0>=(grid_size-1) ? (grid_size-1) : (y0+1);
490
491         u= crn_x-x0;
492         v= crn_y-y0;
493
494         if(mode == 0) {
495                 copy_v3_v3(data[0], grid[y0 * grid_size + x0].no);
496                 copy_v3_v3(data[1], grid[y0 * grid_size + x1].no);
497                 copy_v3_v3(data[2], grid[y1 * grid_size + x1].no);
498                 copy_v3_v3(data[3], grid[y1 * grid_size + x0].no);
499         } else {
500                 copy_v3_v3(data[0], grid[y0 * grid_size + x0].co);
501                 copy_v3_v3(data[1], grid[y0 * grid_size + x1].co);
502                 copy_v3_v3(data[2], grid[y1 * grid_size + x1].co);
503                 copy_v3_v3(data[3], grid[y1 * grid_size + x0].co);
504         }
505
506         interp_bilinear_quad_data(data, u, v, res);
507 }
508
509 static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int *origindex,  const int lvl, const int face_index, const float u, const float v, float co[3], float n[3])
510 {
511         MFace mface;
512         DMGridData **grid_data;
513         float crn_x, crn_y;
514         int grid_size, S, face_side;
515         int *grid_offset, g_index;
516
517         lodm->getTessFace(lodm, face_index, &mface);
518
519         grid_size= hidm->getGridSize(hidm);
520         grid_data= hidm->getGridData(hidm);
521         grid_offset= hidm->getGridOffset(hidm);
522
523         face_side= (grid_size<<1)-1;
524
525         if(lvl==0) {
526                 g_index= grid_offset[face_index];
527                 S= mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u*(face_side-1), v*(face_side-1), &crn_x, &crn_y);
528         } else {
529                 int side= (1 << (lvl-1)) + 1;
530                 int grid_index= origindex[face_index];
531                 int loc_offs= face_index % (1<<(2*lvl));
532                 int cell_index= loc_offs % ((side-1)*(side-1));
533                 int cell_side= grid_size / (side-1);
534                 int row= cell_index / (side-1);
535                 int col= cell_index % (side-1);
536
537                 S= face_index / (1<<(2*(lvl-1))) - grid_offset[grid_index];
538                 g_index= grid_offset[grid_index];
539
540                 crn_y= (row * cell_side) + u * cell_side;
541                 crn_x= (col * cell_side) + v * cell_side;
542         }
543
544         CLAMP(crn_x, 0.0f, grid_size);
545         CLAMP(crn_y, 0.0f, grid_size);
546
547         if(n != NULL)
548                 interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 0, n);
549
550         if(co != NULL)
551                 interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 1, co);
552 }
553
554 /* mode = 0: interpolate normals,
555    mode = 1: interpolate coord */
556 static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
557 {
558         float data[4][3];
559
560         if(mode == 0) {
561                 dm->getVertNo(dm, mface->v1, data[0]);
562                 dm->getVertNo(dm, mface->v2, data[1]);
563                 dm->getVertNo(dm, mface->v3, data[2]);
564                 dm->getVertNo(dm, mface->v4, data[3]);
565         } else {
566                 dm->getVertCo(dm, mface->v1, data[0]);
567                 dm->getVertCo(dm, mface->v2, data[1]);
568                 dm->getVertCo(dm, mface->v3, data[2]);
569                 dm->getVertCo(dm, mface->v4, data[3]);
570         }
571
572         interp_bilinear_quad_data(data, u, v, res);
573 }
574
575 /* mode = 0: interpolate normals,
576    mode = 1: interpolate coord */
577 static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3])
578 {
579         float data[3][3];
580
581         if(mode == 0) {
582                 dm->getVertNo(dm, mface->v1, data[0]);
583                 dm->getVertNo(dm, mface->v2, data[1]);
584                 dm->getVertNo(dm, mface->v3, data[2]);
585         } else {
586                 dm->getVertCo(dm, mface->v1, data[0]);
587                 dm->getVertCo(dm, mface->v2, data[1]);
588                 dm->getVertCo(dm, mface->v3, data[2]);
589         }
590
591         interp_barycentric_tri_data(data, u, v, res);
592 }
593
594 static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
595 {
596         MHeightBakeData *height_data;
597         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
598         DerivedMesh *lodm= bkr->lores_dm;
599
600         height_data= MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
601
602         height_data->ima= ima;
603         height_data->heights= MEM_callocN(sizeof(float)*ibuf->x*ibuf->y, "MultiresBake heights");
604         height_data->height_max= -FLT_MAX;
605         height_data->height_min= FLT_MAX;
606
607         if(!bkr->use_lores_mesh) {
608                 SubsurfModifierData smd= {{NULL}};
609                 int ss_lvl= bkr->tot_lvl - bkr->lvl;
610
611                 CLAMP(ss_lvl, 0, 6);
612
613                 smd.levels= smd.renderLevels= ss_lvl;
614                 smd.flags|= eSubsurfModifierFlag_SubsurfUv;
615
616                 if(bkr->simple)
617                         smd.subdivType= ME_SIMPLE_SUBSURF;
618
619                 height_data->ssdm= subsurf_make_derived_from_derived(bkr->lores_dm, &smd, 0, NULL, 0, 0, 0);
620         }
621
622         height_data->origindex= lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
623
624         return (void*)height_data;
625 }
626
627 static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
628 {
629         MNormalBakeData *normal_data;
630         DerivedMesh *lodm= bkr->lores_dm;
631
632         normal_data= MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData");
633
634         normal_data->origindex= lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
635
636         return (void*)normal_data;
637 }
638
639 static void free_normal_data(void *bake_data)
640 {
641         MNormalBakeData *normal_data= (MNormalBakeData*)bake_data;
642
643         MEM_freeN(normal_data);
644 }
645
646 static void apply_heights_data(void *bake_data)
647 {
648         MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
649         ImBuf *ibuf= BKE_image_get_ibuf(height_data->ima, NULL);
650         int x, y, i;
651         float height, *heights= height_data->heights;
652         float min= height_data->height_min, max= height_data->height_max;
653
654         for(x= 0; x<ibuf->x; x++) {
655                 for(y =0; y<ibuf->y; y++) {
656                         i= ibuf->x*y + x;
657
658                         if(((char*)ibuf->userdata)[i] != FILTER_MASK_USED)
659                                 continue;
660
661                         if(ibuf->rect_float) {
662                                 float *rrgbf= ibuf->rect_float + i*4;
663
664                                 if(max-min > 1e-5f) height= (heights[i]-min)/(max-min);
665                                 else height= 0;
666
667                                 rrgbf[0]=rrgbf[1]=rrgbf[2]= height;
668                         } else {
669                                 char *rrgb= (char*)ibuf->rect + i*4;
670
671                                 if(max-min > 1e-5f) height= (heights[i]-min)/(max-min);
672                                 else height= 0;
673
674                                 rrgb[0]=rrgb[1]=rrgb[2]= FTOCHAR(height);
675                         }
676                 }
677         }
678
679         ibuf->userflags= IB_RECT_INVALID;
680 }
681
682 static void free_heights_data(void *bake_data)
683 {
684         MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
685
686         if(height_data->ssdm)
687                 height_data->ssdm->release(height_data->ssdm);
688
689         MEM_freeN(height_data->heights);
690         MEM_freeN(height_data);
691 }
692
693 /* MultiresBake callback for heights baking
694    general idea:
695      - find coord of point with specified UV in hi-res mesh (let's call it p1)
696      - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res
697        mesh to make texture smoother) let's call this point p0 and n.
698      - height wound be dot(n, p1-p0) */
699 static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
700                                    const int face_index, const int lvl, const float st[2],
701                                    float UNUSED(tangmat[3][3]), const int x, const int y)
702 {
703         MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
704         MFace mface;
705         Image *ima= mtface[face_index].tpage;
706         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
707         MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
708         float uv[2], *st0, *st1, *st2, *st3;
709         int pixel= ibuf->x*y + x;
710         float vec[3], p0[3], p1[3], n[3], len;
711
712         lores_dm->getTessFace(lores_dm, face_index, &mface);
713
714         st0= mtface[face_index].uv[0];
715         st1= mtface[face_index].uv[1];
716         st2= mtface[face_index].uv[2];
717
718         if(mface.v4) {
719                 st3= mtface[face_index].uv[3];
720                 resolve_quad_uv(uv, st, st0, st1, st2, st3);
721         } else
722                 resolve_tri_uv(uv, st, st0, st1, st2);
723
724         CLAMP(uv[0], 0.0f, 1.0f);
725         CLAMP(uv[1], 0.0f, 1.0f);
726
727         get_ccgdm_data(lores_dm, hires_dm, height_data->origindex, lvl, face_index, uv[0], uv[1], p1, 0);
728
729         if(height_data->ssdm) {
730                 get_ccgdm_data(lores_dm, height_data->ssdm, height_data->origindex, 0, face_index, uv[0], uv[1], p0, n);
731         } else {
732                 lores_dm->getTessFace(lores_dm, face_index, &mface);
733
734                 if(mface.v4) {
735                         interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
736                         interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
737                 } else {
738                         interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0);
739                         interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n);
740                 }
741         }
742
743         sub_v3_v3v3(vec, p1, p0);
744         len= dot_v3v3(n, vec);
745
746         height_data->heights[pixel]= len;
747         if(len<height_data->height_min) height_data->height_min= len;
748         if(len>height_data->height_max) height_data->height_max= len;
749
750         if(ibuf->rect_float) {
751                 float *rrgbf= ibuf->rect_float + pixel*4;
752                 rrgbf[3]= 1.0f;
753
754                 ibuf->userflags= IB_RECT_INVALID;
755         } else {
756                 char *rrgb= (char*)ibuf->rect + pixel*4;
757                 rrgb[3]= 255;
758         }
759 }
760
761 /* MultiresBake callback for normals' baking
762    general idea:
763      - find coord and normal of point with specified UV in hi-res mesh
764      - multiply it by tangmat
765      - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */
766 static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data,
767                                    const int face_index, const int lvl, const float st[2],
768                                    float tangmat[3][3], const int x, const int y)
769 {
770         MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
771         MFace mface;
772         Image *ima= mtface[face_index].tpage;
773         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
774         MNormalBakeData *normal_data= (MNormalBakeData*)bake_data;
775         float uv[2], *st0, *st1, *st2, *st3;
776         int pixel= ibuf->x*y + x;
777         float n[3], vec[3], tmp[3]= {0.5, 0.5, 0.5};
778
779         lores_dm->getTessFace(lores_dm, face_index, &mface);
780
781         st0= mtface[face_index].uv[0];
782         st1= mtface[face_index].uv[1];
783         st2= mtface[face_index].uv[2];
784
785         if(mface.v4) {
786                 st3= mtface[face_index].uv[3];
787                 resolve_quad_uv(uv, st, st0, st1, st2, st3);
788         } else
789                 resolve_tri_uv(uv, st, st0, st1, st2);
790
791         CLAMP(uv[0], 0.0f, 1.0f);
792         CLAMP(uv[1], 0.0f, 1.0f);
793
794         get_ccgdm_data(lores_dm, hires_dm, normal_data->origindex, lvl, face_index, uv[0], uv[1], NULL, n);
795
796         mul_v3_m3v3(vec, tangmat, n);
797         normalize_v3(vec);
798         mul_v3_fl(vec, 0.5);
799         add_v3_v3(vec, tmp);
800
801         if(ibuf->rect_float) {
802                 float *rrgbf= ibuf->rect_float + pixel*4;
803                 rrgbf[0]= vec[0];
804                 rrgbf[1]= vec[1];
805                 rrgbf[2]= vec[2];
806                 rrgbf[3]= 1.0f;
807
808                 ibuf->userflags= IB_RECT_INVALID;
809         } else {
810                 unsigned char *rrgb= (unsigned char *)ibuf->rect + pixel*4;
811                 rgb_float_to_uchar(rrgb, vec);
812                 rrgb[3]= 255;
813         }
814 }
815
816 static void count_images(MultiresBakeRender *bkr)
817 {
818         int a, totface;
819         DerivedMesh *dm= bkr->lores_dm;
820         MTFace *mtface= CustomData_get_layer(&dm->faceData, CD_MTFACE);
821
822         bkr->image.first= bkr->image.last= NULL;
823         bkr->tot_image= 0;
824
825         totface= dm->getNumTessFaces(dm);
826
827         for(a= 0; a<totface; a++)
828                 mtface[a].tpage->id.flag&= ~LIB_DOIT;
829
830         for(a= 0; a<totface; a++) {
831                 Image *ima= mtface[a].tpage;
832                 if((ima->id.flag&LIB_DOIT)==0) {
833                         LinkData *data= BLI_genericNodeN(ima);
834                         BLI_addtail(&bkr->image, data);
835                         bkr->tot_image++;
836                         ima->id.flag|= LIB_DOIT;
837                 }
838         }
839
840         for(a= 0; a<totface; a++)
841                 mtface[a].tpage->id.flag&= ~LIB_DOIT;
842 }
843
844 static void bake_images(MultiresBakeRender *bkr)
845 {
846         LinkData *link;
847
848         for(link= bkr->image.first; link; link= link->next) {
849                 Image *ima= (Image*)link->data;
850                 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
851
852                 if(ibuf->x>0 && ibuf->y>0) {
853                         ibuf->userdata= MEM_callocN(ibuf->y*ibuf->x, "MultiresBake imbuf mask");
854
855                         switch(bkr->mode) {
856                                 case RE_BAKE_NORMALS:
857                                         do_multires_bake(bkr, ima, apply_tangmat_callback, init_normal_data, NULL, free_normal_data);
858                                         break;
859                                 case RE_BAKE_DISPLACEMENT:
860                                         do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data,
861                                                          apply_heights_data, free_heights_data);
862                                         break;
863                         }
864                 }
865
866                 ima->id.flag|= LIB_DOIT;
867         }
868 }
869
870 static void finish_images(MultiresBakeRender *bkr)
871 {
872         LinkData *link;
873
874         for(link= bkr->image.first; link; link= link->next) {
875                 Image *ima= (Image*)link->data;
876                 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
877
878                 if(ibuf->x<=0 || ibuf->y<=0)
879                         continue;
880
881                 RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter);
882
883                 ibuf->userflags|= IB_BITMAPDIRTY;
884
885                 if(ibuf->rect_float)
886                         ibuf->userflags|= IB_RECT_INVALID;
887
888                 if(ibuf->mipmap[0]) {
889                         ibuf->userflags|= IB_MIPMAP_INVALID;
890                         imb_freemipmapImBuf(ibuf);
891                 }
892
893                 if(ibuf->userdata) {
894                         MEM_freeN(ibuf->userdata);
895                         ibuf->userdata= NULL;
896                 }
897         }
898 }
899
900 static void multiresbake_start(MultiresBakeRender *bkr)
901 {
902         count_images(bkr);
903         bake_images(bkr);
904         finish_images(bkr);
905 }
906
907 static int multiresbake_check(bContext *C, wmOperator *op)
908 {
909         Scene *scene= CTX_data_scene(C);
910         Object *ob;
911         Mesh *me;
912         MultiresModifierData *mmd;
913         int ok= 1, a;
914
915         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
916                 ob= base->object;
917
918                 if(ob->type != OB_MESH) {
919                         BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh");
920
921                         ok= 0;
922                         break;
923                 }
924
925                 me= (Mesh*)ob->data;
926                 mmd= get_multires_modifier(scene, ob, 0);
927
928                 /* Multi-resolution should be and be last in the stack */
929                 if(ok && mmd) {
930                         ModifierData *md;
931
932                         ok= mmd->totlvl>0;
933
934                         for(md = (ModifierData*)mmd->modifier.next; md && ok; md = md->next) {
935                                 if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) {
936                                         ok= 0;
937                                 }
938                         }
939                 } else ok= 0;
940
941                 if(!ok) {
942                         BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object");
943
944                         break;
945                 }
946
947                 if(!me->mtface) {
948                         BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");
949
950                         ok= 0;
951                 } else {
952                         /* BMESH_TODO - use MPoly rather then tessface */
953                         a= me->totface;
954                         while (ok && a--) {
955                                 Image *ima= me->mtface[a].tpage;
956
957                                 if(!ima) {
958                                         BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker");
959
960                                         ok= 0;
961                                 } else {
962                                         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
963
964                                         if(!ibuf) {
965                                                 BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer");
966
967                                                 ok= 0;
968                                         } else {
969                                                 if(ibuf->rect==NULL && ibuf->rect_float==NULL)
970                                                         ok= 0;
971
972                                                 if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
973                                                         ok= 0;
974
975                                                 if(!ok)
976                                                         BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
977                                         }
978                                 }
979                         }
980                 }
981
982                 if(!ok)
983                         break;
984         }
985         CTX_DATA_END;
986
987         return ok;
988 }
989
990 static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl)
991 {
992         DerivedMesh *dm;
993         MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
994         Mesh *me= (Mesh*)ob->data;
995
996         *lvl= mmd->lvl;
997
998         if(*lvl==0) {
999                 DerivedMesh *tmp_dm= CDDM_from_mesh(me, ob);
1000                 dm= CDDM_copy(tmp_dm);
1001                 tmp_dm->release(tmp_dm);
1002         } else {
1003                 MultiresModifierData tmp_mmd= *mmd;
1004                 DerivedMesh *cddm= CDDM_from_mesh(me, ob);
1005
1006                 tmp_mmd.lvl= *lvl;
1007                 tmp_mmd.sculptlvl= *lvl;
1008                 dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0);
1009                 cddm->release(cddm);
1010         }
1011
1012         return dm;
1013 }
1014
1015 static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, int *simple)
1016 {
1017         Mesh *me= (Mesh*)ob->data;
1018         MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
1019         MultiresModifierData tmp_mmd= *mmd;
1020         DerivedMesh *cddm= CDDM_from_mesh(me, ob);
1021         DerivedMesh *dm;
1022
1023         *lvl= mmd->totlvl;
1024         *simple= mmd->simple;
1025
1026         tmp_mmd.lvl= mmd->totlvl;
1027         tmp_mmd.sculptlvl= mmd->totlvl;
1028         dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0);
1029         cddm->release(cddm);
1030
1031         return dm;
1032 }
1033
1034 static void clear_images(MTFace *mtface, int totface)
1035 {
1036         int a;
1037         const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f};
1038         const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f};
1039
1040         for(a= 0; a<totface; a++)
1041                 mtface[a].tpage->id.flag&= ~LIB_DOIT;
1042
1043         for(a= 0; a<totface; a++) {
1044                 Image *ima= mtface[a].tpage;
1045
1046                 if((ima->id.flag&LIB_DOIT)==0) {
1047                         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1048
1049                         IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
1050                         ima->id.flag|= LIB_DOIT;
1051                 }
1052         }
1053
1054         for(a= 0; a<totface; a++)
1055                 mtface[a].tpage->id.flag&= ~LIB_DOIT;
1056 }
1057
1058 static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
1059 {
1060         Object *ob;
1061         Scene *scene= CTX_data_scene(C);
1062         int objects_baked= 0;
1063
1064         if(!multiresbake_check(C, op))
1065                 return OPERATOR_CANCELLED;
1066
1067         if(scene->r.bake_flag&R_BAKE_CLEAR) {  /* clear images */
1068                 CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
1069                         Mesh *me;
1070
1071                         ob= base->object;
1072                         me= (Mesh*)ob->data;
1073
1074                         clear_images(me->mtface, me->totface);
1075                 }
1076                 CTX_DATA_END;
1077         }
1078
1079         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
1080                 MultiresBakeRender bkr= {0};
1081
1082                 ob= base->object;
1083
1084                 multires_force_update(ob);
1085
1086                 /* copy data stored in job descriptor */
1087                 bkr.bake_filter= scene->r.bake_filter;
1088                 bkr.mode= scene->r.bake_mode;
1089                 bkr.use_lores_mesh= scene->r.bake_flag&R_BAKE_LORES_MESH;
1090
1091                 /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
1092                 bkr.lores_dm= multiresbake_create_loresdm(scene, ob, &bkr.lvl);
1093
1094                 if(!bkr.lores_dm)
1095                         continue;
1096
1097                 bkr.hires_dm= multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
1098
1099                 multiresbake_start(&bkr);
1100
1101                 BLI_freelistN(&bkr.image);
1102
1103                 bkr.lores_dm->release(bkr.lores_dm);
1104                 bkr.hires_dm->release(bkr.hires_dm);
1105
1106                 objects_baked++;
1107         }
1108         CTX_DATA_END;
1109
1110         if(!objects_baked)
1111                 BKE_report(op->reports, RPT_ERROR, "No objects found to bake from");
1112
1113         return OPERATOR_FINISHED;
1114 }
1115
1116 /* Multiresbake adopted for job-system executing */
1117 static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
1118 {
1119         Scene *scene= CTX_data_scene(C);
1120         Object *ob;
1121
1122         /* backup scene settings, so their changing in UI would take no effect on baker */
1123         bkj->bake_filter= scene->r.bake_filter;
1124         bkj->mode= scene->r.bake_mode;
1125         bkj->use_lores_mesh= scene->r.bake_flag&R_BAKE_LORES_MESH;
1126         bkj->bake_clear= scene->r.bake_flag&R_BAKE_CLEAR;
1127
1128         CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
1129                 MultiresBakerJobData *data;
1130                 DerivedMesh *lores_dm;
1131                 int lvl;
1132                 ob= base->object;
1133
1134                 multires_force_update(ob);
1135
1136                 lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
1137                 if(!lores_dm)
1138                         continue;
1139
1140                 data= MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data");
1141                 data->lores_dm = lores_dm;
1142                 data->lvl = lvl;
1143                 data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
1144
1145                 BLI_addtail(&bkj->data, data);
1146         }
1147         CTX_DATA_END;
1148 }
1149
1150 static void multiresbake_startjob(void *bkv, short *stop, short *do_update, float *progress)
1151 {
1152         MultiresBakerJobData *data;
1153         MultiresBakeJob *bkj= bkv;
1154         int baked_objects= 0, tot_obj;
1155
1156         tot_obj= BLI_countlist(&bkj->data);
1157
1158         if(bkj->bake_clear) {  /* clear images */
1159                 for(data= bkj->data.first; data; data= data->next) {
1160                         DerivedMesh *dm= data->lores_dm;
1161                         MTFace *mtface= CustomData_get_layer(&dm->faceData, CD_MTFACE);
1162
1163                         clear_images(mtface, dm->getNumTessFaces(dm));
1164                 }
1165         }
1166
1167         for(data= bkj->data.first; data; data= data->next) {
1168                 MultiresBakeRender bkr= {0};
1169
1170                 /* copy data stored in job descriptor */
1171                 bkr.bake_filter= bkj->bake_filter;
1172                 bkr.mode= bkj->mode;
1173                 bkr.use_lores_mesh= bkj->use_lores_mesh;
1174
1175                 /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
1176                 bkr.lores_dm= data->lores_dm;
1177                 bkr.hires_dm= data->hires_dm;
1178                 bkr.tot_lvl= data->tot_lvl;
1179                 bkr.lvl= data->lvl;
1180                 bkr.simple= data->simple;
1181
1182                 /* needed for proper progress bar */
1183                 bkr.tot_obj= tot_obj;
1184                 bkr.baked_objects= baked_objects;
1185
1186                 bkr.stop= stop;
1187                 bkr.do_update= do_update;
1188                 bkr.progress= progress;
1189
1190                 multiresbake_start(&bkr);
1191
1192                 BLI_freelistN(&bkr.image);
1193
1194                 baked_objects++;
1195         }
1196 }
1197
1198 static void multiresbake_freejob(void *bkv)
1199 {
1200         MultiresBakeJob *bkj= bkv;
1201         MultiresBakerJobData *data, *next;
1202
1203         data= bkj->data.first;
1204         while (data) {
1205                 next= data->next;
1206                 data->lores_dm->release(data->lores_dm);
1207                 data->hires_dm->release(data->hires_dm);
1208                 MEM_freeN(data);
1209                 data= next;
1210         }
1211
1212         MEM_freeN(bkj);
1213 }
1214
1215 static int multiresbake_image_exec(bContext *C, wmOperator *op)
1216 {
1217         Scene *scene= CTX_data_scene(C);
1218         MultiresBakeJob *bkr;
1219         wmJob *steve;
1220
1221         if(!multiresbake_check(C, op))
1222                 return OPERATOR_CANCELLED;
1223
1224         bkr= MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data");
1225         init_multiresbake_job(C, bkr);
1226
1227         if(!bkr->data.first) {
1228                 BKE_report(op->reports, RPT_ERROR, "No objects found to bake from");
1229                 return OPERATOR_CANCELLED;
1230         }
1231
1232         /* setup job */
1233         steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Multires Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
1234         WM_jobs_customdata(steve, bkr, multiresbake_freejob);
1235         WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
1236         WM_jobs_callbacks(steve, multiresbake_startjob, NULL, NULL, NULL);
1237
1238         G.afbreek= 0;
1239
1240         WM_jobs_start(CTX_wm_manager(C), steve);
1241         WM_cursor_wait(0);
1242
1243         /* add modal handler for ESC */
1244         WM_event_add_modal_handler(C, op);
1245
1246         return OPERATOR_RUNNING_MODAL;
1247 }
1248
1249 /* ****************** render BAKING ********************** */
1250
1251 /* threaded break test */
1252 static int thread_break(void *UNUSED(arg))
1253 {
1254         return G.afbreek;
1255 }
1256
1257 typedef struct BakeRender {
1258         Render *re;
1259         Main *main;
1260         Scene *scene;
1261         struct Object *actob;
1262         int result, ready;
1263
1264         ReportList *reports;
1265
1266         short *stop;
1267         short *do_update;
1268         float *progress;
1269         
1270         ListBase threads;
1271
1272         /* backup */
1273         short prev_wo_amb_occ;
1274         short prev_r_raytrace;
1275
1276         /* for redrawing */
1277         ScrArea *sa;
1278 } BakeRender;
1279
1280 /* use by exec and invoke */
1281 static int test_bake_internal(bContext *C, ReportList *reports)
1282 {
1283         Scene *scene= CTX_data_scene(C);
1284
1285         if((scene->r.bake_flag & R_BAKE_TO_ACTIVE) && CTX_data_active_object(C)==NULL) {
1286                 BKE_report(reports, RPT_ERROR, "No active object");
1287         }
1288         else if(scene->r.bake_mode==RE_BAKE_AO && scene->world==NULL) {
1289                 BKE_report(reports, RPT_ERROR, "No world set up");
1290         }
1291         else {
1292                 return 1;
1293         }
1294
1295         return 0;
1296 }
1297
1298 static void init_bake_internal(BakeRender *bkr, bContext *C)
1299 {
1300         Scene *scene= CTX_data_scene(C);
1301
1302         /* get editmode results */
1303         ED_object_exit_editmode(C, 0);  /* 0 = does not exit editmode */
1304
1305         bkr->sa= BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_IMAGE, 10); /* can be NULL */
1306         bkr->main= CTX_data_main(C);
1307         bkr->scene= scene;
1308         bkr->actob= (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL;
1309         bkr->re= RE_NewRender("_Bake View_");
1310
1311         if(scene->r.bake_mode==RE_BAKE_AO) {
1312                 /* If raytracing or AO is disabled, switch it on temporarily for baking. */
1313                 bkr->prev_wo_amb_occ = (scene->world->mode & WO_AMB_OCC) != 0;
1314                 scene->world->mode |= WO_AMB_OCC;
1315         }
1316         if(scene->r.bake_mode==RE_BAKE_AO || bkr->actob) {
1317                 bkr->prev_r_raytrace = (scene->r.mode & R_RAYTRACE) != 0;
1318                 scene->r.mode |= R_RAYTRACE;
1319         }
1320 }
1321
1322 static void finish_bake_internal(BakeRender *bkr)
1323 {
1324         RE_Database_Free(bkr->re);
1325
1326         /* restore raytrace and AO */
1327         if(bkr->scene->r.bake_mode==RE_BAKE_AO)
1328                 if(bkr->prev_wo_amb_occ == 0)
1329                         bkr->scene->world->mode &= ~WO_AMB_OCC;
1330
1331         if(bkr->scene->r.bake_mode==RE_BAKE_AO || bkr->actob)
1332                 if(bkr->prev_r_raytrace == 0)
1333                         bkr->scene->r.mode &= ~R_RAYTRACE;
1334
1335         if(bkr->result==BAKE_RESULT_OK) {
1336                 Image *ima;
1337                 /* force OpenGL reload and mipmap recalc */
1338                 for(ima= G.main->image.first; ima; ima= ima->id.next) {
1339                         if(ima->ok==IMA_OK_LOADED) {
1340                                 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1341                                 if(ibuf) {
1342                                         if(ibuf->userflags & IB_BITMAPDIRTY) {
1343                                                 GPU_free_image(ima);
1344                                                 imb_freemipmapImBuf(ibuf);
1345                                         }
1346
1347                                         /* freed when baking is done, but if its canceled we need to free here */
1348                                         if (ibuf->userdata) {
1349                                                 MEM_freeN(ibuf->userdata);
1350                                                 ibuf->userdata= NULL;
1351                                         }
1352                                 }
1353                         }
1354                 }
1355         }
1356 }
1357
1358 static void *do_bake_render(void *bake_v)
1359 {
1360         BakeRender *bkr= bake_v;
1361
1362         bkr->result= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress);
1363         bkr->ready= 1;
1364
1365         return NULL;
1366 }
1367
1368 static void bake_startjob(void *bkv, short *stop, short *do_update, float *progress)
1369 {
1370         BakeRender *bkr= bkv;
1371         Scene *scene= bkr->scene;
1372         Main *bmain= bkr->main;
1373
1374         bkr->stop= stop;
1375         bkr->do_update= do_update;
1376         bkr->progress= progress;
1377
1378         RE_test_break_cb(bkr->re, NULL, thread_break);
1379         G.afbreek= 0;   /* blender_test_break uses this global */
1380
1381         RE_Database_Baking(bkr->re, bmain, scene, scene->lay, scene->r.bake_mode, bkr->actob);
1382
1383         /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
1384         bkr->result= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress);
1385 }
1386
1387 static void bake_update(void *bkv)
1388 {
1389         BakeRender *bkr= bkv;
1390
1391         if(bkr->sa && bkr->sa->spacetype==SPACE_IMAGE) { /* incase the user changed while baking */
1392                 SpaceImage *sima= bkr->sa->spacedata.first;
1393                 if(sima)
1394                         sima->image= RE_bake_shade_get_image();
1395         }
1396 }
1397
1398 static void bake_freejob(void *bkv)
1399 {
1400         BakeRender *bkr= bkv;
1401         finish_bake_internal(bkr);
1402
1403         if(bkr->result==BAKE_RESULT_NO_OBJECTS)
1404                 BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to");
1405         else if(bkr->result==BAKE_RESULT_FEEDBACK_LOOP)
1406                 BKE_report(bkr->reports, RPT_WARNING, "Feedback loop detected");
1407
1408         MEM_freeN(bkr);
1409         G.rendering = 0;
1410 }
1411
1412 /* catch esc */
1413 static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
1414 {
1415         /* no running blender, remove handler and pass through */
1416         if(0==WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C)))
1417                 return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
1418
1419         /* running render */
1420         switch (event->type) {
1421                 case ESCKEY:
1422                         return OPERATOR_RUNNING_MODAL;
1423                         break;
1424         }
1425         return OPERATOR_PASS_THROUGH;
1426 }
1427
1428 static int is_multires_bake(Scene *scene)
1429 {
1430         if ( ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT))
1431                 return scene->r.bake_flag & R_BAKE_MULTIRES;
1432
1433         return 0;
1434 }
1435
1436 static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(_event))
1437 {
1438         Scene *scene= CTX_data_scene(C);
1439         int result= OPERATOR_CANCELLED;
1440
1441         if(is_multires_bake(scene)) {
1442                 result= multiresbake_image_exec(C, op);
1443         } else {
1444                 /* only one render job at a time */
1445                 if(WM_jobs_test(CTX_wm_manager(C), scene))
1446                         return OPERATOR_CANCELLED;
1447
1448                 if(test_bake_internal(C, op->reports)==0) {
1449                         return OPERATOR_CANCELLED;
1450                 }
1451                 else {
1452                         BakeRender *bkr= MEM_callocN(sizeof(BakeRender), "render bake");
1453                         wmJob *steve;
1454
1455                         init_bake_internal(bkr, C);
1456                         bkr->reports= op->reports;
1457
1458                         /* setup job */
1459                         steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
1460                         WM_jobs_customdata(steve, bkr, bake_freejob);
1461                         WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
1462                         WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL);
1463
1464                         G.afbreek= 0;
1465                         G.rendering = 1;
1466
1467                         WM_jobs_start(CTX_wm_manager(C), steve);
1468
1469                         WM_cursor_wait(0);
1470
1471                         /* add modal handler for ESC */
1472                         WM_event_add_modal_handler(C, op);
1473                 }
1474
1475                 result= OPERATOR_RUNNING_MODAL;
1476         }
1477
1478         WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
1479
1480         return result;
1481 }
1482
1483
1484 static int bake_image_exec(bContext *C, wmOperator *op)
1485 {
1486         Main *bmain= CTX_data_main(C);
1487         Scene *scene= CTX_data_scene(C);
1488         int result= OPERATOR_CANCELLED;
1489
1490         if(is_multires_bake(scene)) {
1491                 result= multiresbake_image_exec_locked(C, op);
1492         } else  {
1493                 if(test_bake_internal(C, op->reports)==0) {
1494                         return OPERATOR_CANCELLED;
1495                 }
1496                 else {
1497                         ListBase threads;
1498                         BakeRender bkr= {NULL};
1499
1500                         init_bake_internal(&bkr, C);
1501                         bkr.reports= op->reports;
1502
1503                         RE_test_break_cb(bkr.re, NULL, thread_break);
1504                         G.afbreek= 0;   /* blender_test_break uses this global */
1505
1506                         RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL);
1507
1508                         /* baking itself is threaded, cannot use test_break in threads  */
1509                         BLI_init_threads(&threads, do_bake_render, 1);
1510                         bkr.ready= 0;
1511                         BLI_insert_thread(&threads, &bkr);
1512
1513                         while(bkr.ready==0) {
1514                                 PIL_sleep_ms(50);
1515                                 if(bkr.ready)
1516                                         break;
1517
1518                                 /* used to redraw in 2.4x but this is just for exec in 2.5 */
1519                                 if (!G.background)
1520                                         blender_test_break();
1521                         }
1522                         BLI_end_threads(&threads);
1523
1524                         if(bkr.result==BAKE_RESULT_NO_OBJECTS)
1525                                 BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to");
1526                         else if(bkr.result==BAKE_RESULT_FEEDBACK_LOOP)
1527                                 BKE_report(op->reports, RPT_ERROR, "Feedback loop detected");
1528
1529                         finish_bake_internal(&bkr);
1530
1531                         result= OPERATOR_FINISHED;
1532                 }
1533         }
1534
1535         WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
1536
1537         return result;
1538 }
1539
1540 void OBJECT_OT_bake_image(wmOperatorType *ot)
1541 {
1542         /* identifiers */
1543         ot->name= "Bake";
1544         ot->description= "Bake image textures of selected objects";
1545         ot->idname= "OBJECT_OT_bake_image";
1546
1547         /* api callbacks */
1548         ot->exec= bake_image_exec;
1549         ot->invoke= objects_bake_render_invoke;
1550         ot->modal= objects_bake_render_modal;
1551 }