From 05d09feeee3cfc70957c079610c8fcbb12a5b711 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Sun, 13 Nov 2011 10:48:46 +0000 Subject: Speedup of multires baker Issue was caused by how CCGDM handles ORIGINDEX cystom layer: It runs cycle through all faces to fill origindex array on each call of dm->getFaceDataArray(dm, CD_ORIGINDEX) Solved issue by obtaining origindex array once on baker data initialization and using this stored array when interpolating multires grid data. --- source/blender/editors/object/object_bake.c | 41 ++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'source/blender') diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 03e169e7007..2d5f0b5ff2b 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -153,8 +153,13 @@ typedef struct { float height_min, height_max; Image *ima; DerivedMesh *ssdm; + const int *origindex; } MHeightBakeData; +typedef struct { + const int *origindex; +} MNormalBakeData; + static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index) { unsigned int indices[]= {data->mface[face_num].v1, data->mface[face_num].v2, @@ -501,7 +506,7 @@ static void interp_bilinear_grid(DMGridData *grid, int grid_size, float crn_x, f interp_bilinear_quad_data(data, u, v, res); } -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]) +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]) { MFace mface; DMGridData **grid_data; @@ -521,9 +526,8 @@ static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int lvl, g_index= grid_offset[face_index]; S= mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u*(face_side-1), v*(face_side-1), &crn_x, &crn_y); } else { - const int *index= lodm->getFaceDataArray(lodm, CD_ORIGINDEX); int side= (1 << (lvl-1)) + 1; - int grid_index= index[face_index]; + int grid_index= origindex[face_index]; int loc_offs= face_index % (1<<(2*lvl)); int cell_index= loc_offs % ((side-1)*(side-1)); int cell_side= grid_size / (side-1); @@ -587,10 +591,11 @@ static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float interp_barycentric_tri_data(data, u, v, res); } -static void *init_heights_data(MultiresBakeRender *bkr, Image* ima) +static void *init_heights_data(MultiresBakeRender *bkr, Image *ima) { MHeightBakeData *height_data; ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + DerivedMesh *lodm= bkr->lores_dm; height_data= MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData"); @@ -614,9 +619,23 @@ static void *init_heights_data(MultiresBakeRender *bkr, Image* ima) height_data->ssdm= subsurf_make_derived_from_derived(bkr->lores_dm, &smd, 0, NULL, 0, 0, 0); } + height_data->origindex= lodm->getFaceDataArray(lodm, CD_ORIGINDEX); + return (void*)height_data; } +static void *init_normal_data(MultiresBakeRender *bkr, Image *UNUSED(ima)) +{ + MNormalBakeData *normal_data; + DerivedMesh *lodm= bkr->lores_dm; + + normal_data= MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData"); + + normal_data->origindex= lodm->getFaceDataArray(lodm, CD_ORIGINDEX); + + return (void*)normal_data; +} + static void apply_heights_data(void *bake_data) { MHeightBakeData *height_data= (MHeightBakeData*)bake_data; @@ -698,13 +717,11 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, CLAMP(uv[0], 0.0f, 1.0f); CLAMP(uv[1], 0.0f, 1.0f); - get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], p1, 0); + get_ccgdm_data(lores_dm, hires_dm, height_data->origindex, lvl, face_index, uv[0], uv[1], p1, 0); if(height_data->ssdm) { - //get_ccgdm_data_ss(lores_dm, height_data->ssdm, lvl, face_index, uv[0], uv[1], p0, n); - get_ccgdm_data(lores_dm, height_data->ssdm, 0, face_index, uv[0], uv[1], p0, n); + get_ccgdm_data(lores_dm, height_data->ssdm, height_data->origindex, 0, face_index, uv[0], uv[1], p0, n); } else { - MFace mface; lores_dm->getFace(lores_dm, face_index, &mface); if(mface.v4) { @@ -717,7 +734,6 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, } sub_v3_v3v3(vec, p1, p0); - //len= len_v3(vec); len= dot_v3v3(n, vec); height_data->heights[pixel]= len; @@ -740,7 +756,7 @@ static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, - find coord and normal of point with specified UV in hi-res mesh - multiply it by tangmat - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */ -static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *UNUSED(bake_data), +static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, const int face_index, const int lvl, const float st[2], float tangmat[3][3], const int x, const int y) { @@ -748,6 +764,7 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, MFace mface; Image *ima= mtface[face_index].tpage; ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + MNormalBakeData *normal_data= (MNormalBakeData*)bake_data; float uv[2], *st0, *st1, *st2, *st3; int pixel= ibuf->x*y + x; float n[3], vec[3], tmp[3]= {0.5, 0.5, 0.5}; @@ -767,7 +784,7 @@ static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, CLAMP(uv[0], 0.0f, 1.0f); CLAMP(uv[1], 0.0f, 1.0f); - get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], NULL, n); + get_ccgdm_data(lores_dm, hires_dm, normal_data->origindex, lvl, face_index, uv[0], uv[1], NULL, n); mul_v3_m3v3(vec, tangmat, n); normalize_v3(vec); @@ -832,7 +849,7 @@ static void bake_images(MultiresBakeRender *bkr) switch(bkr->mode) { case RE_BAKE_NORMALS: - do_multires_bake(bkr, ima, apply_tangmat_callback, NULL, NULL, NULL); + do_multires_bake(bkr, ima, apply_tangmat_callback, init_normal_data, NULL, NULL); break; case RE_BAKE_DISPLACEMENT: do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data, -- cgit v1.2.3