Changeset View
Changeset View
Standalone View
Standalone View
source/blender/render/intern/multires_bake.cc
- This file was moved from source/blender/render/intern/multires_bake.c.
| Show First 20 Lines • Show All 377 Lines • ▼ Show 20 Lines | static void *do_multires_bake_thread(void *data_v) | ||||
| MultiresBakeThread *handle = (MultiresBakeThread *)data_v; | MultiresBakeThread *handle = (MultiresBakeThread *)data_v; | ||||
| MResolvePixelData *data = &handle->data; | MResolvePixelData *data = &handle->data; | ||||
| MBakeRast *bake_rast = &handle->bake_rast; | MBakeRast *bake_rast = &handle->bake_rast; | ||||
| MultiresBakeRender *bkr = handle->bkr; | MultiresBakeRender *bkr = handle->bkr; | ||||
| int tri_index; | int tri_index; | ||||
| while ((tri_index = multires_bake_queue_next_tri(handle->queue)) >= 0) { | while ((tri_index = multires_bake_queue_next_tri(handle->queue)) >= 0) { | ||||
| const MLoopTri *lt = &data->mlooptri[tri_index]; | const MLoopTri *lt = &data->mlooptri[tri_index]; | ||||
| const short mat_nr = data->material_indices == NULL ? 0 : data->material_indices[lt->poly]; | const short mat_nr = data->material_indices == nullptr ? 0 : data->material_indices[lt->poly]; | ||||
| const MLoopUV *mloopuv = data->mloopuv; | const MLoopUV *mloopuv = data->mloopuv; | ||||
| if (multiresbake_test_break(bkr)) { | if (multiresbake_test_break(bkr)) { | ||||
| break; | break; | ||||
| } | } | ||||
| Image *tri_image = mat_nr < bkr->ob_image.len ? bkr->ob_image.array[mat_nr] : NULL; | Image *tri_image = mat_nr < bkr->ob_image.len ? bkr->ob_image.array[mat_nr] : nullptr; | ||||
| if (tri_image != handle->image) { | if (tri_image != handle->image) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| data->tri_index = tri_index; | data->tri_index = tri_index; | ||||
| float uv[3][2]; | float uv[3][2]; | ||||
| sub_v2_v2v2(uv[0], mloopuv[lt->tri[0]].uv, data->uv_offset); | sub_v2_v2v2(uv[0], mloopuv[lt->tri[0]].uv, data->uv_offset); | ||||
| Show All 20 Lines | while ((tri_index = multires_bake_queue_next_tri(handle->queue)) >= 0) { | ||||
| if (bkr->progress) { | if (bkr->progress) { | ||||
| *bkr->progress = ((float)bkr->baked_objects + | *bkr->progress = ((float)bkr->baked_objects + | ||||
| (float)bkr->baked_faces / handle->queue->tot_tri) / | (float)bkr->baked_faces / handle->queue->tot_tri) / | ||||
| bkr->tot_obj; | bkr->tot_obj; | ||||
| } | } | ||||
| BLI_spin_unlock(&handle->queue->spin); | BLI_spin_unlock(&handle->queue->spin); | ||||
| } | } | ||||
| return NULL; | return nullptr; | ||||
| } | } | ||||
| /* some of arrays inside ccgdm are lazy-initialized, which will generally | /* some of arrays inside ccgdm are lazy-initialized, which will generally | ||||
| * require lock around accessing such data | * require lock around accessing such data | ||||
| * this function will ensure all arrays are allocated before threading started | * this function will ensure all arrays are allocated before threading started | ||||
| */ | */ | ||||
| static void init_ccgdm_arrays(DerivedMesh *dm) | static void init_ccgdm_arrays(DerivedMesh *dm) | ||||
| { | { | ||||
| Show All 31 Lines | static void do_multires_bake(MultiresBakeRender *bkr, | ||||
| } | } | ||||
| MultiresBakeThread *handles; | MultiresBakeThread *handles; | ||||
| MultiresBakeQueue queue; | MultiresBakeQueue queue; | ||||
| MVert *mvert = dm->getVertArray(dm); | MVert *mvert = dm->getVertArray(dm); | ||||
| MPoly *mpoly = dm->getPolyArray(dm); | MPoly *mpoly = dm->getPolyArray(dm); | ||||
| MLoop *mloop = dm->getLoopArray(dm); | MLoop *mloop = dm->getLoopArray(dm); | ||||
| MLoopUV *mloopuv = dm->getLoopDataArray(dm, CD_MLOOPUV); | MLoopUV *mloopuv = static_cast<MLoopUV *>(dm->getLoopDataArray(dm, CD_MLOOPUV)); | ||||
| float *pvtangent = NULL; | float *pvtangent = nullptr; | ||||
| ListBase threads; | ListBase threads; | ||||
| int i, tot_thread = bkr->threads > 0 ? bkr->threads : BLI_system_thread_count(); | int i, tot_thread = bkr->threads > 0 ? bkr->threads : BLI_system_thread_count(); | ||||
| void *bake_data = NULL; | void *bake_data = nullptr; | ||||
| Mesh *temp_mesh = BKE_mesh_new_nomain( | Mesh *temp_mesh = BKE_mesh_new_nomain( | ||||
| dm->getNumVerts(dm), dm->getNumEdges(dm), 0, dm->getNumLoops(dm), dm->getNumPolys(dm)); | dm->getNumVerts(dm), dm->getNumEdges(dm), 0, dm->getNumLoops(dm), dm->getNumPolys(dm)); | ||||
| memcpy(BKE_mesh_verts_for_write(temp_mesh), | memcpy(BKE_mesh_verts_for_write(temp_mesh), | ||||
| dm->getVertArray(dm), | dm->getVertArray(dm), | ||||
| temp_mesh->totvert * sizeof(MVert)); | temp_mesh->totvert * sizeof(MVert)); | ||||
| memcpy(BKE_mesh_edges_for_write(temp_mesh), | memcpy(BKE_mesh_edges_for_write(temp_mesh), | ||||
| dm->getEdgeArray(dm), | dm->getEdgeArray(dm), | ||||
| Show All 13 Lines | if (CustomData_get_layer_index(&dm->loopData, CD_TANGENT) == -1) { | ||||
| dm->getVertArray(dm), | dm->getVertArray(dm), | ||||
| dm->getPolyArray(dm), | dm->getPolyArray(dm), | ||||
| dm->getNumPolys(dm), | dm->getNumPolys(dm), | ||||
| dm->getLoopArray(dm), | dm->getLoopArray(dm), | ||||
| dm->getLoopTriArray(dm), | dm->getLoopTriArray(dm), | ||||
| dm->getNumLoopTri(dm), | dm->getNumLoopTri(dm), | ||||
| &dm->loopData, | &dm->loopData, | ||||
| true, | true, | ||||
| NULL, | nullptr, | ||||
| 0, | 0, | ||||
| vert_normals, | vert_normals, | ||||
| poly_normals, | poly_normals, | ||||
| (const float(*)[3])dm->getLoopDataArray(dm, CD_NORMAL), | (const float(*)[3])dm->getLoopDataArray(dm, CD_NORMAL), | ||||
| (const float(*)[3])dm->getVertDataArray(dm, CD_ORCO), /* may be nullptr */ | (const float(*)[3])dm->getVertDataArray(dm, CD_ORCO), /* may be nullptrptr */ | ||||
| /* result */ | /* result */ | ||||
| &dm->loopData, | &dm->loopData, | ||||
| dm->getNumLoops(dm), | dm->getNumLoops(dm), | ||||
| &dm->tangent_mask); | &dm->tangent_mask); | ||||
| } | } | ||||
| pvtangent = DM_get_loop_data_layer(dm, CD_TANGENT); | pvtangent = static_cast<float *>(DM_get_loop_data_layer(dm, CD_TANGENT)); | ||||
| } | } | ||||
| /* all threads shares the same custom bake data */ | /* all threads shares the same custom bake data */ | ||||
| if (initBakeData) { | if (initBakeData) { | ||||
| bake_data = initBakeData(bkr, ibuf); | bake_data = initBakeData(bkr, ibuf); | ||||
| } | } | ||||
| if (tot_thread > 1) { | if (tot_thread > 1) { | ||||
| BLI_threadpool_init(&threads, do_multires_bake_thread, tot_thread); | BLI_threadpool_init(&threads, do_multires_bake_thread, tot_thread); | ||||
| } | } | ||||
| handles = MEM_callocN(tot_thread * sizeof(MultiresBakeThread), "do_multires_bake handles"); | handles = MEM_cnew_array<MultiresBakeThread>(tot_thread, "do_multires_bake handles"); | ||||
| init_ccgdm_arrays(bkr->hires_dm); | init_ccgdm_arrays(bkr->hires_dm); | ||||
| /* faces queue */ | /* faces queue */ | ||||
| queue.cur_tri = 0; | queue.cur_tri = 0; | ||||
| queue.tot_tri = tot_tri; | queue.tot_tri = tot_tri; | ||||
| BLI_spin_init(&queue.spin); | BLI_spin_init(&queue.spin); | ||||
| /* fill in threads handles */ | /* fill in threads handles */ | ||||
| for (i = 0; i < tot_thread; i++) { | for (i = 0; i < tot_thread; i++) { | ||||
| MultiresBakeThread *handle = &handles[i]; | MultiresBakeThread *handle = &handles[i]; | ||||
| handle->bkr = bkr; | handle->bkr = bkr; | ||||
| handle->image = ima; | handle->image = ima; | ||||
| handle->queue = &queue; | handle->queue = &queue; | ||||
| handle->data.mpoly = mpoly; | handle->data.mpoly = mpoly; | ||||
| handle->data.material_indices = CustomData_get_layer_named( | handle->data.material_indices = static_cast<const int *>( | ||||
| &dm->polyData, CD_PROP_INT32, "material_index"); | CustomData_get_layer_named(&dm->polyData, CD_PROP_INT32, "material_index")); | ||||
| handle->data.mvert = mvert; | handle->data.mvert = mvert; | ||||
| handle->data.vert_normals = vert_normals; | handle->data.vert_normals = vert_normals; | ||||
| handle->data.mloopuv = mloopuv; | handle->data.mloopuv = mloopuv; | ||||
| BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset); | BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset); | ||||
| handle->data.mlooptri = mlooptri; | handle->data.mlooptri = mlooptri; | ||||
| handle->data.mloop = mloop; | handle->data.mloop = mloop; | ||||
| handle->data.pvtangent = pvtangent; | handle->data.pvtangent = pvtangent; | ||||
| handle->data.precomputed_normals = poly_normals; /* don't strictly need this */ | handle->data.precomputed_normals = poly_normals; /* don't strictly need this */ | ||||
| Show All 38 Lines | static void do_multires_bake(MultiresBakeRender *bkr, | ||||
| /* finalize baking */ | /* finalize baking */ | ||||
| if (freeBakeData) { | if (freeBakeData) { | ||||
| freeBakeData(bake_data); | freeBakeData(bake_data); | ||||
| } | } | ||||
| MEM_freeN(handles); | MEM_freeN(handles); | ||||
| BKE_id_free(NULL, temp_mesh); | BKE_id_free(nullptr, temp_mesh); | ||||
| } | } | ||||
| /* mode = 0: interpolate normals, | /* mode = 0: interpolate normals, | ||||
| * mode = 1: interpolate coord */ | * mode = 1: interpolate coord */ | ||||
| static void interp_bilinear_grid( | static void interp_bilinear_grid( | ||||
| CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3]) | CCGKey *key, CCGElem *grid, float crn_x, float crn_y, int mode, float res[3]) | ||||
| { | { | ||||
| int x0, x1, y0, y1; | int x0, x1, y0, y1; | ||||
| ▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | else { | ||||
| crn_y = (row * cell_side) + u * cell_side; | crn_y = (row * cell_side) + u * cell_side; | ||||
| crn_x = (col * cell_side) + v * cell_side; | crn_x = (col * cell_side) + v * cell_side; | ||||
| } | } | ||||
| CLAMP(crn_x, 0.0f, grid_size); | CLAMP(crn_x, 0.0f, grid_size); | ||||
| CLAMP(crn_y, 0.0f, grid_size); | CLAMP(crn_y, 0.0f, grid_size); | ||||
| if (n != NULL) { | if (n != nullptr) { | ||||
| interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n); | interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 0, n); | ||||
| } | } | ||||
| if (co != NULL) { | if (co != nullptr) { | ||||
| interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co); | interp_bilinear_grid(&key, grid_data[g_index + S], crn_x, crn_y, 1, co); | ||||
| } | } | ||||
| } | } | ||||
| /* mode = 0: interpolate normals, | /* mode = 0: interpolate normals, | ||||
| * mode = 1: interpolate coord */ | * mode = 1: interpolate coord */ | ||||
| static void interp_bilinear_mpoly(DerivedMesh *dm, | static void interp_bilinear_mpoly(DerivedMesh *dm, | ||||
| ▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* **************** Displacement Baker **************** */ | /* **************** Displacement Baker **************** */ | ||||
| static void *init_heights_data(MultiresBakeRender *bkr, ImBuf *ibuf) | static void *init_heights_data(MultiresBakeRender *bkr, ImBuf *ibuf) | ||||
| { | { | ||||
| MHeightBakeData *height_data; | MHeightBakeData *height_data; | ||||
| DerivedMesh *lodm = bkr->lores_dm; | DerivedMesh *lodm = bkr->lores_dm; | ||||
| BakeImBufuserData *userdata = ibuf->userdata; | BakeImBufuserData *userdata = static_cast<BakeImBufuserData *>(ibuf->userdata); | ||||
| if (userdata->displacement_buffer == NULL) { | if (userdata->displacement_buffer == nullptr) { | ||||
| userdata->displacement_buffer = MEM_callocN(sizeof(float) * ibuf->x * ibuf->y, | userdata->displacement_buffer = MEM_cnew_array<float>(ibuf->x * ibuf->y, | ||||
| "MultiresBake heights"); | "MultiresBake heights"); | ||||
| } | } | ||||
| height_data = MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData"); | height_data = MEM_cnew<MHeightBakeData>("MultiresBake heightData"); | ||||
| height_data->heights = userdata->displacement_buffer; | height_data->heights = userdata->displacement_buffer; | ||||
| if (!bkr->use_lores_mesh) { | if (!bkr->use_lores_mesh) { | ||||
| SubsurfModifierData smd = {{NULL}}; | SubsurfModifierData smd = {{nullptr}}; | ||||
| int ss_lvl = bkr->tot_lvl - bkr->lvl; | int ss_lvl = bkr->tot_lvl - bkr->lvl; | ||||
| CLAMP(ss_lvl, 0, 6); | CLAMP(ss_lvl, 0, 6); | ||||
| if (ss_lvl > 0) { | if (ss_lvl > 0) { | ||||
| smd.levels = smd.renderLevels = ss_lvl; | smd.levels = smd.renderLevels = ss_lvl; | ||||
| smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES; | smd.uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES; | ||||
| smd.quality = 3; | smd.quality = 3; | ||||
| height_data->ssdm = subsurf_make_derived_from_derived( | height_data->ssdm = subsurf_make_derived_from_derived( | ||||
| bkr->lores_dm, &smd, bkr->scene, NULL, 0); | bkr->lores_dm, &smd, bkr->scene, nullptr, SubsurfFlags(0)); | ||||
| init_ccgdm_arrays(height_data->ssdm); | init_ccgdm_arrays(height_data->ssdm); | ||||
| } | } | ||||
| } | } | ||||
| height_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); | height_data->orig_index_mp_to_orig = static_cast<const int *>( | ||||
| lodm->getPolyDataArray(lodm, CD_ORIGINDEX)); | |||||
| return (void *)height_data; | return (void *)height_data; | ||||
| } | } | ||||
| static void free_heights_data(void *bake_data) | static void free_heights_data(void *bake_data) | ||||
| { | { | ||||
| MHeightBakeData *height_data = (MHeightBakeData *)bake_data; | MHeightBakeData *height_data = (MHeightBakeData *)bake_data; | ||||
| Show All 20 Lines | static void apply_heights_callback(DerivedMesh *lores_dm, | ||||
| const float st[2], | const float st[2], | ||||
| float UNUSED(tangmat[3][3]), | float UNUSED(tangmat[3][3]), | ||||
| const int x, | const int x, | ||||
| const int y) | const int y) | ||||
| { | { | ||||
| const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index; | const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index; | ||||
| MLoop *mloop = lores_dm->getLoopArray(lores_dm); | MLoop *mloop = lores_dm->getLoopArray(lores_dm); | ||||
| MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly; | MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly; | ||||
| MLoopUV *mloopuv = lores_dm->getLoopDataArray(lores_dm, CD_MLOOPUV); | MLoopUV *mloopuv = static_cast<MLoopUV *>(lores_dm->getLoopDataArray(lores_dm, CD_MLOOPUV)); | ||||
| MHeightBakeData *height_data = (MHeightBakeData *)bake_data; | MHeightBakeData *height_data = (MHeightBakeData *)bake_data; | ||||
| MultiresBakeThread *thread_data = (MultiresBakeThread *)thread_data_v; | MultiresBakeThread *thread_data = (MultiresBakeThread *)thread_data_v; | ||||
| float uv[2], *st0, *st1, *st2, *st3; | float uv[2], *st0, *st1, *st2, *st3; | ||||
| int pixel = ibuf->x * y + x; | int pixel = ibuf->x * y + x; | ||||
| float vec[3], p0[3], p1[3], n[3], len; | float vec[3], p0[3], p1[3], n[3], len; | ||||
| /* ideally we would work on triangles only, however, we rely on quads to get orthogonal | /* ideally we would work on triangles only, however, we rely on quads to get orthogonal | ||||
| * coordinates for use in grid space (triangle barycentric is not orthogonal) */ | * coordinates for use in grid space (triangle barycentric is not orthogonal) */ | ||||
| Show All 9 Lines | else { | ||||
| st1 = mloopuv[lt->tri[1]].uv; | st1 = mloopuv[lt->tri[1]].uv; | ||||
| st2 = mloopuv[lt->tri[2]].uv; | st2 = mloopuv[lt->tri[2]].uv; | ||||
| resolve_tri_uv_v2(uv, st, st0, st1, st2); | resolve_tri_uv_v2(uv, st, st0, st1, st2); | ||||
| } | } | ||||
| clamp_v2(uv, 0.0f, 1.0f); | clamp_v2(uv, 0.0f, 1.0f); | ||||
| get_ccgdm_data( | get_ccgdm_data( | ||||
| lores_dm, hires_dm, height_data->orig_index_mp_to_orig, lvl, lt, uv[0], uv[1], p1, NULL); | lores_dm, hires_dm, height_data->orig_index_mp_to_orig, lvl, lt, uv[0], uv[1], p1, nullptr); | ||||
| if (height_data->ssdm) { | if (height_data->ssdm) { | ||||
| get_ccgdm_data(lores_dm, | get_ccgdm_data(lores_dm, | ||||
| height_data->ssdm, | height_data->ssdm, | ||||
| height_data->orig_index_mp_to_orig, | height_data->orig_index_mp_to_orig, | ||||
| 0, | 0, | ||||
| lt, | lt, | ||||
| uv[0], | uv[0], | ||||
| Show All 34 Lines | |||||
| /* **************** Normal Maps Baker **************** */ | /* **************** Normal Maps Baker **************** */ | ||||
| static void *init_normal_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf)) | static void *init_normal_data(MultiresBakeRender *bkr, ImBuf *UNUSED(ibuf)) | ||||
| { | { | ||||
| MNormalBakeData *normal_data; | MNormalBakeData *normal_data; | ||||
| DerivedMesh *lodm = bkr->lores_dm; | DerivedMesh *lodm = bkr->lores_dm; | ||||
| normal_data = MEM_callocN(sizeof(MNormalBakeData), "MultiresBake normalData"); | normal_data = MEM_cnew<MNormalBakeData>("MultiresBake normalData"); | ||||
| normal_data->orig_index_mp_to_orig = lodm->getPolyDataArray(lodm, CD_ORIGINDEX); | normal_data->orig_index_mp_to_orig = static_cast<const int *>( | ||||
| lodm->getPolyDataArray(lodm, CD_ORIGINDEX)); | |||||
| return (void *)normal_data; | return (void *)normal_data; | ||||
| } | } | ||||
| static void free_normal_data(void *bake_data) | static void free_normal_data(void *bake_data) | ||||
| { | { | ||||
| MNormalBakeData *normal_data = (MNormalBakeData *)bake_data; | MNormalBakeData *normal_data = (MNormalBakeData *)bake_data; | ||||
| Show All 17 Lines | static void apply_tangmat_callback(DerivedMesh *lores_dm, | ||||
| const int lvl, | const int lvl, | ||||
| const float st[2], | const float st[2], | ||||
| float tangmat[3][3], | float tangmat[3][3], | ||||
| const int x, | const int x, | ||||
| const int y) | const int y) | ||||
| { | { | ||||
| const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index; | const MLoopTri *lt = lores_dm->getLoopTriArray(lores_dm) + tri_index; | ||||
| MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly; | MPoly *mpoly = lores_dm->getPolyArray(lores_dm) + lt->poly; | ||||
| MLoopUV *mloopuv = lores_dm->getLoopDataArray(lores_dm, CD_MLOOPUV); | MLoopUV *mloopuv = static_cast<MLoopUV *>(lores_dm->getLoopDataArray(lores_dm, CD_MLOOPUV)); | ||||
| MNormalBakeData *normal_data = (MNormalBakeData *)bake_data; | MNormalBakeData *normal_data = (MNormalBakeData *)bake_data; | ||||
| float uv[2], *st0, *st1, *st2, *st3; | float uv[2], *st0, *st1, *st2, *st3; | ||||
| int pixel = ibuf->x * y + x; | int pixel = ibuf->x * y + x; | ||||
| float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5}; | float n[3], vec[3], tmp[3] = {0.5, 0.5, 0.5}; | ||||
| /* ideally we would work on triangles only, however, we rely on quads to get orthogonal | /* ideally we would work on triangles only, however, we rely on quads to get orthogonal | ||||
| * coordinates for use in grid space (triangle barycentric is not orthogonal) */ | * coordinates for use in grid space (triangle barycentric is not orthogonal) */ | ||||
| if (mpoly->totloop == 4) { | if (mpoly->totloop == 4) { | ||||
| st0 = mloopuv[mpoly->loopstart].uv; | st0 = mloopuv[mpoly->loopstart].uv; | ||||
| st1 = mloopuv[mpoly->loopstart + 1].uv; | st1 = mloopuv[mpoly->loopstart + 1].uv; | ||||
| st2 = mloopuv[mpoly->loopstart + 2].uv; | st2 = mloopuv[mpoly->loopstart + 2].uv; | ||||
| st3 = mloopuv[mpoly->loopstart + 3].uv; | st3 = mloopuv[mpoly->loopstart + 3].uv; | ||||
| resolve_quad_uv_v2(uv, st, st0, st1, st2, st3); | resolve_quad_uv_v2(uv, st, st0, st1, st2, st3); | ||||
| } | } | ||||
| else { | else { | ||||
| st0 = mloopuv[lt->tri[0]].uv; | st0 = mloopuv[lt->tri[0]].uv; | ||||
| st1 = mloopuv[lt->tri[1]].uv; | st1 = mloopuv[lt->tri[1]].uv; | ||||
| st2 = mloopuv[lt->tri[2]].uv; | st2 = mloopuv[lt->tri[2]].uv; | ||||
| resolve_tri_uv_v2(uv, st, st0, st1, st2); | resolve_tri_uv_v2(uv, st, st0, st1, st2); | ||||
| } | } | ||||
| clamp_v2(uv, 0.0f, 1.0f); | clamp_v2(uv, 0.0f, 1.0f); | ||||
| get_ccgdm_data( | get_ccgdm_data( | ||||
| lores_dm, hires_dm, normal_data->orig_index_mp_to_orig, lvl, lt, uv[0], uv[1], NULL, n); | lores_dm, hires_dm, normal_data->orig_index_mp_to_orig, lvl, lt, uv[0], uv[1], nullptr, n); | ||||
| mul_v3_m3v3(vec, tangmat, n); | mul_v3_m3v3(vec, tangmat, n); | ||||
| normalize_v3_length(vec, 0.5); | normalize_v3_length(vec, 0.5); | ||||
| add_v3_v3(vec, tmp); | add_v3_v3(vec, tmp); | ||||
| if (ibuf->rect_float) { | if (ibuf->rect_float) { | ||||
| float *rrgbf = ibuf->rect_float + pixel * 4; | float *rrgbf = ibuf->rect_float + pixel * 4; | ||||
| rrgbf[0] = vec[0]; | rrgbf[0] = vec[0]; | ||||
| ▲ Show 20 Lines • Show All 443 Lines • ▼ Show 20 Lines | for (int i = 0; i < bkr->ob_image.len; i++) { | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result) | static void bake_images(MultiresBakeRender *bkr, MultiresBakeResult *result) | ||||
| { | { | ||||
| LinkData *link; | LinkData *link; | ||||
| for (link = bkr->image.first; link; link = link->next) { | for (link = static_cast<LinkData *>(bkr->image.first); link; link = link->next) { | ||||
| Image *ima = (Image *)link->data; | Image *ima = (Image *)link->data; | ||||
| LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { | LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { | ||||
| ImageUser iuser; | ImageUser iuser; | ||||
| BKE_imageuser_default(&iuser); | BKE_imageuser_default(&iuser); | ||||
| iuser.tile = tile->tile_number; | iuser.tile = tile->tile_number; | ||||
| ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); | ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr); | ||||
| if (ibuf->x > 0 && ibuf->y > 0) { | if (ibuf->x > 0 && ibuf->y > 0) { | ||||
| BakeImBufuserData *userdata = MEM_callocN(sizeof(BakeImBufuserData), | BakeImBufuserData *userdata = MEM_cnew<BakeImBufuserData>("MultiresBake userdata"); | ||||
| "MultiresBake userdata"); | userdata->mask_buffer = MEM_cnew_array<char>(ibuf->y * ibuf->x, "MultiresBake imbuf mask"); | ||||
| userdata->mask_buffer = MEM_callocN(ibuf->y * ibuf->x, "MultiresBake imbuf mask"); | |||||
| ibuf->userdata = userdata; | ibuf->userdata = userdata; | ||||
| switch (bkr->mode) { | switch (bkr->mode) { | ||||
| case RE_BAKE_NORMALS: | case RE_BAKE_NORMALS: | ||||
| do_multires_bake(bkr, | do_multires_bake(bkr, | ||||
| ima, | ima, | ||||
| tile, | tile, | ||||
| ibuf, | ibuf, | ||||
| Show All 18 Lines | |||||
| #if 0 | #if 0 | ||||
| case RE_BAKE_AO: | case RE_BAKE_AO: | ||||
| do_multires_bake(bkr, ima, tile, ibuf, false, apply_ao_callback, init_ao_data, free_ao_data, result); | do_multires_bake(bkr, ima, tile, ibuf, false, apply_ao_callback, init_ao_data, free_ao_data, result); | ||||
| break; | break; | ||||
| #endif | #endif | ||||
| } | } | ||||
| } | } | ||||
| BKE_image_release_ibuf(ima, ibuf, NULL); | BKE_image_release_ibuf(ima, ibuf, nullptr); | ||||
| } | } | ||||
| ima->id.tag |= LIB_TAG_DOIT; | ima->id.tag |= LIB_TAG_DOIT; | ||||
| } | } | ||||
| } | } | ||||
| static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result) | static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result) | ||||
| { | { | ||||
| LinkData *link; | LinkData *link; | ||||
| bool use_displacement_buffer = bkr->mode == RE_BAKE_DISPLACEMENT; | bool use_displacement_buffer = bkr->mode == RE_BAKE_DISPLACEMENT; | ||||
| for (link = bkr->image.first; link; link = link->next) { | for (link = static_cast<LinkData *>(bkr->image.first); link; link = link->next) { | ||||
| Image *ima = (Image *)link->data; | Image *ima = (Image *)link->data; | ||||
| LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { | LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { | ||||
| ImageUser iuser; | ImageUser iuser; | ||||
| BKE_imageuser_default(&iuser); | BKE_imageuser_default(&iuser); | ||||
| iuser.tile = tile->tile_number; | iuser.tile = tile->tile_number; | ||||
| ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); | ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &iuser, nullptr); | ||||
| BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata; | BakeImBufuserData *userdata = (BakeImBufuserData *)ibuf->userdata; | ||||
| if (ibuf->x <= 0 || ibuf->y <= 0) { | if (ibuf->x <= 0 || ibuf->y <= 0) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (use_displacement_buffer) { | if (use_displacement_buffer) { | ||||
| bake_ibuf_normalize_displacement(ibuf, | bake_ibuf_normalize_displacement(ibuf, | ||||
| Show All 27 Lines | LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { | ||||
| if (ibuf->userdata) { | if (ibuf->userdata) { | ||||
| if (userdata->displacement_buffer) { | if (userdata->displacement_buffer) { | ||||
| MEM_freeN(userdata->displacement_buffer); | MEM_freeN(userdata->displacement_buffer); | ||||
| } | } | ||||
| MEM_freeN(userdata->mask_buffer); | MEM_freeN(userdata->mask_buffer); | ||||
| MEM_freeN(userdata); | MEM_freeN(userdata); | ||||
| ibuf->userdata = NULL; | ibuf->userdata = nullptr; | ||||
| } | } | ||||
| BKE_image_release_ibuf(ima, ibuf, NULL); | BKE_image_release_ibuf(ima, ibuf, nullptr); | ||||
| DEG_id_tag_update(&ima->id, 0); | DEG_id_tag_update(&ima->id, 0); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| void RE_multires_bake_images(MultiresBakeRender *bkr) | void RE_multires_bake_images(MultiresBakeRender *bkr) | ||||
| { | { | ||||
| MultiresBakeResult result; | MultiresBakeResult result; | ||||
| count_images(bkr); | count_images(bkr); | ||||
| bake_images(bkr, &result); | bake_images(bkr, &result); | ||||
| finish_images(bkr, &result); | finish_images(bkr, &result); | ||||
| } | } | ||||