Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/render/intern/multires_bake.c')
-rw-r--r--source/blender/render/intern/multires_bake.c193
1 files changed, 114 insertions, 79 deletions
diff --git a/source/blender/render/intern/multires_bake.c b/source/blender/render/intern/multires_bake.c
index 33d961c027d..f93397eedab 100644
--- a/source/blender/render/intern/multires_bake.c
+++ b/source/blender/render/intern/multires_bake.c
@@ -51,7 +51,7 @@ typedef void (*MPassKnownData)(DerivedMesh *lores_dm,
const int x,
const int y);
-typedef void *(*MInitBakeData)(MultiresBakeRender *bkr, Image *ima);
+typedef void *(*MInitBakeData)(MultiresBakeRender *bkr, ImBuf *ibuf);
typedef void (*MFreeBakeData)(void *bake_data);
typedef struct MultiresBakeResult {
@@ -64,6 +64,7 @@ typedef struct {
MPoly *mpoly;
MLoop *mloop;
MLoopUV *mloopuv;
+ float uv_offset[2];
const MLoopTri *mlooptri;
float *pvtangent;
const float (*precomputed_normals)[3];
@@ -91,7 +92,6 @@ typedef struct {
typedef struct {
float *heights;
- Image *ima;
DerivedMesh *ssdm;
const int *orig_index_mp_to_orig;
} MHeightBakeData;
@@ -148,7 +148,8 @@ static void init_bake_rast(MBakeRast *bake_rast,
static void flush_pixel(const MResolvePixelData *data, const int x, const int y)
{
- const float st[2] = {(x + 0.5f) / data->w, (y + 0.5f) / data->h};
+ const float st[2] = {(x + 0.5f) / data->w + data->uv_offset[0],
+ (y + 0.5f) / data->h + data->uv_offset[1]};
const float *st0, *st1, *st2;
const float *tang0, *tang1, *tang2;
float no0[3], no1[3], no2[3];
@@ -395,8 +396,12 @@ static void *do_multires_bake_thread(void *data_v)
data->tri_index = tri_index;
- bake_rasterize(
- bake_rast, mloopuv[lt->tri[0]].uv, mloopuv[lt->tri[1]].uv, mloopuv[lt->tri[2]].uv);
+ float uv[3][2];
+ sub_v2_v2v2(uv[0], mloopuv[lt->tri[0]].uv, data->uv_offset);
+ sub_v2_v2v2(uv[1], mloopuv[lt->tri[1]].uv, data->uv_offset);
+ sub_v2_v2v2(uv[2], mloopuv[lt->tri[2]].uv, data->uv_offset);
+
+ bake_rasterize(bake_rast, uv[0], uv[1], uv[2]);
/* tag image buffer for refresh */
if (data->ibuf->rect_float) {
@@ -447,6 +452,8 @@ static void init_ccgdm_arrays(DerivedMesh *dm)
static void do_multires_bake(MultiresBakeRender *bkr,
Image *ima,
+ ImageTile *tile,
+ ImBuf *ibuf,
bool require_tangent,
MPassKnownData passKnownData,
MInitBakeData initBakeData,
@@ -462,7 +469,6 @@ static void do_multires_bake(MultiresBakeRender *bkr,
MultiresBakeThread *handles;
MultiresBakeQueue queue;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
MVert *mvert = dm->getVertArray(dm);
MPoly *mpoly = dm->getPolyArray(dm);
MLoop *mloop = dm->getLoopArray(dm);
@@ -511,7 +517,7 @@ static void do_multires_bake(MultiresBakeRender *bkr,
/* all threads shares the same custom bake data */
if (initBakeData) {
- bake_data = initBakeData(bkr, ima);
+ bake_data = initBakeData(bkr, ibuf);
}
if (tot_thread > 1) {
@@ -539,6 +545,7 @@ static void do_multires_bake(MultiresBakeRender *bkr,
handle->data.mvert = mvert;
handle->data.vert_normals = vert_normals;
handle->data.mloopuv = mloopuv;
+ BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset);
handle->data.mlooptri = mlooptri;
handle->data.mloop = mloop;
handle->data.pvtangent = pvtangent;
@@ -590,8 +597,6 @@ static void do_multires_bake(MultiresBakeRender *bkr,
MEM_freeN(handles);
BKE_id_free(NULL, temp_mesh);
-
- BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
@@ -758,10 +763,9 @@ static void interp_barycentric_mlooptri(DerivedMesh *dm,
/* **************** Displacement Baker **************** */
-static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
+static void *init_heights_data(MultiresBakeRender *bkr, ImBuf *ibuf)
{
MHeightBakeData *height_data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
DerivedMesh *lodm = bkr->lores_dm;
BakeImBufuserData *userdata = ibuf->userdata;
@@ -772,7 +776,6 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData");
- height_data->ima = ima;
height_data->heights = userdata->displacement_buffer;
if (!bkr->use_lores_mesh) {
@@ -794,8 +797,6 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image *ima)
height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX);
- BKE_image_release_ibuf(ima, ibuf, NULL);
-
return (void *)height_data;
}
@@ -903,7 +904,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm,
/* **************** Normal Maps Baker **************** */
-static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
+static void *init_normal_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf))
{
MNormalBakeData *normal_data;
DerivedMesh *lodm = bkr->lores_dm;
@@ -1099,7 +1100,7 @@ static void create_ao_raytree(MultiresBakeRender *bkr, MAOBakeData *ao_data)
RE_rayobject_done(raytree);
}
-static void *init_ao_data(MultiresBakeRender *bkr, Image *UNUSED(ima))
+static void *init_ao_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf))
{
MAOBakeData *ao_data;
DerivedMesh *lodm = bkr->lores_dm;
@@ -1313,8 +1314,12 @@ static void apply_ao_callback(DerivedMesh *lores_dm,
/* ******$***************** Post processing ************************* */
-static void bake_ibuf_filter(
- ImBuf *ibuf, char *mask, const int margin, const char margin_type, DerivedMesh *dm)
+static void bake_ibuf_filter(ImBuf *ibuf,
+ char *mask,
+ const int margin,
+ const char margin_type,
+ DerivedMesh *dm,
+ const float uv_offset[2])
{
/* must check before filtering */
const bool is_new_alpha = (ibuf->planes != R_IMF_PLANES_RGBA) && BKE_imbuf_alpha_test(ibuf);
@@ -1322,7 +1327,7 @@ static void bake_ibuf_filter(
if (margin) {
switch (margin_type) {
case R_BAKE_ADJACENT_FACES:
- RE_generate_texturemargin_adjacentfaces_dm(ibuf, mask, margin, dm);
+ RE_generate_texturemargin_adjacentfaces_dm(ibuf, mask, margin, dm, uv_offset);
break;
default:
/* fall through */
@@ -1427,38 +1432,54 @@ static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
for (link = bkr->image.first; link; link = link->next) {
Image *ima = (Image *)link->data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
-
- if (ibuf->x > 0 && ibuf->y > 0) {
- BakeImBufuserData *userdata = MEM_callocN(sizeof(BakeImBufuserData),
- "MultiresBake userdata");
- userdata->mask_buffer = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
- ibuf->userdata = userdata;
-
- switch (bkr->mode) {
- case RE_BAKE_NORMALS:
- do_multires_bake(
- bkr, ima, true, apply_tangmat_callback, init_normal_data, free_normal_data, result);
- break;
- case RE_BAKE_DISPLACEMENT:
- do_multires_bake(bkr,
- ima,
- false,
- apply_heights_callback,
- init_heights_data,
- free_heights_data,
- result);
- break;
-/* TODO: restore ambient occlusion baking support. */
+
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ ImageUser iuser;
+ BKE_imageuser_default(&iuser);
+ iuser.tile = tile->tile_number;
+
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+
+ if (ibuf->x > 0 && ibuf->y > 0) {
+ BakeImBufuserData *userdata = MEM_callocN(sizeof(BakeImBufuserData),
+ "MultiresBake userdata");
+ userdata->mask_buffer = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask");
+ ibuf->userdata = userdata;
+
+ switch (bkr->mode) {
+ case RE_BAKE_NORMALS:
+ do_multires_bake(bkr,
+ ima,
+ tile,
+ ibuf,
+ true,
+ apply_tangmat_callback,
+ init_normal_data,
+ free_normal_data,
+ result);
+ break;
+ case RE_BAKE_DISPLACEMENT:
+ do_multires_bake(bkr,
+ ima,
+ tile,
+ ibuf,
+ false,
+ apply_heights_callback,
+ init_heights_data,
+ free_heights_data,
+ result);
+ break;
+ /* TODO: restore ambient occlusion baking support. */
#if 0
- case RE_BAKE_AO:
- do_multires_bake(bkr, ima, false, apply_ao_callback, init_ao_data, free_ao_data, result);
- break;
+ case RE_BAKE_AO:
+ do_multires_bake(bkr, ima, tile, ibuf, false, apply_ao_callback, init_ao_data, free_ao_data, result);
+ break;
#endif
+ }
}
- }
- BKE_image_release_ibuf(ima, ibuf, NULL);
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ }
ima->id.tag |= LIB_TAG_DOIT;
}
@@ -1471,48 +1492,62 @@ static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
for (link = bkr->image.first; link; link = link->next) {
Image *ima = (Image *)link->data;
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
- BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata;
- if (ibuf->x <= 0 || ibuf->y <= 0) {
- continue;
- }
+ LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) {
+ ImageUser iuser;
+ BKE_imageuser_default(&iuser);
+ iuser.tile = tile->tile_number;
- if (use_displacement_buffer) {
- bake_ibuf_normalize_displacement(ibuf,
- userdata->displacement_buffer,
- userdata->mask_buffer,
- result->height_min,
- result->height_max);
- }
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL);
+ BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata;
- bake_ibuf_filter(
- ibuf, userdata->mask_buffer, bkr->bake_margin, bkr->bake_margin_type, bkr->lores_dm);
+ if (ibuf->x <= 0 || ibuf->y <= 0) {
+ continue;
+ }
- ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
- BKE_image_mark_dirty(ima, ibuf);
+ if (use_displacement_buffer) {
+ bake_ibuf_normalize_displacement(ibuf,
+ userdata->displacement_buffer,
+ userdata->mask_buffer,
+ result->height_min,
+ result->height_max);
+ }
- if (ibuf->rect_float) {
- ibuf->userflags |= IB_RECT_INVALID;
- }
+ float uv_offset[2];
+ BKE_image_get_tile_uv(ima, tile->tile_number, uv_offset);
- if (ibuf->mipmap[0]) {
- ibuf->userflags |= IB_MIPMAP_INVALID;
- imb_freemipmapImBuf(ibuf);
- }
+ bake_ibuf_filter(ibuf,
+ userdata->mask_buffer,
+ bkr->bake_margin,
+ bkr->bake_margin_type,
+ bkr->lores_dm,
+ uv_offset);
+
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ BKE_image_mark_dirty(ima, ibuf);
- if (ibuf->userdata) {
- if (userdata->displacement_buffer) {
- MEM_freeN(userdata->displacement_buffer);
+ if (ibuf->rect_float) {
+ ibuf->userflags |= IB_RECT_INVALID;
}
- MEM_freeN(userdata->mask_buffer);
- MEM_freeN(userdata);
- ibuf->userdata = NULL;
- }
+ if (ibuf->mipmap[0]) {
+ ibuf->userflags |= IB_MIPMAP_INVALID;
+ imb_freemipmapImBuf(ibuf);
+ }
+
+ if (ibuf->userdata) {
+ if (userdata->displacement_buffer) {
+ MEM_freeN(userdata->displacement_buffer);
+ }
- BKE_image_release_ibuf(ima, ibuf, NULL);
- DEG_id_tag_update(&ima->id, 0);
+ MEM_freeN(userdata->mask_buffer);
+ MEM_freeN(userdata);
+ ibuf->userdata = NULL;
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ DEG_id_tag_update(&ima->id, 0);
+ }
}
}