diff options
Diffstat (limited to 'source/blender/editors/object/object_bake.c')
-rw-r--r-- | source/blender/editors/object/object_bake.c | 870 |
1 files changed, 435 insertions, 435 deletions
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index ac1f31d0b48..f3138c5afec 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -73,18 +73,18 @@ static Image *bake_object_image_get(Object *ob, int mat_nr) { - Image *image = NULL; - ED_object_get_active_image(ob, mat_nr + 1, &image, NULL, NULL, NULL); - return image; + Image *image = NULL; + ED_object_get_active_image(ob, mat_nr + 1, &image, NULL, NULL, NULL); + return image; } static Image **bake_object_image_get_array(Object *ob) { - Image **image_array = MEM_mallocN(sizeof(Material *) * ob->totcol, __func__); - for (int i = 0; i < ob->totcol; i++) { - image_array[i] = bake_object_image_get(ob, i); - } - return image_array; + Image **image_array = MEM_mallocN(sizeof(Material *) * ob->totcol, __func__); + for (int i = 0; i < ob->totcol; i++) { + image_array[i] = bake_object_image_get(ob, i); + } + return image_array; } /* ****************** multires BAKING ********************** */ @@ -92,485 +92,486 @@ static Image **bake_object_image_get_array(Object *ob) /* holder of per-object data needed for bake job * needed to make job totally thread-safe */ typedef struct MultiresBakerJobData { - struct MultiresBakerJobData *next, *prev; - /* material aligned image array (for per-face bake image) */ - struct { - Image **array; - int len; - } ob_image; - DerivedMesh *lores_dm, *hires_dm; - bool simple; - int lvl, tot_lvl; - ListBase images; + struct MultiresBakerJobData *next, *prev; + /* material aligned image array (for per-face bake image) */ + struct { + Image **array; + int len; + } ob_image; + DerivedMesh *lores_dm, *hires_dm; + bool simple; + int lvl, tot_lvl; + ListBase images; } MultiresBakerJobData; /* data passing to multires-baker job */ typedef struct { - Scene *scene; - ListBase data; - /** Clear the images before baking */ - bool bake_clear; - /** Bake-filter, aka margin */ - int bake_filter; - /** mode of baking (displacement, normals, AO) */ - short mode; - /** Use low-resolution mesh when baking displacement maps */ - bool use_lores_mesh; - /** Number of rays to be cast when doing AO baking */ - int number_of_rays; - /** Bias between object and start ray point when doing AO baking */ - float bias; - /** Number of threads to be used for baking */ - int threads; - /** User scale used to scale displacement when baking derivative map. */ - float user_scale; + Scene *scene; + ListBase data; + /** Clear the images before baking */ + bool bake_clear; + /** Bake-filter, aka margin */ + int bake_filter; + /** mode of baking (displacement, normals, AO) */ + short mode; + /** Use low-resolution mesh when baking displacement maps */ + bool use_lores_mesh; + /** Number of rays to be cast when doing AO baking */ + int number_of_rays; + /** Bias between object and start ray point when doing AO baking */ + float bias; + /** Number of threads to be used for baking */ + int threads; + /** User scale used to scale displacement when baking derivative map. */ + float user_scale; } MultiresBakeJob; static bool multiresbake_check(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); - Object *ob; - Mesh *me; - MultiresModifierData *mmd; - bool ok = true; - int a; - - CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) - { - ob = base->object; - - if (ob->type != OB_MESH) { - BKE_report(op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object"); - - ok = false; - break; - } - - me = (Mesh *)ob->data; - mmd = get_multires_modifier(scene, ob, 0); - - /* Multi-resolution should be and be last in the stack */ - if (ok && mmd) { - ModifierData *md; - - ok = mmd->totlvl > 0; - - for (md = (ModifierData *)mmd->modifier.next; md && ok; md = md->next) { - if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) { - ok = false; - } - } - } - else { - ok = false; - } - - if (!ok) { - BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object"); - - break; - } - - if (!me->mloopuv) { - BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); - - ok = false; - } - else { - a = me->totpoly; - while (ok && a--) { - Image *ima = bake_object_image_get(ob, me->mpoly[a].mat_nr); - - if (!ima) { - BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker"); - - ok = false; - } - else { - ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); - - if (!ibuf) { - BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer"); - - ok = false; - } - else { - if (ibuf->rect == NULL && ibuf->rect_float == NULL) - ok = false; - - if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4)) - ok = false; - - if (!ok) - BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type"); - } - - BKE_image_release_ibuf(ima, ibuf, NULL); - } - } - } - - if (!ok) - break; - } - CTX_DATA_END; - - return ok; + Scene *scene = CTX_data_scene(C); + Object *ob; + Mesh *me; + MultiresModifierData *mmd; + bool ok = true; + int a; + + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { + ob = base->object; + + if (ob->type != OB_MESH) { + BKE_report( + op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object"); + + ok = false; + break; + } + + me = (Mesh *)ob->data; + mmd = get_multires_modifier(scene, ob, 0); + + /* Multi-resolution should be and be last in the stack */ + if (ok && mmd) { + ModifierData *md; + + ok = mmd->totlvl > 0; + + for (md = (ModifierData *)mmd->modifier.next; md && ok; md = md->next) { + if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) { + ok = false; + } + } + } + else { + ok = false; + } + + if (!ok) { + BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object"); + + break; + } + + if (!me->mloopuv) { + BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); + + ok = false; + } + else { + a = me->totpoly; + while (ok && a--) { + Image *ima = bake_object_image_get(ob, me->mpoly[a].mat_nr); + + if (!ima) { + BKE_report( + op->reports, RPT_ERROR, "You should have active texture to use multires baker"); + + ok = false; + } + else { + ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL); + + if (!ibuf) { + BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer"); + + ok = false; + } + else { + if (ibuf->rect == NULL && ibuf->rect_float == NULL) + ok = false; + + if (ibuf->rect_float && !(ibuf->channels == 0 || ibuf->channels == 4)) + ok = false; + + if (!ok) + BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type"); + } + + BKE_image_release_ibuf(ima, ibuf, NULL); + } + } + } + + if (!ok) + break; + } + CTX_DATA_END; + + return ok; } static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl) { - DerivedMesh *dm; - MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); - Mesh *me = (Mesh *)ob->data; - MultiresModifierData tmp_mmd = *mmd; - DerivedMesh *cddm = CDDM_from_mesh(me); + DerivedMesh *dm; + MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); + Mesh *me = (Mesh *)ob->data; + MultiresModifierData tmp_mmd = *mmd; + DerivedMesh *cddm = CDDM_from_mesh(me); - DM_set_only_copy(cddm, &CD_MASK_BAREMESH); + DM_set_only_copy(cddm, &CD_MASK_BAREMESH); - if (mmd->lvl == 0) { - dm = CDDM_copy(cddm); - } - else { - tmp_mmd.lvl = mmd->lvl; - tmp_mmd.sculptlvl = mmd->lvl; - dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0); - } + if (mmd->lvl == 0) { + dm = CDDM_copy(cddm); + } + else { + tmp_mmd.lvl = mmd->lvl; + tmp_mmd.sculptlvl = mmd->lvl; + dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0); + } - cddm->release(cddm); + cddm->release(cddm); - *lvl = mmd->lvl; + *lvl = mmd->lvl; - return dm; + return dm; } static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, bool *simple) { - Mesh *me = (Mesh *)ob->data; - MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); - MultiresModifierData tmp_mmd = *mmd; - DerivedMesh *cddm = CDDM_from_mesh(me); - DerivedMesh *dm; + Mesh *me = (Mesh *)ob->data; + MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); + MultiresModifierData tmp_mmd = *mmd; + DerivedMesh *cddm = CDDM_from_mesh(me); + DerivedMesh *dm; - DM_set_only_copy(cddm, &CD_MASK_BAREMESH); + DM_set_only_copy(cddm, &CD_MASK_BAREMESH); - /* TODO: DM_set_only_copy wouldn't set mask for loop and poly data, - * but we really need BAREMESH only to save lots of memory - */ - CustomData_set_only_copy(&cddm->loopData, CD_MASK_BAREMESH.lmask); - CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH.pmask); + /* TODO: DM_set_only_copy wouldn't set mask for loop and poly data, + * but we really need BAREMESH only to save lots of memory + */ + CustomData_set_only_copy(&cddm->loopData, CD_MASK_BAREMESH.lmask); + CustomData_set_only_copy(&cddm->polyData, CD_MASK_BAREMESH.pmask); - *lvl = mmd->totlvl; - *simple = mmd->simple != 0; + *lvl = mmd->totlvl; + *simple = mmd->simple != 0; - tmp_mmd.lvl = mmd->totlvl; - tmp_mmd.sculptlvl = mmd->totlvl; - dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0); - cddm->release(cddm); + tmp_mmd.lvl = mmd->totlvl; + tmp_mmd.sculptlvl = mmd->totlvl; + dm = multires_make_derived_from_derived(cddm, &tmp_mmd, scene, ob, 0); + cddm->release(cddm); - return dm; + return dm; } typedef enum ClearFlag { - CLEAR_TANGENT_NORMAL = 1, - CLEAR_DISPLACEMENT = 2, + CLEAR_TANGENT_NORMAL = 1, + CLEAR_DISPLACEMENT = 2, } ClearFlag; - static void clear_single_image(Image *image, ClearFlag flag) { - const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f}; - const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f}; - const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f}; - const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f}; - const float disp_alpha[4] = {0.5f, 0.5f, 0.5f, 0.0f}; - const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f}; - - if ((image->id.tag & LIB_TAG_DOIT) == 0) { - ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); - - if (flag == CLEAR_TANGENT_NORMAL) - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid); - else if (flag == CLEAR_DISPLACEMENT) - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid); - else - IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); - - image->id.tag |= LIB_TAG_DOIT; - - BKE_image_release_ibuf(image, ibuf, NULL); - } + const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + const float vec_solid[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + const float nor_alpha[4] = {0.5f, 0.5f, 1.0f, 0.0f}; + const float nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f}; + const float disp_alpha[4] = {0.5f, 0.5f, 0.5f, 0.0f}; + const float disp_solid[4] = {0.5f, 0.5f, 0.5f, 1.0f}; + + if ((image->id.tag & LIB_TAG_DOIT) == 0) { + ImBuf *ibuf = BKE_image_acquire_ibuf(image, NULL, NULL); + + if (flag == CLEAR_TANGENT_NORMAL) + IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid); + else if (flag == CLEAR_DISPLACEMENT) + IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? disp_alpha : disp_solid); + else + IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); + + image->id.tag |= LIB_TAG_DOIT; + + BKE_image_release_ibuf(image, ibuf, NULL); + } } static void clear_images_poly(Image **ob_image_array, int ob_image_array_len, ClearFlag flag) { - for (int i = 0; i < ob_image_array_len; i++) { - Image *image = ob_image_array[i]; - if (image) { - image->id.tag &= ~LIB_TAG_DOIT; - } - } - - for (int i = 0; i < ob_image_array_len; i++) { - Image *image = ob_image_array[i]; - if (image) { - clear_single_image(image, flag); - } - } - - for (int i = 0; i < ob_image_array_len; i++) { - Image *image = ob_image_array[i]; - if (image) { - image->id.tag &= ~LIB_TAG_DOIT; - } - } + for (int i = 0; i < ob_image_array_len; i++) { + Image *image = ob_image_array[i]; + if (image) { + image->id.tag &= ~LIB_TAG_DOIT; + } + } + + for (int i = 0; i < ob_image_array_len; i++) { + Image *image = ob_image_array[i]; + if (image) { + clear_single_image(image, flag); + } + } + + for (int i = 0; i < ob_image_array_len; i++) { + Image *image = ob_image_array[i]; + if (image) { + image->id.tag &= ~LIB_TAG_DOIT; + } + } } static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) { - Object *ob; - Scene *scene = CTX_data_scene(C); - int objects_baked = 0; + Object *ob; + Scene *scene = CTX_data_scene(C); + int objects_baked = 0; - if (!multiresbake_check(C, op)) - return OPERATOR_CANCELLED; + if (!multiresbake_check(C, op)) + return OPERATOR_CANCELLED; - if (scene->r.bake_flag & R_BAKE_CLEAR) { /* clear images */ - CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) - { - ClearFlag clear_flag = 0; + if (scene->r.bake_flag & R_BAKE_CLEAR) { /* clear images */ + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { + ClearFlag clear_flag = 0; - ob = base->object; - // me = (Mesh *)ob->data; + ob = base->object; + // me = (Mesh *)ob->data; - if (scene->r.bake_mode == RE_BAKE_NORMALS) { - clear_flag = CLEAR_TANGENT_NORMAL; - } - else if (scene->r.bake_mode == RE_BAKE_DISPLACEMENT) { - clear_flag = CLEAR_DISPLACEMENT; - } + if (scene->r.bake_mode == RE_BAKE_NORMALS) { + clear_flag = CLEAR_TANGENT_NORMAL; + } + else if (scene->r.bake_mode == RE_BAKE_DISPLACEMENT) { + clear_flag = CLEAR_DISPLACEMENT; + } - { - Image **ob_image_array = bake_object_image_get_array(ob); - clear_images_poly(ob_image_array, ob->totcol, clear_flag); - MEM_freeN(ob_image_array); - } - } - CTX_DATA_END; - } + { + Image **ob_image_array = bake_object_image_get_array(ob); + clear_images_poly(ob_image_array, ob->totcol, clear_flag); + MEM_freeN(ob_image_array); + } + } + CTX_DATA_END; + } - CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) - { - MultiresBakeRender bkr = {NULL}; + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { + MultiresBakeRender bkr = {NULL}; - ob = base->object; + ob = base->object; - multires_force_update(ob); + multires_force_update(ob); - /* copy data stored in job descriptor */ - bkr.scene = scene; - bkr.bake_filter = scene->r.bake_filter; - bkr.mode = scene->r.bake_mode; - bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH; - bkr.bias = scene->r.bake_biasdist; - bkr.number_of_rays = scene->r.bake_samples; - bkr.threads = BKE_scene_num_threads(scene); - bkr.user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f; - //bkr.reports= op->reports; + /* copy data stored in job descriptor */ + bkr.scene = scene; + bkr.bake_filter = scene->r.bake_filter; + bkr.mode = scene->r.bake_mode; + bkr.use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH; + bkr.bias = scene->r.bake_biasdist; + bkr.number_of_rays = scene->r.bake_samples; + bkr.threads = BKE_scene_num_threads(scene); + bkr.user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f; + //bkr.reports= op->reports; - /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ - bkr.ob_image.array = bake_object_image_get_array(ob); - bkr.ob_image.len = ob->totcol; + /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ + bkr.ob_image.array = bake_object_image_get_array(ob); + bkr.ob_image.len = ob->totcol; - bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); - bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl); + bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); + bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl); - RE_multires_bake_images(&bkr); + RE_multires_bake_images(&bkr); - MEM_freeN(bkr.ob_image.array); + MEM_freeN(bkr.ob_image.array); - BLI_freelistN(&bkr.image); + BLI_freelistN(&bkr.image); - bkr.lores_dm->release(bkr.lores_dm); - bkr.hires_dm->release(bkr.hires_dm); + bkr.lores_dm->release(bkr.lores_dm); + bkr.hires_dm->release(bkr.hires_dm); - objects_baked++; - } - CTX_DATA_END; + objects_baked++; + } + CTX_DATA_END; - if (!objects_baked) - BKE_report(op->reports, RPT_ERROR, "No objects found to bake from"); + if (!objects_baked) + BKE_report(op->reports, RPT_ERROR, "No objects found to bake from"); - return OPERATOR_FINISHED; + return OPERATOR_FINISHED; } /* Multiresbake adopted for job-system executing */ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) { - Scene *scene = CTX_data_scene(C); - Object *ob; - - /* backup scene settings, so their changing in UI would take no effect on baker */ - bkj->scene = scene; - bkj->bake_filter = scene->r.bake_filter; - bkj->mode = scene->r.bake_mode; - bkj->use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH; - bkj->bake_clear = scene->r.bake_flag & R_BAKE_CLEAR; - bkj->bias = scene->r.bake_biasdist; - bkj->number_of_rays = scene->r.bake_samples; - bkj->threads = BKE_scene_num_threads(scene); - bkj->user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f; - //bkj->reports = op->reports; - - CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) - { - MultiresBakerJobData *data; - int lvl; - - ob = base->object; - - multires_force_update(ob); - - data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); - - data->ob_image.array = bake_object_image_get_array(ob); - data->ob_image.len = ob->totcol; - - /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ - data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple); - data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl); - data->lvl = lvl; - - BLI_addtail(&bkj->data, data); - } - CTX_DATA_END; + Scene *scene = CTX_data_scene(C); + Object *ob; + + /* backup scene settings, so their changing in UI would take no effect on baker */ + bkj->scene = scene; + bkj->bake_filter = scene->r.bake_filter; + bkj->mode = scene->r.bake_mode; + bkj->use_lores_mesh = scene->r.bake_flag & R_BAKE_LORES_MESH; + bkj->bake_clear = scene->r.bake_flag & R_BAKE_CLEAR; + bkj->bias = scene->r.bake_biasdist; + bkj->number_of_rays = scene->r.bake_samples; + bkj->threads = BKE_scene_num_threads(scene); + bkj->user_scale = (scene->r.bake_flag & R_BAKE_USERSCALE) ? scene->r.bake_user_scale : -1.0f; + //bkj->reports = op->reports; + + CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { + MultiresBakerJobData *data; + int lvl; + + ob = base->object; + + multires_force_update(ob); + + data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); + + data->ob_image.array = bake_object_image_get_array(ob); + data->ob_image.len = ob->totcol; + + /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ + data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple); + data->lores_dm = multiresbake_create_loresdm(scene, ob, &lvl); + data->lvl = lvl; + + BLI_addtail(&bkj->data, data); + } + CTX_DATA_END; } static void multiresbake_startjob(void *bkv, short *stop, short *do_update, float *progress) { - MultiresBakerJobData *data; - MultiresBakeJob *bkj = bkv; - int baked_objects = 0, tot_obj; - - tot_obj = BLI_listbase_count(&bkj->data); - - if (bkj->bake_clear) { /* clear images */ - for (data = bkj->data.first; data; data = data->next) { - ClearFlag clear_flag = 0; - - if (bkj->mode == RE_BAKE_NORMALS) { - clear_flag = CLEAR_TANGENT_NORMAL; - } - else if (bkj->mode == RE_BAKE_DISPLACEMENT) { - clear_flag = CLEAR_DISPLACEMENT; - } - - clear_images_poly(data->ob_image.array, data->ob_image.len, clear_flag); - } - } - - for (data = bkj->data.first; data; data = data->next) { - MultiresBakeRender bkr = {NULL}; - - /* copy data stored in job descriptor */ - bkr.scene = bkj->scene; - bkr.bake_filter = bkj->bake_filter; - bkr.mode = bkj->mode; - bkr.use_lores_mesh = bkj->use_lores_mesh; - bkr.user_scale = bkj->user_scale; - //bkr.reports = bkj->reports; - bkr.ob_image.array = data->ob_image.array; - bkr.ob_image.len = data->ob_image.len; - - /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ - bkr.lores_dm = data->lores_dm; - bkr.hires_dm = data->hires_dm; - bkr.tot_lvl = data->tot_lvl; - bkr.lvl = data->lvl; - bkr.simple = data->simple; - - /* needed for proper progress bar */ - bkr.tot_obj = tot_obj; - bkr.baked_objects = baked_objects; - - bkr.stop = stop; - bkr.do_update = do_update; - bkr.progress = progress; - - bkr.bias = bkj->bias; - bkr.number_of_rays = bkj->number_of_rays; - bkr.threads = bkj->threads; - - RE_multires_bake_images(&bkr); - - data->images = bkr.image; - - baked_objects++; - } + MultiresBakerJobData *data; + MultiresBakeJob *bkj = bkv; + int baked_objects = 0, tot_obj; + + tot_obj = BLI_listbase_count(&bkj->data); + + if (bkj->bake_clear) { /* clear images */ + for (data = bkj->data.first; data; data = data->next) { + ClearFlag clear_flag = 0; + + if (bkj->mode == RE_BAKE_NORMALS) { + clear_flag = CLEAR_TANGENT_NORMAL; + } + else if (bkj->mode == RE_BAKE_DISPLACEMENT) { + clear_flag = CLEAR_DISPLACEMENT; + } + + clear_images_poly(data->ob_image.array, data->ob_image.len, clear_flag); + } + } + + for (data = bkj->data.first; data; data = data->next) { + MultiresBakeRender bkr = {NULL}; + + /* copy data stored in job descriptor */ + bkr.scene = bkj->scene; + bkr.bake_filter = bkj->bake_filter; + bkr.mode = bkj->mode; + bkr.use_lores_mesh = bkj->use_lores_mesh; + bkr.user_scale = bkj->user_scale; + //bkr.reports = bkj->reports; + bkr.ob_image.array = data->ob_image.array; + bkr.ob_image.len = data->ob_image.len; + + /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ + bkr.lores_dm = data->lores_dm; + bkr.hires_dm = data->hires_dm; + bkr.tot_lvl = data->tot_lvl; + bkr.lvl = data->lvl; + bkr.simple = data->simple; + + /* needed for proper progress bar */ + bkr.tot_obj = tot_obj; + bkr.baked_objects = baked_objects; + + bkr.stop = stop; + bkr.do_update = do_update; + bkr.progress = progress; + + bkr.bias = bkj->bias; + bkr.number_of_rays = bkj->number_of_rays; + bkr.threads = bkj->threads; + + RE_multires_bake_images(&bkr); + + data->images = bkr.image; + + baked_objects++; + } } static void multiresbake_freejob(void *bkv) { - MultiresBakeJob *bkj = bkv; - MultiresBakerJobData *data, *next; - LinkData *link; + MultiresBakeJob *bkj = bkv; + MultiresBakerJobData *data, *next; + LinkData *link; - data = bkj->data.first; - while (data) { - next = data->next; - data->lores_dm->release(data->lores_dm); - data->hires_dm->release(data->hires_dm); + data = bkj->data.first; + while (data) { + next = data->next; + data->lores_dm->release(data->lores_dm); + data->hires_dm->release(data->hires_dm); - /* delete here, since this delete will be called from main thread */ - for (link = data->images.first; link; link = link->next) { - Image *ima = (Image *)link->data; - GPU_free_image(ima); - } + /* delete here, since this delete will be called from main thread */ + for (link = data->images.first; link; link = link->next) { + Image *ima = (Image *)link->data; + GPU_free_image(ima); + } - MEM_freeN(data->ob_image.array); + MEM_freeN(data->ob_image.array); - BLI_freelistN(&data->images); + BLI_freelistN(&data->images); - MEM_freeN(data); - data = next; - } + MEM_freeN(data); + data = next; + } - MEM_freeN(bkj); + MEM_freeN(bkj); } static int multiresbake_image_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); - MultiresBakeJob *bkr; - wmJob *wm_job; + Scene *scene = CTX_data_scene(C); + MultiresBakeJob *bkr; + wmJob *wm_job; - if (!multiresbake_check(C, op)) - return OPERATOR_CANCELLED; + if (!multiresbake_check(C, op)) + return OPERATOR_CANCELLED; - bkr = MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data"); - init_multiresbake_job(C, bkr); + bkr = MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data"); + init_multiresbake_job(C, bkr); - if (!bkr->data.first) { - BKE_report(op->reports, RPT_ERROR, "No objects found to bake from"); - return OPERATOR_CANCELLED; - } + if (!bkr->data.first) { + BKE_report(op->reports, RPT_ERROR, "No objects found to bake from"); + return OPERATOR_CANCELLED; + } - /* setup job */ - wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Multires Bake", - WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, WM_JOB_TYPE_OBJECT_BAKE_TEXTURE); - WM_jobs_customdata_set(wm_job, bkr, multiresbake_freejob); - WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ - WM_jobs_callbacks(wm_job, multiresbake_startjob, NULL, NULL, NULL); + /* setup job */ + wm_job = WM_jobs_get(CTX_wm_manager(C), + CTX_wm_window(C), + scene, + "Multires Bake", + WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS, + WM_JOB_TYPE_OBJECT_BAKE_TEXTURE); + WM_jobs_customdata_set(wm_job, bkr, multiresbake_freejob); + WM_jobs_timer(wm_job, 0.5, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ + WM_jobs_callbacks(wm_job, multiresbake_startjob, NULL, NULL, NULL); - G.is_break = false; + G.is_break = false; - WM_jobs_start(CTX_wm_manager(C), wm_job); - WM_cursor_wait(0); + WM_jobs_start(CTX_wm_manager(C), wm_job); + WM_cursor_wait(0); - /* add modal handler for ESC */ - WM_event_add_modal_handler(C, op); + /* add modal handler for ESC */ + WM_event_add_modal_handler(C, op); - return OPERATOR_RUNNING_MODAL; + return OPERATOR_RUNNING_MODAL; } /* ****************** render BAKING ********************** */ @@ -578,66 +579,65 @@ static int multiresbake_image_exec(bContext *C, wmOperator *op) /* catch esc */ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { - /* no running blender, remove handler and pass through */ - if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE_TEXTURE)) - return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; - - /* running render */ - switch (event->type) { - case ESCKEY: - return OPERATOR_RUNNING_MODAL; - } - return OPERATOR_PASS_THROUGH; + /* no running blender, remove handler and pass through */ + if (0 == WM_jobs_test(CTX_wm_manager(C), CTX_data_scene(C), WM_JOB_TYPE_OBJECT_BAKE_TEXTURE)) + return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; + + /* running render */ + switch (event->type) { + case ESCKEY: + return OPERATOR_RUNNING_MODAL; + } + return OPERATOR_PASS_THROUGH; } static bool is_multires_bake(Scene *scene) { - if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO)) - return scene->r.bake_flag & R_BAKE_MULTIRES; + if (ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT, RE_BAKE_AO)) + return scene->r.bake_flag & R_BAKE_MULTIRES; - return 0; + return 0; } static int objects_bake_render_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(_event)) { - Scene *scene = CTX_data_scene(C); - int result = OPERATOR_CANCELLED; + Scene *scene = CTX_data_scene(C); + int result = OPERATOR_CANCELLED; - result = multiresbake_image_exec(C, op); + result = multiresbake_image_exec(C, op); - WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); - return result; + return result; } - static int bake_image_exec(bContext *C, wmOperator *op) { - Scene *scene = CTX_data_scene(C); - int result = OPERATOR_CANCELLED; + Scene *scene = CTX_data_scene(C); + int result = OPERATOR_CANCELLED; - if (!is_multires_bake(scene)) { - BLI_assert(0); - return result; - } + if (!is_multires_bake(scene)) { + BLI_assert(0); + return result; + } - result = multiresbake_image_exec_locked(C, op); + result = multiresbake_image_exec_locked(C, op); - WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); - return result; + return result; } void OBJECT_OT_bake_image(wmOperatorType *ot) { - /* identifiers */ - ot->name = "Bake"; - ot->description = "Bake image textures of selected objects"; - ot->idname = "OBJECT_OT_bake_image"; - - /* api callbacks */ - ot->exec = bake_image_exec; - ot->invoke = objects_bake_render_invoke; - ot->modal = objects_bake_render_modal; - ot->poll = ED_operator_object_active; + /* identifiers */ + ot->name = "Bake"; + ot->description = "Bake image textures of selected objects"; + ot->idname = "OBJECT_OT_bake_image"; + + /* api callbacks */ + ot->exec = bake_image_exec; + ot->invoke = objects_bake_render_invoke; + ot->modal = objects_bake_render_modal; + ot->poll = ED_operator_object_active; } |