2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2004 by Blender Foundation
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): Morten Mikkelsen,
26 * ***** END GPL LICENSE BLOCK *****
29 /** \file blender/editors/object/object_bake.c
35 meshtools.c: no editmode (violated already :), tools operating on meshes
40 #include "MEM_guardedalloc.h"
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"
50 #include "BLI_blenlib.h"
51 #include "BLI_threads.h"
52 #include "BLI_utildefines.h"
54 #include "BLI_math_geom.h"
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"
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"
69 #include "RE_pipeline.h"
70 #include "RE_shader_ext.h"
74 #include "IMB_imbuf_types.h"
75 #include "IMB_imbuf.h"
77 #include "GPU_draw.h" /* GPU_free_image */
82 #include "ED_object.h"
84 #include "object_intern.h"
86 /* ****************** multires BAKING ********************** */
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;
96 /* data passing to multires-baker job */
99 int bake_clear, bake_filter;
100 short mode, use_lores_mesh;
103 /* data passing to multires baker */
105 DerivedMesh *lores_dm, *hires_dm;
106 int simple, lvl, tot_lvl, bake_filter;
107 short mode, use_lores_mesh;
109 int tot_obj, tot_image;
112 int baked_objects, baked_faces;
117 } MultiresBakeRender;
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);
123 typedef void* (*MInitBakeData)(MultiresBakeRender *bkr, Image* ima);
124 typedef void (*MApplyBakeData)(void *bake_data);
125 typedef void (*MFreeBakeData)(void *bake_data);
132 float *precomputed_normals;
136 DerivedMesh *lores_dm, *hires_dm;
139 MPassKnownData pass_data;
142 typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y);
147 const MResolvePixelData *data;
148 MFlushPixel flush_pixel;
153 float height_min, height_max;
156 const int *origindex;
160 const int *origindex;
163 static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index)
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);
169 if(!smoothnormal) { /* flat */
170 if(data->precomputed_normals) {
171 copy_v3_v3(norm, &data->precomputed_normals[3*face_num]);
175 const int iGetNrVerts= data->mface[face_num].v4!=0 ? 4 : 3;
177 p0= data->mvert[indices[0]].co;
178 p1= data->mvert[indices[1]].co;
179 p2= data->mvert[indices[2]].co;
182 float *p3= data->mvert[indices[3]].co;
183 normal_quad_v3(nor, p0, p1, p2, p3);
185 normal_tri_v3(nor, p0, p1, p2);
188 copy_v3_v3(norm, nor);
191 short *no= data->mvert[indices[vert_index]].no;
193 normal_short_to_float_v3(norm, no);
198 static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel)
200 memset(bake_rast, 0, sizeof(MBakeRast));
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;
209 static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
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];
219 const int i0= data->i0;
220 const int i1= data->i1;
221 const int i2= data->i2;
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];
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;
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);
235 resolve_tri_uv(fUV, st, st0, st1, st2);
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;
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;
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);
257 data->pass_data(data->lores_dm, data->hires_dm, data->bake_data,
258 data->face_index, data->lvl, st, to_tang, x, y);
261 static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y)
263 const int w= bake_rast->w;
264 const int h= bake_rast->h;
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;
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)
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;
285 if(y1_in<=0 || y0_in>=h)
288 y0= y0_in<0 ? 0 : y0_in;
289 y1= y1_in>=h ? h : y1_in;
291 for(y= y0; y<y1; y++) {
292 /*-b(x-x0) + a(y-y0) = 0 */
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;
298 SWAP(float, x_l, x_r);
300 iXl= (int)ceilf(x_l);
301 iXr= (int)ceilf(x_r);
307 for(x= iXl; x<iXr; x++)
308 set_rast_triangle(bake_rast, x, y);
313 static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2])
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;
325 /* skip degenerates */
326 if((slo==smi && tlo==tmi) || (slo==shi && tlo==thi) || (smi==shi && tmi==thi))
330 if(tlo>tmi && tlo>thi) {
331 SWAP(float, shi, slo);
332 SWAP(float, thi, tlo);
334 SWAP(float, shi, smi);
335 SWAP(float, thi, tmi);
339 SWAP(float, slo, smi);
340 SWAP(float, tlo, tmi);
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);
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);
354 static int multiresbake_test_break(MultiresBakeRender *bkr)
357 /* this means baker is executed outside from job system */
364 static void do_multires_bake(MultiresBakeRender *bkr, Image* ima, MPassKnownData passKnownData,
365 MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData)
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;
376 if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1)
377 DM_add_tangent_layer(dm);
379 pvtangent= DM_get_tessface_data_layer(dm, CD_TANGENT);
381 if(tot_face > 0) { /* sanity check */
384 MResolvePixelData data={NULL};
389 data.pvtangent= pvtangent;
390 data.precomputed_normals= dm->getTessFaceDataArray(dm, CD_NORMAL); /* don't strictly need this */
394 data.hires_dm= bkr->hires_dm;
396 data.pass_data= passKnownData;
399 data.bake_data= initBakeData(bkr, ima);
401 init_bake_rast(&bake_rast, ibuf, &data, flush_pixel);
403 for(f= 0; f<tot_face; f++) {
404 MTFace *mtfate= &mtface[f];
405 int verts[3][2], nr_tris, t;
407 if(multiresbake_test_break(bkr))
410 if(mtfate->tpage!=ima)
415 /* might support other forms of diagonal splits later on such as
416 split by shortest diagonal.*/
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];
431 bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]);
440 *bkr->progress= ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj;
444 applyBakeData(data.bake_data);
447 freeBakeData(data.bake_data);
451 static void interp_bilinear_quad_data(float data[4][3], float u, float v, float res[3])
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);
465 static void interp_barycentric_tri_data(float data[3][3], float u, float v, float res[3])
469 copy_v3_v3(res, data[0]);
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);
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])
486 x1= x0>=(grid_size-1) ? (grid_size-1) : (x0+1);
489 y1= y0>=(grid_size-1) ? (grid_size-1) : (y0+1);
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);
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);
506 interp_bilinear_quad_data(data, u, v, res);
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])
512 DMGridData **grid_data;
514 int grid_size, S, face_side;
515 int *grid_offset, g_index;
517 lodm->getTessFace(lodm, face_index, &mface);
519 grid_size= hidm->getGridSize(hidm);
520 grid_data= hidm->getGridData(hidm);
521 grid_offset= hidm->getGridOffset(hidm);
523 face_side= (grid_size<<1)-1;
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);
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);
537 S= face_index / (1<<(2*(lvl-1))) - grid_offset[grid_index];
538 g_index= grid_offset[grid_index];
540 crn_y= (row * cell_side) + u * cell_side;
541 crn_x= (col * cell_side) + v * cell_side;
544 CLAMP(crn_x, 0.0f, grid_size);
545 CLAMP(crn_y, 0.0f, grid_size);
548 interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 0, n);
551 interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 1, co);
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])
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]);
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]);
572 interp_bilinear_quad_data(data, u, v, res);
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])
582 dm->getVertNo(dm, mface->v1, data[0]);
583 dm->getVertNo(dm, mface->v2, data[1]);
584 dm->getVertNo(dm, mface->v3, data[2]);
586 dm->getVertCo(dm, mface->v1, data[0]);
587 dm->getVertCo(dm, mface->v2, data[1]);
588 dm->getVertCo(dm, mface->v3, data[2]);
591 interp_barycentric_tri_data(data, u, v, res);
594 static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
596 MHeightBakeData *height_data;
597 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
598 DerivedMesh *lodm= bkr->lores_dm;
600 height_data= MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
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;
607 if(!bkr->use_lores_mesh) {
608 SubsurfModifierData smd= {{NULL}};
609 int ss_lvl= bkr->tot_lvl - bkr->lvl;
613 smd.levels= smd.renderLevels= ss_lvl;
614 smd.flags|= eSubsurfModifierFlag_SubsurfUv;
617 smd.subdivType= ME_SIMPLE_SUBSURF;
619 height_data->ssdm= subsurf_make_derived_from_derived(bkr->lores_dm, &smd, 0, NULL, 0, 0, 0);
622 height_data->origindex= lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
624 return (void*)height_data;
627 static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
629 MNormalBakeData *normal_data;
630 DerivedMesh *lodm= bkr->lores_dm;
632 normal_data= MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData");
634 normal_data->origindex= lodm->getTessFaceDataArray(lodm, CD_ORIGINDEX);
636 return (void*)normal_data;
639 static void free_normal_data(void *bake_data)
641 MNormalBakeData *normal_data= (MNormalBakeData*)bake_data;
643 MEM_freeN(normal_data);
646 static void apply_heights_data(void *bake_data)
648 MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
649 ImBuf *ibuf= BKE_image_get_ibuf(height_data->ima, NULL);
651 float height, *heights= height_data->heights;
652 float min= height_data->height_min, max= height_data->height_max;
654 for(x= 0; x<ibuf->x; x++) {
655 for(y =0; y<ibuf->y; y++) {
658 if(((char*)ibuf->userdata)[i] != FILTER_MASK_USED)
661 if(ibuf->rect_float) {
662 float *rrgbf= ibuf->rect_float + i*4;
664 if(max-min > 1e-5f) height= (heights[i]-min)/(max-min);
667 rrgbf[0]=rrgbf[1]=rrgbf[2]= height;
669 char *rrgb= (char*)ibuf->rect + i*4;
671 if(max-min > 1e-5f) height= (heights[i]-min)/(max-min);
674 rrgb[0]=rrgb[1]=rrgb[2]= FTOCHAR(height);
679 ibuf->userflags= IB_RECT_INVALID;
682 static void free_heights_data(void *bake_data)
684 MHeightBakeData *height_data= (MHeightBakeData*)bake_data;
686 if(height_data->ssdm)
687 height_data->ssdm->release(height_data->ssdm);
689 MEM_freeN(height_data->heights);
690 MEM_freeN(height_data);
693 /* MultiresBake callback for heights baking
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)
703 MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
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;
712 lores_dm->getTessFace(lores_dm, face_index, &mface);
714 st0= mtface[face_index].uv[0];
715 st1= mtface[face_index].uv[1];
716 st2= mtface[face_index].uv[2];
719 st3= mtface[face_index].uv[3];
720 resolve_quad_uv(uv, st, st0, st1, st2, st3);
722 resolve_tri_uv(uv, st, st0, st1, st2);
724 CLAMP(uv[0], 0.0f, 1.0f);
725 CLAMP(uv[1], 0.0f, 1.0f);
727 get_ccgdm_data(lores_dm, hires_dm, height_data->origindex, lvl, face_index, uv[0], uv[1], p1, 0);
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);
732 lores_dm->getTessFace(lores_dm, face_index, &mface);
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);
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);
743 sub_v3_v3v3(vec, p1, p0);
744 len= dot_v3v3(n, vec);
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;
750 if(ibuf->rect_float) {
751 float *rrgbf= ibuf->rect_float + pixel*4;
754 ibuf->userflags= IB_RECT_INVALID;
756 char *rrgb= (char*)ibuf->rect + pixel*4;
761 /* MultiresBake callback for normals' baking
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)
770 MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE);
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};
779 lores_dm->getTessFace(lores_dm, face_index, &mface);
781 st0= mtface[face_index].uv[0];
782 st1= mtface[face_index].uv[1];
783 st2= mtface[face_index].uv[2];
786 st3= mtface[face_index].uv[3];
787 resolve_quad_uv(uv, st, st0, st1, st2, st3);
789 resolve_tri_uv(uv, st, st0, st1, st2);
791 CLAMP(uv[0], 0.0f, 1.0f);
792 CLAMP(uv[1], 0.0f, 1.0f);
794 get_ccgdm_data(lores_dm, hires_dm, normal_data->origindex, lvl, face_index, uv[0], uv[1], NULL, n);
796 mul_v3_m3v3(vec, tangmat, n);
801 if(ibuf->rect_float) {
802 float *rrgbf= ibuf->rect_float + pixel*4;
808 ibuf->userflags= IB_RECT_INVALID;
810 unsigned char *rrgb= (unsigned char *)ibuf->rect + pixel*4;
811 rgb_float_to_uchar(rrgb, vec);
816 static void count_images(MultiresBakeRender *bkr)
819 DerivedMesh *dm= bkr->lores_dm;
820 MTFace *mtface= CustomData_get_layer(&dm->faceData, CD_MTFACE);
822 bkr->image.first= bkr->image.last= NULL;
825 totface= dm->getNumTessFaces(dm);
827 for(a= 0; a<totface; a++)
828 mtface[a].tpage->id.flag&= ~LIB_DOIT;
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);
836 ima->id.flag|= LIB_DOIT;
840 for(a= 0; a<totface; a++)
841 mtface[a].tpage->id.flag&= ~LIB_DOIT;
844 static void bake_images(MultiresBakeRender *bkr)
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);
852 if(ibuf->x>0 && ibuf->y>0) {
853 ibuf->userdata= MEM_callocN(ibuf->y*ibuf->x, "MultiresBake imbuf mask");
856 case RE_BAKE_NORMALS:
857 do_multires_bake(bkr, ima, apply_tangmat_callback, init_normal_data, NULL, free_normal_data);
859 case RE_BAKE_DISPLACEMENT:
860 do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data,
861 apply_heights_data, free_heights_data);
866 ima->id.flag|= LIB_DOIT;
870 static void finish_images(MultiresBakeRender *bkr)
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);
878 if(ibuf->x<=0 || ibuf->y<=0)
881 RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter);
883 ibuf->userflags|= IB_BITMAPDIRTY;
886 ibuf->userflags|= IB_RECT_INVALID;
888 if(ibuf->mipmap[0]) {
889 ibuf->userflags|= IB_MIPMAP_INVALID;
890 imb_freemipmapImBuf(ibuf);
894 MEM_freeN(ibuf->userdata);
895 ibuf->userdata= NULL;
900 static void multiresbake_start(MultiresBakeRender *bkr)
907 static int multiresbake_check(bContext *C, wmOperator *op)
909 Scene *scene= CTX_data_scene(C);
912 MultiresModifierData *mmd;
915 CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
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");
926 mmd= get_multires_modifier(scene, ob, 0);
928 /* Multi-resolution should be and be last in the stack */
934 for(md = (ModifierData*)mmd->modifier.next; md && ok; md = md->next) {
935 if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) {
942 BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object");
948 BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");
954 Image *ima= me->mtface[a].tpage;
957 BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker");
961 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
964 BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer");
968 if(ibuf->rect==NULL && ibuf->rect_float==NULL)
971 if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
975 BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
989 static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl)
992 MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
993 Mesh *me= (Mesh*)ob->data;
998 DerivedMesh *tmp_dm= CDDM_from_mesh(me, ob);
999 dm= CDDM_copy(tmp_dm, 0);
1000 tmp_dm->release(tmp_dm);
1002 MultiresModifierData tmp_mmd= *mmd;
1003 DerivedMesh *cddm= CDDM_from_mesh(me, ob);
1006 dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0);
1007 cddm->release(cddm);
1013 static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, int *simple)
1015 Mesh *me= (Mesh*)ob->data;
1016 MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
1017 MultiresModifierData tmp_mmd= *mmd;
1018 DerivedMesh *cddm= CDDM_from_mesh(me, ob);
1022 *simple= mmd->simple;
1024 tmp_mmd.lvl= mmd->totlvl;
1025 tmp_mmd.sculptlvl= mmd->totlvl;
1026 dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0);
1027 cddm->release(cddm);
1032 static void clear_images(MTFace *mtface, int totface)
1035 const float vec_alpha[4]= {0.0f, 0.0f, 0.0f, 0.0f};
1036 const float vec_solid[4]= {0.0f, 0.0f, 0.0f, 1.0f};
1038 for(a= 0; a<totface; a++)
1039 mtface[a].tpage->id.flag&= ~LIB_DOIT;
1041 for(a= 0; a<totface; a++) {
1042 Image *ima= mtface[a].tpage;
1044 if((ima->id.flag&LIB_DOIT)==0) {
1045 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1047 IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid);
1048 ima->id.flag|= LIB_DOIT;
1052 for(a= 0; a<totface; a++)
1053 mtface[a].tpage->id.flag&= ~LIB_DOIT;
1056 static int multiresbake_image_exec_locked(bContext *C, wmOperator *op)
1059 Scene *scene= CTX_data_scene(C);
1060 int objects_baked= 0;
1062 if(!multiresbake_check(C, op))
1063 return OPERATOR_CANCELLED;
1065 if(scene->r.bake_flag&R_BAKE_CLEAR) { /* clear images */
1066 CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
1070 me= (Mesh*)ob->data;
1072 clear_images(me->mtface, me->totface);
1077 CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
1078 MultiresBakeRender bkr= {0};
1082 multires_force_update(ob);
1084 /* copy data stored in job descriptor */
1085 bkr.bake_filter= scene->r.bake_filter;
1086 bkr.mode= scene->r.bake_mode;
1087 bkr.use_lores_mesh= scene->r.bake_flag&R_BAKE_LORES_MESH;
1089 /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
1090 bkr.lores_dm= multiresbake_create_loresdm(scene, ob, &bkr.lvl);
1095 bkr.hires_dm= multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple);
1097 multiresbake_start(&bkr);
1099 BLI_freelistN(&bkr.image);
1101 bkr.lores_dm->release(bkr.lores_dm);
1102 bkr.hires_dm->release(bkr.hires_dm);
1109 BKE_report(op->reports, RPT_ERROR, "No objects found to bake from");
1111 return OPERATOR_FINISHED;
1114 /* Multiresbake adopted for job-system executing */
1115 static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj)
1117 Scene *scene= CTX_data_scene(C);
1120 /* backup scene settings, so their changing in UI would take no effect on baker */
1121 bkj->bake_filter= scene->r.bake_filter;
1122 bkj->mode= scene->r.bake_mode;
1123 bkj->use_lores_mesh= scene->r.bake_flag&R_BAKE_LORES_MESH;
1124 bkj->bake_clear= scene->r.bake_flag&R_BAKE_CLEAR;
1126 CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
1127 MultiresBakerJobData *data;
1128 DerivedMesh *lores_dm;
1132 multires_force_update(ob);
1134 lores_dm = multiresbake_create_loresdm(scene, ob, &lvl);
1138 data= MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data");
1139 data->lores_dm = lores_dm;
1141 data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple);
1143 BLI_addtail(&bkj->data, data);
1148 static void multiresbake_startjob(void *bkv, short *stop, short *do_update, float *progress)
1150 MultiresBakerJobData *data;
1151 MultiresBakeJob *bkj= bkv;
1152 int baked_objects= 0, tot_obj;
1154 tot_obj= BLI_countlist(&bkj->data);
1156 if(bkj->bake_clear) { /* clear images */
1157 for(data= bkj->data.first; data; data= data->next) {
1158 DerivedMesh *dm= data->lores_dm;
1159 MTFace *mtface= CustomData_get_layer(&dm->faceData, CD_MTFACE);
1161 clear_images(mtface, dm->getNumTessFaces(dm));
1165 for(data= bkj->data.first; data; data= data->next) {
1166 MultiresBakeRender bkr= {0};
1168 /* copy data stored in job descriptor */
1169 bkr.bake_filter= bkj->bake_filter;
1170 bkr.mode= bkj->mode;
1171 bkr.use_lores_mesh= bkj->use_lores_mesh;
1173 /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */
1174 bkr.lores_dm= data->lores_dm;
1175 bkr.hires_dm= data->hires_dm;
1176 bkr.tot_lvl= data->tot_lvl;
1178 bkr.simple= data->simple;
1180 /* needed for proper progress bar */
1181 bkr.tot_obj= tot_obj;
1182 bkr.baked_objects= baked_objects;
1185 bkr.do_update= do_update;
1186 bkr.progress= progress;
1188 multiresbake_start(&bkr);
1190 BLI_freelistN(&bkr.image);
1196 static void multiresbake_freejob(void *bkv)
1198 MultiresBakeJob *bkj= bkv;
1199 MultiresBakerJobData *data, *next;
1201 data= bkj->data.first;
1204 data->lores_dm->release(data->lores_dm);
1205 data->hires_dm->release(data->hires_dm);
1213 static int multiresbake_image_exec(bContext *C, wmOperator *op)
1215 Scene *scene= CTX_data_scene(C);
1216 MultiresBakeJob *bkr;
1219 if(!multiresbake_check(C, op))
1220 return OPERATOR_CANCELLED;
1222 bkr= MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data");
1223 init_multiresbake_job(C, bkr);
1225 if(!bkr->data.first) {
1226 BKE_report(op->reports, RPT_ERROR, "No objects found to bake from");
1227 return OPERATOR_CANCELLED;
1231 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);
1232 WM_jobs_customdata(steve, bkr, multiresbake_freejob);
1233 WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
1234 WM_jobs_callbacks(steve, multiresbake_startjob, NULL, NULL, NULL);
1238 WM_jobs_start(CTX_wm_manager(C), steve);
1241 /* add modal handler for ESC */
1242 WM_event_add_modal_handler(C, op);
1244 return OPERATOR_RUNNING_MODAL;
1247 /* ****************** render BAKING ********************** */
1249 /* threaded break test */
1250 static int thread_break(void *UNUSED(arg))
1255 typedef struct BakeRender {
1259 struct Object *actob;
1262 ReportList *reports;
1271 short prev_wo_amb_occ;
1272 short prev_r_raytrace;
1278 /* use by exec and invoke */
1279 static int test_bake_internal(bContext *C, ReportList *reports)
1281 Scene *scene= CTX_data_scene(C);
1283 if((scene->r.bake_flag & R_BAKE_TO_ACTIVE) && CTX_data_active_object(C)==NULL) {
1284 BKE_report(reports, RPT_ERROR, "No active object");
1286 else if(scene->r.bake_mode==RE_BAKE_AO && scene->world==NULL) {
1287 BKE_report(reports, RPT_ERROR, "No world set up");
1296 static void init_bake_internal(BakeRender *bkr, bContext *C)
1298 Scene *scene= CTX_data_scene(C);
1300 /* get editmode results */
1301 ED_object_exit_editmode(C, 0); /* 0 = does not exit editmode */
1303 bkr->sa= BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_IMAGE, 10); /* can be NULL */
1304 bkr->main= CTX_data_main(C);
1306 bkr->actob= (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL;
1307 bkr->re= RE_NewRender("_Bake View_");
1309 if(scene->r.bake_mode==RE_BAKE_AO) {
1310 /* If raytracing or AO is disabled, switch it on temporarily for baking. */
1311 bkr->prev_wo_amb_occ = (scene->world->mode & WO_AMB_OCC) != 0;
1312 scene->world->mode |= WO_AMB_OCC;
1314 if(scene->r.bake_mode==RE_BAKE_AO || bkr->actob) {
1315 bkr->prev_r_raytrace = (scene->r.mode & R_RAYTRACE) != 0;
1316 scene->r.mode |= R_RAYTRACE;
1320 static void finish_bake_internal(BakeRender *bkr)
1322 RE_Database_Free(bkr->re);
1324 /* restore raytrace and AO */
1325 if(bkr->scene->r.bake_mode==RE_BAKE_AO)
1326 if(bkr->prev_wo_amb_occ == 0)
1327 bkr->scene->world->mode &= ~WO_AMB_OCC;
1329 if(bkr->scene->r.bake_mode==RE_BAKE_AO || bkr->actob)
1330 if(bkr->prev_r_raytrace == 0)
1331 bkr->scene->r.mode &= ~R_RAYTRACE;
1333 if(bkr->result==BAKE_RESULT_OK) {
1335 /* force OpenGL reload and mipmap recalc */
1336 for(ima= G.main->image.first; ima; ima= ima->id.next) {
1337 if(ima->ok==IMA_OK_LOADED) {
1338 ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1340 if(ibuf->userflags & IB_BITMAPDIRTY) {
1341 GPU_free_image(ima);
1342 imb_freemipmapImBuf(ibuf);
1345 /* freed when baking is done, but if its canceled we need to free here */
1346 if (ibuf->userdata) {
1347 MEM_freeN(ibuf->userdata);
1348 ibuf->userdata= NULL;
1356 static void *do_bake_render(void *bake_v)
1358 BakeRender *bkr= bake_v;
1360 bkr->result= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress);
1366 static void bake_startjob(void *bkv, short *stop, short *do_update, float *progress)
1368 BakeRender *bkr= bkv;
1369 Scene *scene= bkr->scene;
1370 Main *bmain= bkr->main;
1373 bkr->do_update= do_update;
1374 bkr->progress= progress;
1376 RE_test_break_cb(bkr->re, NULL, thread_break);
1377 G.afbreek= 0; /* blender_test_break uses this global */
1379 RE_Database_Baking(bkr->re, bmain, scene, scene->lay, scene->r.bake_mode, bkr->actob);
1381 /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
1382 bkr->result= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress);
1385 static void bake_update(void *bkv)
1387 BakeRender *bkr= bkv;
1389 if(bkr->sa && bkr->sa->spacetype==SPACE_IMAGE) { /* incase the user changed while baking */
1390 SpaceImage *sima= bkr->sa->spacedata.first;
1392 sima->image= RE_bake_shade_get_image();
1396 static void bake_freejob(void *bkv)
1398 BakeRender *bkr= bkv;
1399 finish_bake_internal(bkr);
1401 if(bkr->result==BAKE_RESULT_NO_OBJECTS)
1402 BKE_report(bkr->reports, RPT_ERROR, "No objects or images found to bake to");
1403 else if(bkr->result==BAKE_RESULT_FEEDBACK_LOOP)
1404 BKE_report(bkr->reports, RPT_WARNING, "Feedback loop detected");
1411 static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEvent *event)
1413 /* no running blender, remove handler and pass through */
1414 if(0==WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C)))
1415 return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
1417 /* running render */
1418 switch (event->type) {
1420 return OPERATOR_RUNNING_MODAL;
1423 return OPERATOR_PASS_THROUGH;
1426 static int is_multires_bake(Scene *scene)
1428 if ( ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT))
1429 return scene->r.bake_flag & R_BAKE_MULTIRES;
1434 static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(_event))
1436 Scene *scene= CTX_data_scene(C);
1437 int result= OPERATOR_CANCELLED;
1439 if(is_multires_bake(scene)) {
1440 result= multiresbake_image_exec(C, op);
1442 /* only one render job at a time */
1443 if(WM_jobs_test(CTX_wm_manager(C), scene))
1444 return OPERATOR_CANCELLED;
1446 if(test_bake_internal(C, op->reports)==0) {
1447 return OPERATOR_CANCELLED;
1450 BakeRender *bkr= MEM_callocN(sizeof(BakeRender), "render bake");
1453 init_bake_internal(bkr, C);
1454 bkr->reports= op->reports;
1457 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);
1458 WM_jobs_customdata(steve, bkr, bake_freejob);
1459 WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
1460 WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL);
1465 WM_jobs_start(CTX_wm_manager(C), steve);
1469 /* add modal handler for ESC */
1470 WM_event_add_modal_handler(C, op);
1473 result= OPERATOR_RUNNING_MODAL;
1476 WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
1482 static int bake_image_exec(bContext *C, wmOperator *op)
1484 Main *bmain= CTX_data_main(C);
1485 Scene *scene= CTX_data_scene(C);
1486 int result= OPERATOR_CANCELLED;
1488 if(is_multires_bake(scene)) {
1489 result= multiresbake_image_exec_locked(C, op);
1491 if(test_bake_internal(C, op->reports)==0) {
1492 return OPERATOR_CANCELLED;
1496 BakeRender bkr= {NULL};
1498 init_bake_internal(&bkr, C);
1499 bkr.reports= op->reports;
1501 RE_test_break_cb(bkr.re, NULL, thread_break);
1502 G.afbreek= 0; /* blender_test_break uses this global */
1504 RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL);
1506 /* baking itself is threaded, cannot use test_break in threads */
1507 BLI_init_threads(&threads, do_bake_render, 1);
1509 BLI_insert_thread(&threads, &bkr);
1511 while(bkr.ready==0) {
1516 /* used to redraw in 2.4x but this is just for exec in 2.5 */
1518 blender_test_break();
1520 BLI_end_threads(&threads);
1522 if(bkr.result==BAKE_RESULT_NO_OBJECTS)
1523 BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to");
1524 else if(bkr.result==BAKE_RESULT_FEEDBACK_LOOP)
1525 BKE_report(op->reports, RPT_ERROR, "Feedback loop detected");
1527 finish_bake_internal(&bkr);
1529 result= OPERATOR_FINISHED;
1533 WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene);
1538 void OBJECT_OT_bake_image(wmOperatorType *ot)
1542 ot->description= "Bake image textures of selected objects";
1543 ot->idname= "OBJECT_OT_bake_image";
1546 ot->exec= bake_image_exec;
1547 ot->invoke= objects_bake_render_invoke;
1548 ot->modal= objects_bake_render_modal;