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