Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/key.c
| Show First 20 Lines • Show All 992 Lines • ▼ Show 20 Lines | |||||
| MEM_SAFE_FREE(kb->data); | MEM_SAFE_FREE(kb->data); | ||||
| kb->data = MEM_malloc_arrayN((size_t)len, (size_t)key->elemsize, __func__); | kb->data = MEM_malloc_arrayN((size_t)len, (size_t)key->elemsize, __func__); | ||||
| kb->totelem = len; | kb->totelem = len; | ||||
| BKE_keyblock_update_from_mesh(me, kb); | BKE_keyblock_update_from_mesh(me, kb); | ||||
| } | } | ||||
| void BKE_keyblock_convert_to_mesh(KeyBlock *kb, Mesh *me) | void BKE_keyblock_convert_to_mesh(KeyBlock *kb, struct MVert *mvert, int totvert) | ||||
| { | { | ||||
| MVert *mvert; | |||||
| const float(*fp)[3]; | const float(*fp)[3]; | ||||
| int a, tot; | int a, tot; | ||||
| mvert = me->mvert; | |||||
| fp = kb->data; | fp = kb->data; | ||||
| tot = min_ii(kb->totelem, me->totvert); | tot = min_ii(kb->totelem, totvert); | ||||
| for (a = 0; a < tot; a++, fp++, mvert++) { | for (a = 0; a < tot; a++, fp++, mvert++) { | ||||
| copy_v3_v3(mvert->co, *fp); | copy_v3_v3(mvert->co, *fp); | ||||
| } | } | ||||
| } | } | ||||
| void BKE_keyblock_mesh_calc_normals(struct KeyBlock *kb, | void BKE_keyblock_mesh_calc_normals(struct KeyBlock *kb, | ||||
| struct Mesh *mesh, | struct Mesh *mesh, | ||||
| float (*r_vertnors)[3], | float (*r_vertnors)[3], | ||||
| float (*r_polynors)[3], | float (*r_polynors)[3], | ||||
| float (*r_loopnors)[3]) | float (*r_loopnors)[3]) | ||||
| { | { | ||||
| /* We use a temp, shallow copy of mesh to work. */ | |||||
| Mesh me; | |||||
| bool free_polynors = false; | |||||
| if (r_vertnors == NULL && r_polynors == NULL && r_loopnors == NULL) { | if (r_vertnors == NULL && r_polynors == NULL && r_loopnors == NULL) { | ||||
| return; | return; | ||||
| } | } | ||||
| me = *mesh; | MVert *mvert = MEM_dupallocN(mesh->mvert); | ||||
| me.mvert = MEM_dupallocN(mesh->mvert); | BKE_keyblock_convert_to_mesh(kb, mesh->mvert, mesh->totvert); | ||||
| CustomData_reset(&me.vdata); | |||||
| CustomData_reset(&me.edata); | const bool loop_normals_needed = r_loopnors != NULL; | ||||
| CustomData_reset(&me.pdata); | const bool vert_normals_needed = r_vertnors != NULL || loop_normals_needed; | ||||
| CustomData_reset(&me.ldata); | const bool poly_normals_needed = r_polynors != NULL || vert_normals_needed || | ||||
| CustomData_reset(&me.fdata); | loop_normals_needed; | ||||
| BKE_keyblock_convert_to_mesh(kb, &me); | float(*vert_normals)[3] = r_vertnors; | ||||
| float(*poly_normals)[3] = r_polynors; | |||||
| if (r_polynors == NULL && r_loopnors != NULL) { | bool free_vert_normals = false; | ||||
| r_polynors = MEM_mallocN(sizeof(float[3]) * me.totpoly, __func__); | bool free_poly_normals = false; | ||||
| free_polynors = true; | if (vert_normals_needed && r_vertnors == NULL) { | ||||
| } | vert_normals = MEM_malloc_arrayN(mesh->totvert, sizeof(float[3]), __func__); | ||||
| free_vert_normals = true; | |||||
| const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); | } | ||||
| if (r_vertnors) { | if (poly_normals_needed && r_polynors == NULL) { | ||||
| memcpy(r_vertnors, vert_normals, sizeof(float[3]) * me.totvert); | poly_normals = MEM_malloc_arrayN(mesh->totpoly, sizeof(float[3]), __func__); | ||||
| } | free_poly_normals = true; | ||||
| } | |||||
| const float(*face_normals)[3] = BKE_mesh_poly_normals_ensure(mesh); | |||||
| memcpy(r_polynors, face_normals, sizeof(float[3]) * me.totpoly); | if (poly_normals_needed) { | ||||
| BKE_mesh_calc_normals_poly(mvert, | |||||
| if (r_loopnors) { | mesh->totvert, | ||||
| mesh->mloop, | |||||
| mesh->totloop, | |||||
| mesh->mpoly, | |||||
| mesh->totpoly, | |||||
| poly_normals); | |||||
| } | |||||
| if (vert_normals_needed) { | |||||
| BKE_mesh_calc_normals_poly_and_vertex(mvert, | |||||
| mesh->totvert, | |||||
| mesh->mloop, | |||||
| mesh->totloop, | |||||
| mesh->mpoly, | |||||
| mesh->totpoly, | |||||
| poly_normals, | |||||
| vert_normals); | |||||
| } | |||||
| if (loop_normals_needed) { | |||||
| short(*clnors)[2] = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); /* May be NULL. */ | short(*clnors)[2] = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL); /* May be NULL. */ | ||||
| BKE_mesh_normals_loop_split(mesh->mvert, | |||||
| BKE_mesh_normals_loop_split(me.mvert, | |||||
| vert_normals, | vert_normals, | ||||
| me.totvert, | mesh->totvert, | ||||
| me.medge, | mesh->medge, | ||||
| me.totedge, | mesh->totedge, | ||||
| me.mloop, | mesh->mloop, | ||||
| r_loopnors, | r_loopnors, | ||||
| me.totloop, | mesh->totloop, | ||||
| me.mpoly, | mesh->mpoly, | ||||
| face_normals, | poly_normals, | ||||
| me.totpoly, | mesh->totpoly, | ||||
| (me.flag & ME_AUTOSMOOTH) != 0, | (mesh->flag & ME_AUTOSMOOTH) != 0, | ||||
| me.smoothresh, | mesh->smoothresh, | ||||
| NULL, | NULL, | ||||
| clnors, | clnors, | ||||
| NULL); | NULL); | ||||
| } | } | ||||
| CustomData_free(&me.vdata, me.totvert); | if (free_vert_normals) { | ||||
| CustomData_free(&me.edata, me.totedge); | MEM_freeN(vert_normals); | ||||
| CustomData_free(&me.pdata, me.totpoly); | } | ||||
| CustomData_free(&me.ldata, me.totloop); | if (free_poly_normals) { | ||||
| CustomData_free(&me.fdata, me.totface); | MEM_freeN(poly_normals); | ||||
| MEM_freeN(me.mvert); | |||||
| if (free_polynors) { | |||||
| MEM_freeN(r_polynors); | |||||
| } | } | ||||
| MEM_freeN(mvert); | |||||
| } | } | ||||
| /************************* raw coords ************************/ | /************************* raw coords ************************/ | ||||
| void BKE_keyblock_update_from_vertcos(Object *ob, KeyBlock *kb, const float (*vertCos)[3]) | void BKE_keyblock_update_from_vertcos(Object *ob, KeyBlock *kb, const float (*vertCos)[3]) | ||||
| { | { | ||||
| const float(*co)[3] = vertCos; | const float(*co)[3] = vertCos; | ||||
| float *fp = kb->data; | float *fp = kb->data; | ||||
| ▲ Show 20 Lines • Show All 280 Lines • Show Last 20 Lines | |||||