diff options
Diffstat (limited to 'source/blender/editors/object/object_bake.c')
-rw-r--r-- | source/blender/editors/object/object_bake.c | 98 |
1 files changed, 67 insertions, 31 deletions
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 9837fec2b1e..e23329a7a68 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -52,15 +52,17 @@ #include "BKE_global.h" #include "BKE_image.h" #include "BKE_main.h" +#include "BKE_material.h" #include "BKE_multires.h" #include "BKE_report.h" #include "BKE_cdderivedmesh.h" #include "BKE_modifier.h" #include "BKE_DerivedMesh.h" -#include "BKE_depsgraph.h" #include "BKE_mesh.h" #include "BKE_scene.h" +#include "DEG_depsgraph.h" + #include "RE_pipeline.h" #include "RE_shader_ext.h" #include "RE_multires_bake.h" @@ -86,6 +88,11 @@ * 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; @@ -152,7 +159,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) break; } - if (!me->mtpoly) { + if (!me->mloopuv) { BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); ok = false; @@ -160,7 +167,7 @@ static bool multiresbake_check(bContext *C, wmOperator *op) else { a = me->totpoly; while (ok && a--) { - Image *ima = me->mtpoly[a].tpage; + Image *ima = BKE_object_material_edit_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"); @@ -199,7 +206,8 @@ static bool multiresbake_check(bContext *C, wmOperator *op) return ok; } -static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl) +static DerivedMesh *multiresbake_create_loresdm( + Scene *scene, Object *ob, eObjectMode object_mode, int *lvl) { DerivedMesh *dm; MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); @@ -219,13 +227,15 @@ static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *l tmp_mmd.lvl = *lvl; tmp_mmd.sculptlvl = *lvl; - dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0); + dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0, object_mode); cddm->release(cddm); return dm; } -static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, bool *simple) +static DerivedMesh *multiresbake_create_hiresdm( + Scene *scene, Object *ob, eObjectMode object_mode, + int *lvl, bool *simple) { Mesh *me = (Mesh *)ob->data; MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0); @@ -246,7 +256,7 @@ static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *l tmp_mmd.lvl = mmd->totlvl; tmp_mmd.sculptlvl = mmd->totlvl; - dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0); + dm = multires_make_derived_from_derived(cddm, &tmp_mmd, ob, 0, object_mode); cddm->release(cddm); return dm; @@ -283,26 +293,34 @@ static void clear_single_image(Image *image, ClearFlag flag) } } -static void clear_images_poly(MTexPoly *mtpoly, int totpoly, ClearFlag flag) +static void clear_images_poly(Image **ob_image_array, int ob_image_array_len, ClearFlag flag) { - int a; - - for (a = 0; a < totpoly; a++) { - mtpoly[a].tpage->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 (a = 0; a < totpoly; a++) { - clear_single_image(mtpoly[a].tpage, flag); + for (int i = 0; i < ob_image_array_len; i++) { + Image *image = ob_image_array[i]; + if (image) { + clear_single_image(image, flag); + } } - for (a = 0; a < totpoly; a++) { - mtpoly[a].tpage->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; + } } } static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) { Object *ob; + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); int objects_baked = 0; @@ -312,11 +330,10 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) if (scene->r.bake_flag & R_BAKE_CLEAR) { /* clear images */ CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) { - Mesh *me; ClearFlag clear_flag = 0; ob = base->object; - me = (Mesh *)ob->data; + // me = (Mesh *)ob->data; if (scene->r.bake_mode == RE_BAKE_NORMALS) { clear_flag = CLEAR_TANGENT_NORMAL; @@ -325,7 +342,11 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) clear_flag = CLEAR_DISPLACEMENT; } - clear_images_poly(me->mtpoly, me->totpoly, clear_flag); + { + Image **ob_image_array = BKE_object_material_edit_image_get_array(ob); + clear_images_poly(ob_image_array, ob->totcol, clear_flag); + MEM_freeN(ob_image_array); + } } CTX_DATA_END; } @@ -351,11 +372,16 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) //bkr.reports= op->reports; /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ - bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); - bkr.lores_dm = multiresbake_create_loresdm(scene, ob, &bkr.lvl); + bkr.ob_image.array = BKE_object_material_edit_image_get_array(ob); + bkr.ob_image.len = ob->totcol; + + bkr.hires_dm = multiresbake_create_hiresdm(scene, ob, workspace->object_mode, &bkr.tot_lvl, &bkr.simple); + bkr.lores_dm = multiresbake_create_loresdm(scene, ob, workspace->object_mode, &bkr.lvl); RE_multires_bake_images(&bkr); + MEM_freeN(bkr.ob_image.array); + BLI_freelistN(&bkr.image); bkr.lores_dm->release(bkr.lores_dm); @@ -374,6 +400,7 @@ static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) /* Multiresbake adopted for job-system executing */ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) { + const WorkSpace *workspace = CTX_wm_workspace(C); Scene *scene = CTX_data_scene(C); Object *ob; @@ -401,9 +428,12 @@ static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) data = MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); + data->ob_image.array = BKE_object_material_edit_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->hires_dm = multiresbake_create_hiresdm(scene, ob, workspace->object_mode, &data->tot_lvl, &data->simple); + data->lores_dm = multiresbake_create_loresdm(scene, ob, workspace->object_mode, &lvl); data->lvl = lvl; BLI_addtail(&bkj->data, data); @@ -421,8 +451,6 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa if (bkj->bake_clear) { /* clear images */ for (data = bkj->data.first; data; data = data->next) { - DerivedMesh *dm = data->lores_dm; - MTexPoly *mtexpoly = CustomData_get_layer(&dm->polyData, CD_MTEXPOLY); ClearFlag clear_flag = 0; if (bkj->mode == RE_BAKE_NORMALS) { @@ -432,7 +460,7 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa clear_flag = CLEAR_DISPLACEMENT; } - clear_images_poly(mtexpoly, dm->getNumPolys(dm), clear_flag); + clear_images_poly(data->ob_image.array, data->ob_image.len, clear_flag); } } @@ -445,6 +473,8 @@ static void multiresbake_startjob(void *bkv, short *stop, short *do_update, floa 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; @@ -493,6 +523,8 @@ static void multiresbake_freejob(void *bkv) GPU_free_image(ima); } + MEM_freeN(data->ob_image.array); + BLI_freelistN(&data->images); MEM_freeN(data); @@ -549,6 +581,7 @@ typedef struct BakeRender { Render *re; Main *main; Scene *scene; + ViewLayer *view_layer; struct Object *actob; int result, ready; @@ -589,6 +622,7 @@ static int test_bake_internal(bContext *C, ReportList *reports) static void init_bake_internal(BakeRender *bkr, bContext *C) { Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); bScreen *sc = CTX_wm_screen(C); /* get editmode results */ @@ -597,7 +631,8 @@ static void init_bake_internal(BakeRender *bkr, bContext *C) bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL; /* can be NULL */ bkr->main = CTX_data_main(C); bkr->scene = scene; - bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL; + bkr->view_layer = view_layer; + bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT(view_layer) : NULL; bkr->re = RE_NewRender("_Bake View_"); if (scene->r.bake_mode == RE_BAKE_AO) { @@ -661,7 +696,7 @@ static void finish_bake_internal(BakeRender *bkr) } BKE_image_release_ibuf(ima, ibuf, NULL); - DAG_id_tag_update(&ima->id, 0); + DEG_id_tag_update(&ima->id, 0); } } @@ -671,7 +706,7 @@ static void finish_bake_internal(BakeRender *bkr) BLI_assert(BLI_thread_is_main()); for (me = G.main->mesh.first; me; me = me->id.next) { if (me->id.tag & LIB_TAG_DOIT) { - DAG_id_tag_update(&me->id, OB_RECALC_DATA); + DEG_id_tag_update(&me->id, OB_RECALC_DATA); BKE_mesh_tessface_clear(me); } } @@ -702,7 +737,7 @@ static void bake_startjob(void *bkv, short *stop, short *do_update, float *progr RE_test_break_cb(bkr->re, NULL, thread_break); G.is_break = false; /* BKE_blender_test_break uses this global */ - RE_Database_Baking(bkr->re, bmain, scene, scene->lay, scene->r.bake_mode, bkr->actob); + RE_Database_Baking(bkr->re, bmain, scene, bkr->view_layer, scene->lay, scene->r.bake_mode, bkr->actob); /* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */ bkr->result = RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress); @@ -829,7 +864,8 @@ static int bake_image_exec(bContext *C, wmOperator *op) RE_test_break_cb(bkr.re, NULL, thread_break); G.is_break = false; /* BKE_blender_test_break uses this global */ - RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT : NULL); + RE_Database_Baking(bkr.re, bmain, scene, bkr.view_layer, scene->lay, scene->r.bake_mode, + (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT(bkr.view_layer) : NULL); /* baking itself is threaded, cannot use test_break in threads */ BLI_threadpool_init(&threads, do_bake_render, 1); |