Changeset View
Changeset View
Standalone View
Standalone View
source/blender/render/intern/bake.cc
- This file was moved from source/blender/render/intern/bake.c.
| Show First 20 Lines • Show All 330 Lines • ▼ Show 20 Lines | static bool cast_ray_highpoly(BVHTreeFromMesh *treeData, | ||||
| int hit_mesh = -1; | int hit_mesh = -1; | ||||
| float hit_distance_squared = max_ray_distance * max_ray_distance; | float hit_distance_squared = max_ray_distance * max_ray_distance; | ||||
| if (hit_distance_squared == 0.0f) { | if (hit_distance_squared == 0.0f) { | ||||
| /* No ray distance set, use maximum. */ | /* No ray distance set, use maximum. */ | ||||
| hit_distance_squared = FLT_MAX; | hit_distance_squared = FLT_MAX; | ||||
| } | } | ||||
| BVHTreeRayHit *hits; | BVHTreeRayHit *hits; | ||||
| hits = MEM_mallocN(sizeof(BVHTreeRayHit) * tot_highpoly, "Bake Highpoly to Lowpoly: BVH Rays"); | hits = static_cast<BVHTreeRayHit *>( | ||||
| MEM_mallocN(sizeof(BVHTreeRayHit) * tot_highpoly, "Bake Highpoly to Lowpoly: BVH Rays")); | |||||
| for (i = 0; i < tot_highpoly; i++) { | for (i = 0; i < tot_highpoly; i++) { | ||||
| float co_high[3], dir_high[3]; | float co_high[3], dir_high[3]; | ||||
| hits[i].index = -1; | hits[i].index = -1; | ||||
| /* TODO: we should use FLT_MAX here, but sweep-sphere code isn't prepared for that. */ | /* TODO: we should use FLT_MAX here, but sweep-sphere code isn't prepared for that. */ | ||||
| hits[i].dist = BVH_RAYCAST_DIST_MAX; | hits[i].dist = BVH_RAYCAST_DIST_MAX; | ||||
| ▲ Show 20 Lines • Show All 110 Lines • ▼ Show 20 Lines | static TriTessFace *mesh_calc_tri_tessface(Mesh *me, bool tangent, Mesh *me_eval) | ||||
| /* calculate normal for each polygon only once */ | /* calculate normal for each polygon only once */ | ||||
| uint mpoly_prev = UINT_MAX; | uint mpoly_prev = UINT_MAX; | ||||
| float no[3]; | float no[3]; | ||||
| const MVert *verts = BKE_mesh_verts(me); | const MVert *verts = BKE_mesh_verts(me); | ||||
| const MPoly *polys = BKE_mesh_polys(me); | const MPoly *polys = BKE_mesh_polys(me); | ||||
| const MLoop *loops = BKE_mesh_loops(me); | const MLoop *loops = BKE_mesh_loops(me); | ||||
| looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); | looptri = static_cast<MLoopTri *>(MEM_mallocN(sizeof(*looptri) * tottri, __func__)); | ||||
| triangles = MEM_callocN(sizeof(TriTessFace) * tottri, __func__); | triangles = static_cast<TriTessFace *>(MEM_callocN(sizeof(TriTessFace) * tottri, __func__)); | ||||
| const float(*precomputed_normals)[3] = BKE_mesh_poly_normals_are_dirty(me) ? | const float(*precomputed_normals)[3] = BKE_mesh_poly_normals_are_dirty(me) ? | ||||
| NULL : | nullptr : | ||||
| BKE_mesh_poly_normals_ensure(me); | BKE_mesh_poly_normals_ensure(me); | ||||
| const bool calculate_normal = precomputed_normals ? false : true; | const bool calculate_normal = precomputed_normals ? false : true; | ||||
| if (precomputed_normals != NULL) { | if (precomputed_normals != nullptr) { | ||||
| BKE_mesh_recalc_looptri_with_normals( | BKE_mesh_recalc_looptri_with_normals( | ||||
| loops, polys, verts, me->totloop, me->totpoly, looptri, precomputed_normals); | loops, polys, verts, me->totloop, me->totpoly, looptri, precomputed_normals); | ||||
| } | } | ||||
| else { | else { | ||||
| BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); | BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); | ||||
| } | } | ||||
| const TSpace *tspace = NULL; | const TSpace *tspace = nullptr; | ||||
| const float(*loop_normals)[3] = NULL; | const float(*loop_normals)[3] = nullptr; | ||||
| if (tangent) { | if (tangent) { | ||||
| BKE_mesh_ensure_normals_for_display(me_eval); | BKE_mesh_ensure_normals_for_display(me_eval); | ||||
| BKE_mesh_calc_normals_split(me_eval); | BKE_mesh_calc_normals_split(me_eval); | ||||
| BKE_mesh_calc_loop_tangents(me_eval, true, NULL, 0); | BKE_mesh_calc_loop_tangents(me_eval, true, nullptr, 0); | ||||
| tspace = CustomData_get_layer(&me_eval->ldata, CD_TANGENT); | tspace = static_cast<const TSpace *>(CustomData_get_layer(&me_eval->ldata, CD_TANGENT)); | ||||
| BLI_assert(tspace); | BLI_assert(tspace); | ||||
| loop_normals = CustomData_get_layer(&me_eval->ldata, CD_NORMAL); | loop_normals = static_cast<const float(*)[3]>( | ||||
| CustomData_get_layer(&me_eval->ldata, CD_NORMAL)); | |||||
| } | } | ||||
| const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me); | const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me); | ||||
| for (i = 0; i < tottri; i++) { | for (i = 0; i < tottri; i++) { | ||||
| const MLoopTri *lt = &looptri[i]; | const MLoopTri *lt = &looptri[i]; | ||||
| const MPoly *mp = &polys[lt->poly]; | const MPoly *mp = &polys[lt->poly]; | ||||
| triangles[i].mverts[0] = &verts[loops[lt->tri[0]].v]; | triangles[i].mverts[0] = &verts[loops[lt->tri[0]].v]; | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | bool RE_bake_pixels_populate_from_objects(struct Mesh *me_low, | ||||
| float mat_low[4][4], | float mat_low[4][4], | ||||
| float mat_cage[4][4], | float mat_cage[4][4], | ||||
| struct Mesh *me_cage) | struct Mesh *me_cage) | ||||
| { | { | ||||
| size_t i; | size_t i; | ||||
| int primitive_id; | int primitive_id; | ||||
| float u, v; | float u, v; | ||||
| float imat_low[4][4]; | float imat_low[4][4]; | ||||
| bool is_cage = me_cage != NULL; | bool is_cage = me_cage != nullptr; | ||||
| bool result = true; | bool result = true; | ||||
| Mesh *me_eval_low = NULL; | Mesh *me_eval_low = nullptr; | ||||
| Mesh **me_highpoly; | Mesh **me_highpoly; | ||||
| BVHTreeFromMesh *treeData; | BVHTreeFromMesh *treeData; | ||||
| /* NOTE: all coordinates are in local space. */ | /* NOTE: all coordinates are in local space. */ | ||||
| TriTessFace *tris_low = NULL; | TriTessFace *tris_low = nullptr; | ||||
| TriTessFace *tris_cage = NULL; | TriTessFace *tris_cage = nullptr; | ||||
| TriTessFace **tris_high; | TriTessFace **tris_high; | ||||
| /* Assume all low-poly tessfaces can be quads. */ | /* Assume all low-poly tessfaces can be quads. */ | ||||
| tris_high = MEM_callocN(sizeof(TriTessFace *) * tot_highpoly, "MVerts Highpoly Mesh Array"); | tris_high = MEM_cnew_array<TriTessFace *>(tot_highpoly, "MVerts Highpoly Mesh Array"); | ||||
| /* Assume all high-poly tessfaces are triangles. */ | /* Assume all high-poly tessfaces are triangles. */ | ||||
| me_highpoly = MEM_mallocN(sizeof(Mesh *) * tot_highpoly, "Highpoly Derived Meshes"); | me_highpoly = static_cast<Mesh **>( | ||||
| treeData = MEM_callocN(sizeof(BVHTreeFromMesh) * tot_highpoly, "Highpoly BVH Trees"); | MEM_mallocN(sizeof(Mesh *) * tot_highpoly, "Highpoly Derived Meshes")); | ||||
| treeData = MEM_cnew_array<BVHTreeFromMesh>(tot_highpoly, "Highpoly BVH Trees"); | |||||
| if (!is_cage) { | if (!is_cage) { | ||||
| me_eval_low = BKE_mesh_copy_for_eval(me_low, false); | me_eval_low = BKE_mesh_copy_for_eval(me_low, false); | ||||
| tris_low = mesh_calc_tri_tessface(me_low, true, me_eval_low); | tris_low = mesh_calc_tri_tessface(me_low, true, me_eval_low); | ||||
| } | } | ||||
| else if (is_custom_cage) { | else if (is_custom_cage) { | ||||
| tris_low = mesh_calc_tri_tessface(me_low, false, NULL); | tris_low = mesh_calc_tri_tessface(me_low, false, nullptr); | ||||
| tris_cage = mesh_calc_tri_tessface(me_cage, false, NULL); | tris_cage = mesh_calc_tri_tessface(me_cage, false, nullptr); | ||||
| } | } | ||||
| else { | else { | ||||
| tris_cage = mesh_calc_tri_tessface(me_cage, false, NULL); | tris_cage = mesh_calc_tri_tessface(me_cage, false, nullptr); | ||||
| } | } | ||||
| invert_m4_m4(imat_low, mat_low); | invert_m4_m4(imat_low, mat_low); | ||||
| for (i = 0; i < tot_highpoly; i++) { | for (i = 0; i < tot_highpoly; i++) { | ||||
| tris_high[i] = mesh_calc_tri_tessface(highpoly[i].me, false, NULL); | tris_high[i] = mesh_calc_tri_tessface(highpoly[i].me, false, nullptr); | ||||
| me_highpoly[i] = highpoly[i].me; | me_highpoly[i] = highpoly[i].me; | ||||
| BKE_mesh_runtime_looptri_ensure(me_highpoly[i]); | BKE_mesh_runtime_looptri_ensure(me_highpoly[i]); | ||||
| if (BKE_mesh_runtime_looptri_len(me_highpoly[i]) != 0) { | if (BKE_mesh_runtime_looptri_len(me_highpoly[i]) != 0) { | ||||
| /* Create a BVH-tree for each `highpoly` object. */ | /* Create a BVH-tree for each `highpoly` object. */ | ||||
| BKE_bvhtree_from_mesh_get(&treeData[i], me_highpoly[i], BVHTREE_FROM_LOOPTRI, 2); | BKE_bvhtree_from_mesh_get(&treeData[i], me_highpoly[i], BVHTREE_FROM_LOOPTRI, 2); | ||||
| if (treeData[i].tree == NULL) { | if (treeData[i].tree == nullptr) { | ||||
| printf("Baking: out of memory while creating BHVTree for object \"%s\"\n", | printf("Baking: out of memory while creating BHVTree for object \"%s\"\n", | ||||
| highpoly[i].ob->id.name + 2); | highpoly[i].ob->id.name + 2); | ||||
| result = false; | result = false; | ||||
| goto cleanup; | goto cleanup; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | for (i = 0; i < tot_highpoly; i++) { | ||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(tris_high); | MEM_freeN(tris_high); | ||||
| MEM_freeN(treeData); | MEM_freeN(treeData); | ||||
| MEM_freeN(me_highpoly); | MEM_freeN(me_highpoly); | ||||
| if (me_eval_low) { | if (me_eval_low) { | ||||
| BKE_id_free(NULL, me_eval_low); | BKE_id_free(nullptr, me_eval_low); | ||||
| } | } | ||||
| if (tris_low) { | if (tris_low) { | ||||
| MEM_freeN(tris_low); | MEM_freeN(tris_low); | ||||
| } | } | ||||
| if (tris_cage) { | if (tris_cage) { | ||||
| MEM_freeN(tris_cage); | MEM_freeN(tris_cage); | ||||
| } | } | ||||
| Show All 27 Lines | |||||
| void RE_bake_pixels_populate(Mesh *me, | void RE_bake_pixels_populate(Mesh *me, | ||||
| BakePixel pixel_array[], | BakePixel pixel_array[], | ||||
| const size_t pixels_num, | const size_t pixels_num, | ||||
| const BakeTargets *targets, | const BakeTargets *targets, | ||||
| const char *uv_layer) | const char *uv_layer) | ||||
| { | { | ||||
| const MLoopUV *mloopuv; | const MLoopUV *mloopuv; | ||||
| if ((uv_layer == NULL) || (uv_layer[0] == '\0')) { | if ((uv_layer == nullptr) || (uv_layer[0] == '\0')) { | ||||
| mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV); | mloopuv = static_cast<const MLoopUV *>(CustomData_get_layer(&me->ldata, CD_MLOOPUV)); | ||||
| } | } | ||||
| else { | else { | ||||
| int uv_id = CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer); | int uv_id = CustomData_get_named_layer(&me->ldata, CD_MLOOPUV, uv_layer); | ||||
| mloopuv = CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uv_id); | mloopuv = static_cast<const MLoopUV *>(CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uv_id)); | ||||
| } | } | ||||
| if (mloopuv == NULL) { | if (mloopuv == nullptr) { | ||||
| return; | return; | ||||
| } | } | ||||
| BakeDataZSpan bd; | BakeDataZSpan bd; | ||||
| bd.pixel_array = pixel_array; | bd.pixel_array = pixel_array; | ||||
| bd.zspan = MEM_callocN(sizeof(ZSpan) * targets->images_num, "bake zspan"); | bd.zspan = MEM_cnew_array<ZSpan>(targets->images_num, "bake zspan"); | ||||
| /* initialize all pixel arrays so we know which ones are 'blank' */ | /* initialize all pixel arrays so we know which ones are 'blank' */ | ||||
| for (int i = 0; i < pixels_num; i++) { | for (int i = 0; i < pixels_num; i++) { | ||||
| pixel_array[i].primitive_id = -1; | pixel_array[i].primitive_id = -1; | ||||
| pixel_array[i].object_id = 0; | pixel_array[i].object_id = 0; | ||||
| } | } | ||||
| for (int i = 0; i < targets->images_num; i++) { | for (int i = 0; i < targets->images_num; i++) { | ||||
| zbuf_alloc_span(&bd.zspan[i], targets->images[i].width, targets->images[i].height); | zbuf_alloc_span(&bd.zspan[i], targets->images[i].width, targets->images[i].height); | ||||
| } | } | ||||
| const int tottri = poly_to_tri_count(me->totpoly, me->totloop); | const int tottri = poly_to_tri_count(me->totpoly, me->totloop); | ||||
| MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); | MLoopTri *looptri = static_cast<MLoopTri *>(MEM_mallocN(sizeof(*looptri) * tottri, __func__)); | ||||
| const MVert *verts = BKE_mesh_verts(me); | const MVert *verts = BKE_mesh_verts(me); | ||||
| const MPoly *polys = BKE_mesh_polys(me); | const MPoly *polys = BKE_mesh_polys(me); | ||||
| const MLoop *loops = BKE_mesh_loops(me); | const MLoop *loops = BKE_mesh_loops(me); | ||||
| BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); | BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); | ||||
| const int *material_indices = BKE_mesh_material_indices(me); | const int *material_indices = BKE_mesh_material_indices(me); | ||||
| const int materials_num = targets->materials_num; | const int materials_num = targets->materials_num; | ||||
| ▲ Show 20 Lines • Show All 201 Lines • ▼ Show 20 Lines | for (i = 0; i < pixels_num; i++) { | ||||
| /* save back the values */ | /* save back the values */ | ||||
| normal_compress(&result[offset], nor, normal_swizzle); | normal_compress(&result[offset], nor, normal_swizzle); | ||||
| } | } | ||||
| /* garbage collection */ | /* garbage collection */ | ||||
| MEM_freeN(triangles); | MEM_freeN(triangles); | ||||
| if (me_eval) { | if (me_eval) { | ||||
| BKE_id_free(NULL, me_eval); | BKE_id_free(nullptr, me_eval); | ||||
| } | } | ||||
| } | } | ||||
| void RE_bake_normal_world_to_object(const BakePixel pixel_array[], | void RE_bake_normal_world_to_object(const BakePixel pixel_array[], | ||||
| const size_t pixels_num, | const size_t pixels_num, | ||||
| const int depth, | const int depth, | ||||
| float result[], | float result[], | ||||
| struct Object *ob, | struct Object *ob, | ||||
| ▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | void RE_bake_ibuf_clear(Image *image, const bool is_tangent) | ||||
| ImBuf *ibuf; | ImBuf *ibuf; | ||||
| void *lock; | void *lock; | ||||
| const float vec_alpha[4] = {0.0f, 0.0f, 0.0f, 0.0f}; | 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 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_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 nor_solid[4] = {0.5f, 0.5f, 1.0f, 1.0f}; | ||||
| ibuf = BKE_image_acquire_ibuf(image, NULL, &lock); | ibuf = BKE_image_acquire_ibuf(image, nullptr, &lock); | ||||
| BLI_assert(ibuf); | BLI_assert(ibuf); | ||||
| if (is_tangent) { | if (is_tangent) { | ||||
| IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid); | IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? nor_alpha : nor_solid); | ||||
| } | } | ||||
| else { | else { | ||||
| IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); | IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 47 Lines • Show Last 20 Lines | |||||