diff options
author | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:17:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2019-04-17 07:21:24 +0300 |
commit | e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch) | |
tree | 8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/bmesh/intern/bmesh_interp.c | |
parent | b3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff) |
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211.
For details on usage and instructions for migrating branches
without conflicts, see:
https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_interp.c')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_interp.c | 1823 |
1 files changed, 938 insertions, 885 deletions
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 11d6df430c3..c58521297dd 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -40,41 +40,45 @@ #include "intern/bmesh_private.h" /* edge and vertex share, currently theres no need to have different logic */ -static void bm_data_interp_from_elem( - CustomData *data_layer, const BMElem *ele_src_1, const BMElem *ele_src_2, - BMElem *ele_dst, const float fac) +static void bm_data_interp_from_elem(CustomData *data_layer, + const BMElem *ele_src_1, + const BMElem *ele_src_2, + BMElem *ele_dst, + const float fac) { - if (ele_src_1->head.data && ele_src_2->head.data) { - /* first see if we can avoid interpolation */ - if (fac <= 0.0f) { - if (ele_src_1 == ele_dst) { - /* do nothing */ - } - else { - CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data); - CustomData_bmesh_copy_data(data_layer, data_layer, ele_src_1->head.data, &ele_dst->head.data); - } - } - else if (fac >= 1.0f) { - if (ele_src_2 == ele_dst) { - /* do nothing */ - } - else { - CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data); - CustomData_bmesh_copy_data(data_layer, data_layer, ele_src_2->head.data, &ele_dst->head.data); - } - } - else { - const void *src[2]; - float w[2]; - - src[0] = ele_src_1->head.data; - src[1] = ele_src_2->head.data; - w[0] = 1.0f - fac; - w[1] = fac; - CustomData_bmesh_interp(data_layer, src, w, NULL, 2, ele_dst->head.data); - } - } + if (ele_src_1->head.data && ele_src_2->head.data) { + /* first see if we can avoid interpolation */ + if (fac <= 0.0f) { + if (ele_src_1 == ele_dst) { + /* do nothing */ + } + else { + CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data); + CustomData_bmesh_copy_data( + data_layer, data_layer, ele_src_1->head.data, &ele_dst->head.data); + } + } + else if (fac >= 1.0f) { + if (ele_src_2 == ele_dst) { + /* do nothing */ + } + else { + CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data); + CustomData_bmesh_copy_data( + data_layer, data_layer, ele_src_2->head.data, &ele_dst->head.data); + } + } + else { + const void *src[2]; + float w[2]; + + src[0] = ele_src_1->head.data; + src[1] = ele_src_2->head.data; + w[0] = 1.0f - fac; + w[1] = fac; + CustomData_bmesh_interp(data_layer, src, w, NULL, 2, ele_dst->head.data); + } + } } /** @@ -84,9 +88,11 @@ static void bm_data_interp_from_elem( * * \note This is an exact match to #BM_data_interp_from_edges */ -void BM_data_interp_from_verts(BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v_dst, const float fac) +void BM_data_interp_from_verts( + BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v_dst, const float fac) { - bm_data_interp_from_elem(&bm->vdata, (const BMElem *)v_src_1, (const BMElem *)v_src_2, (BMElem *)v_dst, fac); + bm_data_interp_from_elem( + &bm->vdata, (const BMElem *)v_src_1, (const BMElem *)v_src_2, (BMElem *)v_dst, fac); } /** @@ -96,9 +102,11 @@ void BM_data_interp_from_verts(BMesh *bm, const BMVert *v_src_1, const BMVert *v * * \note This is an exact match to #BM_data_interp_from_verts */ -void BM_data_interp_from_edges(BMesh *bm, const BMEdge *e_src_1, const BMEdge *e_src_2, BMEdge *e_dst, const float fac) +void BM_data_interp_from_edges( + BMesh *bm, const BMEdge *e_src_1, const BMEdge *e_src_2, BMEdge *e_dst, const float fac) { - bm_data_interp_from_elem(&bm->edata, (const BMElem *)e_src_1, (const BMElem *)e_src_2, (BMElem *)e_dst, fac); + bm_data_interp_from_elem( + &bm->edata, (const BMElem *)e_src_1, (const BMElem *)e_src_2, (BMElem *)e_dst, fac); } /** @@ -109,7 +117,7 @@ void BM_data_interp_from_edges(BMesh *bm, const BMEdge *e_src_1, const BMEdge *e */ static void UNUSED_FUNCTION(BM_Data_Vert_Average)(BMesh *UNUSED(bm), BMFace *UNUSED(f)) { - // BMIter iter; + // BMIter iter; } /** @@ -118,44 +126,48 @@ static void UNUSED_FUNCTION(BM_Data_Vert_Average)(BMesh *UNUSED(bm), BMFace *UNU * Walks around the faces of \a e and interpolates * the loop data between two sources. */ -void BM_data_interp_face_vert_edge( - BMesh *bm, const BMVert *v_src_1, const BMVert *UNUSED(v_src_2), BMVert *v, BMEdge *e, const float fac) +void BM_data_interp_face_vert_edge(BMesh *bm, + const BMVert *v_src_1, + const BMVert *UNUSED(v_src_2), + BMVert *v, + BMEdge *e, + const float fac) { - float w[2]; - BMLoop *l_v1 = NULL, *l_v = NULL, *l_v2 = NULL; - BMLoop *l_iter = NULL; - - if (!e->l) { - return; - } - - w[1] = 1.0f - fac; - w[0] = fac; - - l_iter = e->l; - do { - if (l_iter->v == v_src_1) { - l_v1 = l_iter; - l_v = l_v1->next; - l_v2 = l_v->next; - } - else if (l_iter->v == v) { - l_v1 = l_iter->next; - l_v = l_iter; - l_v2 = l_iter->prev; - } - - if (!l_v1 || !l_v2) { - return; - } - else { - const void *src[2]; - src[0] = l_v1->head.data; - src[1] = l_v2->head.data; - - CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_v->head.data); - } - } while ((l_iter = l_iter->radial_next) != e->l); + float w[2]; + BMLoop *l_v1 = NULL, *l_v = NULL, *l_v2 = NULL; + BMLoop *l_iter = NULL; + + if (!e->l) { + return; + } + + w[1] = 1.0f - fac; + w[0] = fac; + + l_iter = e->l; + do { + if (l_iter->v == v_src_1) { + l_v1 = l_iter; + l_v = l_v1->next; + l_v2 = l_v->next; + } + else if (l_iter->v == v) { + l_v1 = l_iter->next; + l_v = l_iter; + l_v2 = l_iter->prev; + } + + if (!l_v1 || !l_v2) { + return; + } + else { + const void *src[2]; + src[0] = l_v1->head.data; + src[1] = l_v2->head.data; + + CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_v->head.data); + } + } while ((l_iter = l_iter->radial_next) != e->l); } /** @@ -166,61 +178,65 @@ void BM_data_interp_face_vert_edge( * * \note Only handles loop customdata. multires is handled. */ -void BM_face_interp_from_face_ex( - BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex, - const void **blocks_l, const void **blocks_v, float (*cos_2d)[2], float axis_mat[3][3]) +void BM_face_interp_from_face_ex(BMesh *bm, + BMFace *f_dst, + const BMFace *f_src, + const bool do_vertex, + const void **blocks_l, + const void **blocks_v, + float (*cos_2d)[2], + float axis_mat[3][3]) { - BMLoop *l_iter; - BMLoop *l_first; - - float *w = BLI_array_alloca(w, f_src->len); - float co[2]; - int i; - - if (f_src != f_dst) { - BM_elem_attrs_copy(bm, bm, f_src, f_dst); - } - - /* interpolate */ - i = 0; - l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst); - do { - mul_v2_m3v3(co, axis_mat, l_iter->v->co); - interp_weights_poly_v2(w, cos_2d, f_src->len, co); - CustomData_bmesh_interp(&bm->ldata, blocks_l, w, NULL, f_src->len, l_iter->head.data); - if (do_vertex) { - CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, f_src->len, l_iter->v->head.data); - } - } while ((void)i++, (l_iter = l_iter->next) != l_first); + BMLoop *l_iter; + BMLoop *l_first; + + float *w = BLI_array_alloca(w, f_src->len); + float co[2]; + int i; + + if (f_src != f_dst) { + BM_elem_attrs_copy(bm, bm, f_src, f_dst); + } + + /* interpolate */ + i = 0; + l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst); + do { + mul_v2_m3v3(co, axis_mat, l_iter->v->co); + interp_weights_poly_v2(w, cos_2d, f_src->len, co); + CustomData_bmesh_interp(&bm->ldata, blocks_l, w, NULL, f_src->len, l_iter->head.data); + if (do_vertex) { + CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, f_src->len, l_iter->v->head.data); + } + } while ((void)i++, (l_iter = l_iter->next) != l_first); } void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex) { - BMLoop *l_iter; - BMLoop *l_first; - - const void **blocks_l = BLI_array_alloca(blocks_l, f_src->len); - const void **blocks_v = do_vertex ? BLI_array_alloca(blocks_v, f_src->len) : NULL; - float (*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len); - float axis_mat[3][3]; /* use normal to transform into 2d xy coords */ - int i; - - /* convert the 3d coords into 2d for projection */ - BLI_assert(BM_face_is_normal_valid(f_src)); - axis_dominant_v3_to_m3(axis_mat, f_src->no); - - i = 0; - l_iter = l_first = BM_FACE_FIRST_LOOP(f_src); - do { - mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co); - blocks_l[i] = l_iter->head.data; - if (do_vertex) { - blocks_v[i] = l_iter->v->head.data; - } - } while ((void)i++, (l_iter = l_iter->next) != l_first); - - BM_face_interp_from_face_ex(bm, f_dst, f_src, do_vertex, - blocks_l, blocks_v, cos_2d, axis_mat); + BMLoop *l_iter; + BMLoop *l_first; + + const void **blocks_l = BLI_array_alloca(blocks_l, f_src->len); + const void **blocks_v = do_vertex ? BLI_array_alloca(blocks_v, f_src->len) : NULL; + float(*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len); + float axis_mat[3][3]; /* use normal to transform into 2d xy coords */ + int i; + + /* convert the 3d coords into 2d for projection */ + BLI_assert(BM_face_is_normal_valid(f_src)); + axis_dominant_v3_to_m3(axis_mat, f_src->no); + + i = 0; + l_iter = l_first = BM_FACE_FIRST_LOOP(f_src); + do { + mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co); + blocks_l[i] = l_iter->head.data; + if (do_vertex) { + blocks_v[i] = l_iter->v->head.data; + } + } while ((void)i++, (l_iter = l_iter->next) != l_first); + + BM_face_interp_from_face_ex(bm, f_dst, f_src, do_vertex, blocks_l, blocks_v, cos_2d, axis_mat); } /** @@ -237,283 +253,318 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, con * y * </pre> */ -static int compute_mdisp_quad( - const BMLoop *l, const float l_f_center[3], - float v1[3], float v2[3], float v3[3], float v4[3], - float e1[3], float e2[3]) +static int compute_mdisp_quad(const BMLoop *l, + const float l_f_center[3], + float v1[3], + float v2[3], + float v3[3], + float v4[3], + float e1[3], + float e2[3]) { - float n[3], p[3]; + float n[3], p[3]; #ifndef NDEBUG - { - float cent[3]; - /* computer center */ - BM_face_calc_center_median(l->f, cent); - BLI_assert(equals_v3v3(cent, l_f_center)); - } + { + float cent[3]; + /* computer center */ + BM_face_calc_center_median(l->f, cent); + BLI_assert(equals_v3v3(cent, l_f_center)); + } #endif - mid_v3_v3v3(p, l->prev->v->co, l->v->co); - mid_v3_v3v3(n, l->next->v->co, l->v->co); + mid_v3_v3v3(p, l->prev->v->co, l->v->co); + mid_v3_v3v3(n, l->next->v->co, l->v->co); - copy_v3_v3(v1, l_f_center); - copy_v3_v3(v2, p); - copy_v3_v3(v3, l->v->co); - copy_v3_v3(v4, n); + copy_v3_v3(v1, l_f_center); + copy_v3_v3(v2, p); + copy_v3_v3(v3, l->v->co); + copy_v3_v3(v4, n); - sub_v3_v3v3(e1, v2, v1); - sub_v3_v3v3(e2, v3, v4); + sub_v3_v3v3(e1, v2, v1); + sub_v3_v3v3(e2, v3, v4); - return 1; + return 1; } -static bool quad_co( - const float v1[3], const float v2[3], const float v3[3], const float v4[3], - const float p[3], const float n[3], - float r_uv[2]) +static bool quad_co(const float v1[3], + const float v2[3], + const float v3[3], + const float v4[3], + const float p[3], + const float n[3], + float r_uv[2]) { - float projverts[5][3], n2[3]; - float origin[2] = {0.0f, 0.0f}; - int i; + float projverts[5][3], n2[3]; + float origin[2] = {0.0f, 0.0f}; + int i; - /* project points into 2d along normal */ - copy_v3_v3(projverts[0], v1); - copy_v3_v3(projverts[1], v2); - copy_v3_v3(projverts[2], v3); - copy_v3_v3(projverts[3], v4); - copy_v3_v3(projverts[4], p); + /* project points into 2d along normal */ + copy_v3_v3(projverts[0], v1); + copy_v3_v3(projverts[1], v2); + copy_v3_v3(projverts[2], v3); + copy_v3_v3(projverts[3], v4); + copy_v3_v3(projverts[4], p); - normal_quad_v3(n2, projverts[0], projverts[1], projverts[2], projverts[3]); + normal_quad_v3(n2, projverts[0], projverts[1], projverts[2], projverts[3]); - if (dot_v3v3(n, n2) < -FLT_EPSILON) { - return false; - } + if (dot_v3v3(n, n2) < -FLT_EPSILON) { + return false; + } - /* rotate */ - poly_rotate_plane(n, projverts, 5); + /* rotate */ + poly_rotate_plane(n, projverts, 5); - /* subtract origin */ - for (i = 0; i < 4; i++) { - sub_v2_v2(projverts[i], projverts[4]); - } + /* subtract origin */ + for (i = 0; i < 4; i++) { + sub_v2_v2(projverts[i], projverts[4]); + } - if (!isect_point_quad_v2(origin, projverts[0], projverts[1], projverts[2], projverts[3])) { - return false; - } + if (!isect_point_quad_v2(origin, projverts[0], projverts[1], projverts[2], projverts[3])) { + return false; + } - resolve_quad_uv_v2(r_uv, origin, projverts[0], projverts[3], projverts[2], projverts[1]); + resolve_quad_uv_v2(r_uv, origin, projverts[0], projverts[3], projverts[2], projverts[1]); - return true; + return true; } -static void mdisp_axis_from_quad( - float v1[3], float v2[3], float UNUSED(v3[3]), float v4[3], - float r_axis_x[3], float r_axis_y[3]) +static void mdisp_axis_from_quad(float v1[3], + float v2[3], + float UNUSED(v3[3]), + float v4[3], + float r_axis_x[3], + float r_axis_y[3]) { - sub_v3_v3v3(r_axis_x, v4, v1); - sub_v3_v3v3(r_axis_y, v2, v1); + sub_v3_v3v3(r_axis_x, v4, v1); + sub_v3_v3v3(r_axis_y, v2, v1); - normalize_v3(r_axis_x); - normalize_v3(r_axis_y); + normalize_v3(r_axis_x); + normalize_v3(r_axis_y); } /* tl is loop to project onto, l is loop whose internal displacement, co, is being * projected. x and y are location in loop's mdisps grid of point co. */ -static bool mdisp_in_mdispquad( - BMLoop *l_src, BMLoop *l_dst, const float l_dst_f_center[3], - const float p[3], int res, - float r_axis_x[3], float r_axis_y[3], float r_uv[2]) +static bool mdisp_in_mdispquad(BMLoop *l_src, + BMLoop *l_dst, + const float l_dst_f_center[3], + const float p[3], + int res, + float r_axis_x[3], + float r_axis_y[3], + float r_uv[2]) { - float v1[3], v2[3], c[3], v3[3], v4[3], e1[3], e2[3]; - float eps = FLT_EPSILON * 4000; - - if (is_zero_v3(l_src->v->no)) { - BM_vert_normal_update_all(l_src->v); - } - if (is_zero_v3(l_dst->v->no)) { - BM_vert_normal_update_all(l_dst->v); - } - - compute_mdisp_quad(l_dst, l_dst_f_center, v1, v2, v3, v4, e1, e2); - - /* expand quad a bit */ - mid_v3_v3v3v3v3(c, v1, v2, v3, v4); - - sub_v3_v3(v1, c); sub_v3_v3(v2, c); - sub_v3_v3(v3, c); sub_v3_v3(v4, c); - mul_v3_fl(v1, 1.0f + eps); mul_v3_fl(v2, 1.0f + eps); - mul_v3_fl(v3, 1.0f + eps); mul_v3_fl(v4, 1.0f + eps); - add_v3_v3(v1, c); add_v3_v3(v2, c); - add_v3_v3(v3, c); add_v3_v3(v4, c); - - if (!quad_co(v1, v2, v3, v4, p, l_src->v->no, r_uv)) { - return 0; - } - - mul_v2_fl(r_uv, (float)(res - 1)); - - mdisp_axis_from_quad(v1, v2, v3, v4, r_axis_x, r_axis_y); - - return 1; + float v1[3], v2[3], c[3], v3[3], v4[3], e1[3], e2[3]; + float eps = FLT_EPSILON * 4000; + + if (is_zero_v3(l_src->v->no)) { + BM_vert_normal_update_all(l_src->v); + } + if (is_zero_v3(l_dst->v->no)) { + BM_vert_normal_update_all(l_dst->v); + } + + compute_mdisp_quad(l_dst, l_dst_f_center, v1, v2, v3, v4, e1, e2); + + /* expand quad a bit */ + mid_v3_v3v3v3v3(c, v1, v2, v3, v4); + + sub_v3_v3(v1, c); + sub_v3_v3(v2, c); + sub_v3_v3(v3, c); + sub_v3_v3(v4, c); + mul_v3_fl(v1, 1.0f + eps); + mul_v3_fl(v2, 1.0f + eps); + mul_v3_fl(v3, 1.0f + eps); + mul_v3_fl(v4, 1.0f + eps); + add_v3_v3(v1, c); + add_v3_v3(v2, c); + add_v3_v3(v3, c); + add_v3_v3(v4, c); + + if (!quad_co(v1, v2, v3, v4, p, l_src->v->no, r_uv)) { + return 0; + } + + mul_v2_fl(r_uv, (float)(res - 1)); + + mdisp_axis_from_quad(v1, v2, v3, v4, r_axis_x, r_axis_y); + + return 1; } -static float bm_loop_flip_equotion( - float mat[2][2], float b[2], const float target_axis_x[3], const float target_axis_y[3], - const float coord[3], int i, int j) +static float bm_loop_flip_equotion(float mat[2][2], + float b[2], + const float target_axis_x[3], + const float target_axis_y[3], + const float coord[3], + int i, + int j) { - mat[0][0] = target_axis_x[i]; - mat[0][1] = target_axis_y[i]; - mat[1][0] = target_axis_x[j]; - mat[1][1] = target_axis_y[j]; - b[0] = coord[i]; - b[1] = coord[j]; - - return cross_v2v2(mat[0], mat[1]); + mat[0][0] = target_axis_x[i]; + mat[0][1] = target_axis_y[i]; + mat[1][0] = target_axis_x[j]; + mat[1][1] = target_axis_y[j]; + b[0] = coord[i]; + b[1] = coord[j]; + + return cross_v2v2(mat[0], mat[1]); } -static void bm_loop_flip_disp( - const float source_axis_x[3], const float source_axis_y[3], - const float target_axis_x[3], const float target_axis_y[3], float disp[3]) +static void bm_loop_flip_disp(const float source_axis_x[3], + const float source_axis_y[3], + const float target_axis_x[3], + const float target_axis_y[3], + float disp[3]) { - float vx[3], vy[3], coord[3]; - float n[3], vec[3]; - float b[2], mat[2][2], d; - - mul_v3_v3fl(vx, source_axis_x, disp[0]); - mul_v3_v3fl(vy, source_axis_y, disp[1]); - add_v3_v3v3(coord, vx, vy); - - /* project displacement from source grid plane onto target grid plane */ - cross_v3_v3v3(n, target_axis_x, target_axis_y); - project_v3_v3v3(vec, coord, n); - sub_v3_v3v3(coord, coord, vec); - - d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 0, 1); - - if (fabsf(d) < 1e-4f) { - d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 0, 2); - if (fabsf(d) < 1e-4f) { - d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 1, 2); - } - } - - disp[0] = (b[0] * mat[1][1] - mat[0][1] * b[1]) / d; - disp[1] = (mat[0][0] * b[1] - b[0] * mat[1][0]) / d; + float vx[3], vy[3], coord[3]; + float n[3], vec[3]; + float b[2], mat[2][2], d; + + mul_v3_v3fl(vx, source_axis_x, disp[0]); + mul_v3_v3fl(vy, source_axis_y, disp[1]); + add_v3_v3v3(coord, vx, vy); + + /* project displacement from source grid plane onto target grid plane */ + cross_v3_v3v3(n, target_axis_x, target_axis_y); + project_v3_v3v3(vec, coord, n); + sub_v3_v3v3(coord, coord, vec); + + d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 0, 1); + + if (fabsf(d) < 1e-4f) { + d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 0, 2); + if (fabsf(d) < 1e-4f) { + d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 1, 2); + } + } + + disp[0] = (b[0] * mat[1][1] - mat[0][1] * b[1]) / d; + disp[1] = (mat[0][0] * b[1] - b[0] * mat[1][0]) / d; } - typedef struct BMLoopInterpMultiresData { - BMLoop *l_dst; - BMLoop *l_src_first; - int cd_loop_mdisp_offset; + BMLoop *l_dst; + BMLoop *l_src_first; + int cd_loop_mdisp_offset; - MDisps *md_dst; - const float *f_src_center; + MDisps *md_dst; + const float *f_src_center; - float *axis_x, *axis_y; - float *v1, *v4; - float *e1, *e2; + float *axis_x, *axis_y; + float *v1, *v4; + float *e1, *e2; - int res; - float d; + int res; + float d; } BMLoopInterpMultiresData; -static void loop_interp_multires_cb( - void *__restrict userdata, - const int ix, - const ParallelRangeTLS *__restrict UNUSED(tls)) +static void loop_interp_multires_cb(void *__restrict userdata, + const int ix, + const ParallelRangeTLS *__restrict UNUSED(tls)) { - BMLoopInterpMultiresData *data = userdata; + BMLoopInterpMultiresData *data = userdata; - BMLoop *l_first = data->l_src_first; - BMLoop *l_dst = data->l_dst; - const int cd_loop_mdisp_offset = data->cd_loop_mdisp_offset; + BMLoop *l_first = data->l_src_first; + BMLoop *l_dst = data->l_dst; + const int cd_loop_mdisp_offset = data->cd_loop_mdisp_offset; - MDisps *md_dst = data->md_dst; - const float *f_src_center = data->f_src_center; + MDisps *md_dst = data->md_dst; + const float *f_src_center = data->f_src_center; - float *axis_x = data->axis_x; - float *axis_y = data->axis_y; + float *axis_x = data->axis_x; + float *axis_y = data->axis_y; - float *v1 = data->v1; - float *v4 = data->v4; - float *e1 = data->e1; - float *e2 = data->e2; + float *v1 = data->v1; + float *v4 = data->v4; + float *e1 = data->e1; + float *e2 = data->e2; - const int res = data->res; - const float d = data->d; + const int res = data->res; + const float d = data->d; - float x = d * ix, y; - int iy; - for (y = 0.0f, iy = 0; iy < res; y += d, iy++) { - BMLoop *l_iter = l_first; - float co1[3], co2[3], co[3]; + float x = d * ix, y; + int iy; + for (y = 0.0f, iy = 0; iy < res; y += d, iy++) { + BMLoop *l_iter = l_first; + float co1[3], co2[3], co[3]; - madd_v3_v3v3fl(co1, v1, e1, y); - madd_v3_v3v3fl(co2, v4, e2, y); - interp_v3_v3v3(co, co1, co2, x); + madd_v3_v3v3fl(co1, v1, e1, y); + madd_v3_v3v3fl(co2, v4, e2, y); + interp_v3_v3v3(co, co1, co2, x); - do { - MDisps *md_src; - float src_axis_x[3], src_axis_y[3]; - float uv[2]; + do { + MDisps *md_src; + float src_axis_x[3], src_axis_y[3]; + float uv[2]; - md_src = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset); + md_src = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset); - if (mdisp_in_mdispquad(l_dst, l_iter, f_src_center, co, res, src_axis_x, src_axis_y, uv)) { - old_mdisps_bilinear(md_dst->disps[iy * res + ix], md_src->disps, res, uv[0], uv[1]); - bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md_dst->disps[iy * res + ix]); + if (mdisp_in_mdispquad(l_dst, l_iter, f_src_center, co, res, src_axis_x, src_axis_y, uv)) { + old_mdisps_bilinear(md_dst->disps[iy * res + ix], md_src->disps, res, uv[0], uv[1]); + bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md_dst->disps[iy * res + ix]); - break; - } - } while ((l_iter = l_iter->next) != l_first); - } + break; + } + } while ((l_iter = l_iter->next) != l_first); + } } -void BM_loop_interp_multires_ex( - BMesh *UNUSED(bm), BMLoop *l_dst, const BMFace *f_src, - const float f_dst_center[3], const float f_src_center[3], const int cd_loop_mdisp_offset) +void BM_loop_interp_multires_ex(BMesh *UNUSED(bm), + BMLoop *l_dst, + const BMFace *f_src, + const float f_dst_center[3], + const float f_src_center[3], + const int cd_loop_mdisp_offset) { - MDisps *md_dst; - float v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3]; - float axis_x[3], axis_y[3]; - - /* ignore 2-edged faces */ - if (UNLIKELY(l_dst->f->len < 3)) { - return; - } - - md_dst = BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_mdisp_offset); - compute_mdisp_quad(l_dst, f_dst_center, v1, v2, v3, v4, e1, e2); - - /* if no disps data allocate a new grid, the size of the first grid in f_src. */ - if (!md_dst->totdisp) { - const MDisps *md_src = BM_ELEM_CD_GET_VOID_P(BM_FACE_FIRST_LOOP(f_src), cd_loop_mdisp_offset); - - md_dst->totdisp = md_src->totdisp; - md_dst->level = md_src->level; - if (md_dst->totdisp) { - md_dst->disps = MEM_callocN(sizeof(float) * 3 * md_dst->totdisp, __func__); - } - else { - return; - } - } - - mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y); - - const int res = (int)sqrt(md_dst->totdisp); - BMLoopInterpMultiresData data = { - .l_dst = l_dst, .l_src_first = BM_FACE_FIRST_LOOP(f_src), - .cd_loop_mdisp_offset = cd_loop_mdisp_offset, - .md_dst = md_dst, .f_src_center = f_src_center, - .axis_x = axis_x, .axis_y = axis_y, .v1 = v1, .v4 = v4, .e1 = e1, .e2 = e2, - .res = res, .d = 1.0f / (float)(res - 1), - }; - ParallelRangeSettings settings; - BLI_parallel_range_settings_defaults(&settings); - settings.use_threading = (res > 5); - BLI_task_parallel_range(0, res, &data, loop_interp_multires_cb, &settings); + MDisps *md_dst; + float v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3]; + float axis_x[3], axis_y[3]; + + /* ignore 2-edged faces */ + if (UNLIKELY(l_dst->f->len < 3)) { + return; + } + + md_dst = BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_mdisp_offset); + compute_mdisp_quad(l_dst, f_dst_center, v1, v2, v3, v4, e1, e2); + + /* if no disps data allocate a new grid, the size of the first grid in f_src. */ + if (!md_dst->totdisp) { + const MDisps *md_src = BM_ELEM_CD_GET_VOID_P(BM_FACE_FIRST_LOOP(f_src), cd_loop_mdisp_offset); + + md_dst->totdisp = md_src->totdisp; + md_dst->level = md_src->level; + if (md_dst->totdisp) { + md_dst->disps = MEM_callocN(sizeof(float) * 3 * md_dst->totdisp, __func__); + } + else { + return; + } + } + + mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y); + + const int res = (int)sqrt(md_dst->totdisp); + BMLoopInterpMultiresData data = { + .l_dst = l_dst, + .l_src_first = BM_FACE_FIRST_LOOP(f_src), + .cd_loop_mdisp_offset = cd_loop_mdisp_offset, + .md_dst = md_dst, + .f_src_center = f_src_center, + .axis_x = axis_x, + .axis_y = axis_y, + .v1 = v1, + .v4 = v4, + .e1 = e1, + .e2 = e2, + .res = res, + .d = 1.0f / (float)(res - 1), + }; + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.use_threading = (res > 5); + BLI_task_parallel_range(0, res, &data, loop_interp_multires_cb, &settings); } /** @@ -521,45 +572,47 @@ void BM_loop_interp_multires_ex( */ void BM_loop_interp_multires(BMesh *bm, BMLoop *l_dst, const BMFace *f_src) { - const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS); + const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS); - if (cd_loop_mdisp_offset != -1) { - float f_dst_center[3]; - float f_src_center[3]; + if (cd_loop_mdisp_offset != -1) { + float f_dst_center[3]; + float f_src_center[3]; - BM_face_calc_center_median(l_dst->f, f_dst_center); - BM_face_calc_center_median(f_src, f_src_center); + BM_face_calc_center_median(l_dst->f, f_dst_center); + BM_face_calc_center_median(f_src, f_src_center); - BM_loop_interp_multires_ex(bm, l_dst, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset); - } + BM_loop_interp_multires_ex(bm, l_dst, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset); + } } -void BM_face_interp_multires_ex( - BMesh *bm, BMFace *f_dst, const BMFace *f_src, - const float f_dst_center[3], const float f_src_center[3], const int cd_loop_mdisp_offset) +void BM_face_interp_multires_ex(BMesh *bm, + BMFace *f_dst, + const BMFace *f_src, + const float f_dst_center[3], + const float f_src_center[3], + const int cd_loop_mdisp_offset) { - BMLoop *l_iter, *l_first; - l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst); - do { - BM_loop_interp_multires_ex( - bm, l_iter, f_src, - f_dst_center, f_src_center, cd_loop_mdisp_offset); - } while ((l_iter = l_iter->next) != l_first); + BMLoop *l_iter, *l_first; + l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst); + do { + BM_loop_interp_multires_ex( + bm, l_iter, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset); + } while ((l_iter = l_iter->next) != l_first); } void BM_face_interp_multires(BMesh *bm, BMFace *f_dst, const BMFace *f_src) { - const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS); + const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS); - if (cd_loop_mdisp_offset != -1) { - float f_dst_center[3]; - float f_src_center[3]; + if (cd_loop_mdisp_offset != -1) { + float f_dst_center[3]; + float f_src_center[3]; - BM_face_calc_center_median(f_dst, f_dst_center); - BM_face_calc_center_median(f_src, f_src_center); + BM_face_calc_center_median(f_dst, f_dst_center); + BM_face_calc_center_median(f_src, f_src_center); - BM_face_interp_multires_ex(bm, f_dst, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset); - } + BM_face_interp_multires_ex(bm, f_dst, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset); + } } /** @@ -568,110 +621,110 @@ void BM_face_interp_multires(BMesh *bm, BMFace *f_dst, const BMFace *f_src) */ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f) { - const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS); - BMLoop *l; - BMIter liter; - - if (cd_loop_mdisp_offset == -1) { - return; - } - - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - MDisps *mdp = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_mdisp_offset); - MDisps *mdl = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset); - MDisps *mdn = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_mdisp_offset); - float co1[3]; - int sides; - int y; - - /** - * mdisps is a grid of displacements, ordered thus: - * <pre> - * v4/next - * | - * | v1/cent-----mid2 ---> x - * | | | - * | | | - * v2/prev---mid1-----v3/cur - * | - * V - * y - * </pre> - */ - - sides = (int)sqrt(mdp->totdisp); - for (y = 0; y < sides; y++) { - mid_v3_v3v3(co1, mdn->disps[y * sides], mdl->disps[y]); - - copy_v3_v3(mdn->disps[y * sides], co1); - copy_v3_v3(mdl->disps[y], co1); - } - } - - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - MDisps *mdl1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset); - MDisps *mdl2; - float co1[3], co2[3], co[3]; - int sides; - int y; - - /** - * mdisps is a grid of displacements, ordered thus: - * <pre> - * v4/next - * | - * | v1/cent-----mid2 ---> x - * | | | - * | | | - * v2/prev---mid1-----v3/cur - * | - * V - * y - * </pre> - */ - - if (l->radial_next == l) { - continue; - } - - if (l->radial_next->v == l->v) { - mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next, cd_loop_mdisp_offset); - } - else { - mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next->next, cd_loop_mdisp_offset); - } - - sides = (int)sqrt(mdl1->totdisp); - for (y = 0; y < sides; y++) { - int a1, a2, o1, o2; - - if (l->v != l->radial_next->v) { - a1 = sides * y + sides - 2; - a2 = (sides - 2) * sides + y; - - o1 = sides * y + sides - 1; - o2 = (sides - 1) * sides + y; - } - else { - a1 = sides * y + sides - 2; - a2 = sides * y + sides - 2; - o1 = sides * y + sides - 1; - o2 = sides * y + sides - 1; - } - - /* magic blending numbers, hardcoded! */ - add_v3_v3v3(co1, mdl1->disps[a1], mdl2->disps[a2]); - mul_v3_fl(co1, 0.18); - - add_v3_v3v3(co2, mdl1->disps[o1], mdl2->disps[o2]); - mul_v3_fl(co2, 0.32); - - add_v3_v3v3(co, co1, co2); - - copy_v3_v3(mdl1->disps[o1], co); - copy_v3_v3(mdl2->disps[o2], co); - } - } + const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS); + BMLoop *l; + BMIter liter; + + if (cd_loop_mdisp_offset == -1) { + return; + } + + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { + MDisps *mdp = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_mdisp_offset); + MDisps *mdl = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset); + MDisps *mdn = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_mdisp_offset); + float co1[3]; + int sides; + int y; + + /** + * mdisps is a grid of displacements, ordered thus: + * <pre> + * v4/next + * | + * | v1/cent-----mid2 ---> x + * | | | + * | | | + * v2/prev---mid1-----v3/cur + * | + * V + * y + * </pre> + */ + + sides = (int)sqrt(mdp->totdisp); + for (y = 0; y < sides; y++) { + mid_v3_v3v3(co1, mdn->disps[y * sides], mdl->disps[y]); + + copy_v3_v3(mdn->disps[y * sides], co1); + copy_v3_v3(mdl->disps[y], co1); + } + } + + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { + MDisps *mdl1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset); + MDisps *mdl2; + float co1[3], co2[3], co[3]; + int sides; + int y; + + /** + * mdisps is a grid of displacements, ordered thus: + * <pre> + * v4/next + * | + * | v1/cent-----mid2 ---> x + * | | | + * | | | + * v2/prev---mid1-----v3/cur + * | + * V + * y + * </pre> + */ + + if (l->radial_next == l) { + continue; + } + + if (l->radial_next->v == l->v) { + mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next, cd_loop_mdisp_offset); + } + else { + mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next->next, cd_loop_mdisp_offset); + } + + sides = (int)sqrt(mdl1->totdisp); + for (y = 0; y < sides; y++) { + int a1, a2, o1, o2; + + if (l->v != l->radial_next->v) { + a1 = sides * y + sides - 2; + a2 = (sides - 2) * sides + y; + + o1 = sides * y + sides - 1; + o2 = (sides - 1) * sides + y; + } + else { + a1 = sides * y + sides - 2; + a2 = sides * y + sides - 2; + o1 = sides * y + sides - 1; + o2 = sides * y + sides - 1; + } + + /* magic blending numbers, hardcoded! */ + add_v3_v3v3(co1, mdl1->disps[a1], mdl2->disps[a2]); + mul_v3_fl(co1, 0.18); + + add_v3_v3v3(co2, mdl1->disps[o1], mdl2->disps[o2]); + mul_v3_fl(co2, 0.32); + + add_v3_v3v3(co, co1, co2); + + copy_v3_v3(mdl1->disps[o1], co); + copy_v3_v3(mdl2->disps[o2], co); + } + } } /** @@ -679,290 +732,288 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f) * if do_vertex is true, target's vert data will also get interpolated. */ void BM_loop_interp_from_face( - BMesh *bm, BMLoop *l_dst, const BMFace *f_src, - const bool do_vertex, const bool do_multires) + BMesh *bm, BMLoop *l_dst, const BMFace *f_src, const bool do_vertex, const bool do_multires) { - BMLoop *l_iter; - BMLoop *l_first; - const void **vblocks = do_vertex ? BLI_array_alloca(vblocks, f_src->len) : NULL; - const void **blocks = BLI_array_alloca(blocks, f_src->len); - float (*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len); - float *w = BLI_array_alloca(w, f_src->len); - float axis_mat[3][3]; /* use normal to transform into 2d xy coords */ - float co[2]; - int i; - - /* convert the 3d coords into 2d for projection */ - BLI_assert(BM_face_is_normal_valid(f_src)); - axis_dominant_v3_to_m3(axis_mat, f_src->no); - - i = 0; - l_iter = l_first = BM_FACE_FIRST_LOOP(f_src); - do { - mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co); - blocks[i] = l_iter->head.data; - - if (do_vertex) { - vblocks[i] = l_iter->v->head.data; - } - } while ((void)i++, (l_iter = l_iter->next) != l_first); - - mul_v2_m3v3(co, axis_mat, l_dst->v->co); - - /* interpolate */ - interp_weights_poly_v2(w, cos_2d, f_src->len, co); - CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, f_src->len, l_dst->head.data); - if (do_vertex) { - CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, f_src->len, l_dst->v->head.data); - } - - if (do_multires) { - BM_loop_interp_multires(bm, l_dst, f_src); - } + BMLoop *l_iter; + BMLoop *l_first; + const void **vblocks = do_vertex ? BLI_array_alloca(vblocks, f_src->len) : NULL; + const void **blocks = BLI_array_alloca(blocks, f_src->len); + float(*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len); + float *w = BLI_array_alloca(w, f_src->len); + float axis_mat[3][3]; /* use normal to transform into 2d xy coords */ + float co[2]; + int i; + + /* convert the 3d coords into 2d for projection */ + BLI_assert(BM_face_is_normal_valid(f_src)); + axis_dominant_v3_to_m3(axis_mat, f_src->no); + + i = 0; + l_iter = l_first = BM_FACE_FIRST_LOOP(f_src); + do { + mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co); + blocks[i] = l_iter->head.data; + + if (do_vertex) { + vblocks[i] = l_iter->v->head.data; + } + } while ((void)i++, (l_iter = l_iter->next) != l_first); + + mul_v2_m3v3(co, axis_mat, l_dst->v->co); + + /* interpolate */ + interp_weights_poly_v2(w, cos_2d, f_src->len, co); + CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, f_src->len, l_dst->head.data); + if (do_vertex) { + CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, f_src->len, l_dst->v->head.data); + } + + if (do_multires) { + BM_loop_interp_multires(bm, l_dst, f_src); + } } - void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src) { - BMLoop *l_iter; - BMLoop *l_first; - const void **blocks = BLI_array_alloca(blocks, f_src->len); - float (*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len); - float *w = BLI_array_alloca(w, f_src->len); - float axis_mat[3][3]; /* use normal to transform into 2d xy coords */ - float co[2]; - int i; - - /* convert the 3d coords into 2d for projection */ - BLI_assert(BM_face_is_normal_valid(f_src)); - axis_dominant_v3_to_m3(axis_mat, f_src->no); - - i = 0; - l_iter = l_first = BM_FACE_FIRST_LOOP(f_src); - do { - mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co); - blocks[i] = l_iter->v->head.data; - } while ((void)i++, (l_iter = l_iter->next) != l_first); - - mul_v2_m3v3(co, axis_mat, v_dst->co); - - /* interpolate */ - interp_weights_poly_v2(w, cos_2d, f_src->len, co); - CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, f_src->len, v_dst->head.data); + BMLoop *l_iter; + BMLoop *l_first; + const void **blocks = BLI_array_alloca(blocks, f_src->len); + float(*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len); + float *w = BLI_array_alloca(w, f_src->len); + float axis_mat[3][3]; /* use normal to transform into 2d xy coords */ + float co[2]; + int i; + + /* convert the 3d coords into 2d for projection */ + BLI_assert(BM_face_is_normal_valid(f_src)); + axis_dominant_v3_to_m3(axis_mat, f_src->no); + + i = 0; + l_iter = l_first = BM_FACE_FIRST_LOOP(f_src); + do { + mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co); + blocks[i] = l_iter->v->head.data; + } while ((void)i++, (l_iter = l_iter->next) != l_first); + + mul_v2_m3v3(co, axis_mat, v_dst->co); + + /* interpolate */ + interp_weights_poly_v2(w, cos_2d, f_src->len, co); + CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, f_src->len, v_dst->head.data); } static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data) { - BMIter iter; - BLI_mempool *oldpool = olddata->pool; - void *block; - - if (data == &bm->vdata) { - BMVert *eve; - - CustomData_bmesh_init_pool(data, bm->totvert, BM_VERT); - - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - block = NULL; - CustomData_bmesh_set_default(data, &block); - CustomData_bmesh_copy_data(olddata, data, eve->head.data, &block); - CustomData_bmesh_free_block(olddata, &eve->head.data); - eve->head.data = block; - } - } - else if (data == &bm->edata) { - BMEdge *eed; - - CustomData_bmesh_init_pool(data, bm->totedge, BM_EDGE); - - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - block = NULL; - CustomData_bmesh_set_default(data, &block); - CustomData_bmesh_copy_data(olddata, data, eed->head.data, &block); - CustomData_bmesh_free_block(olddata, &eed->head.data); - eed->head.data = block; - } - } - else if (data == &bm->ldata) { - BMIter liter; - BMFace *efa; - BMLoop *l; - - CustomData_bmesh_init_pool(data, bm->totloop, BM_LOOP); - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - block = NULL; - CustomData_bmesh_set_default(data, &block); - CustomData_bmesh_copy_data(olddata, data, l->head.data, &block); - CustomData_bmesh_free_block(olddata, &l->head.data); - l->head.data = block; - } - } - } - else if (data == &bm->pdata) { - BMFace *efa; - - CustomData_bmesh_init_pool(data, bm->totface, BM_FACE); - - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - block = NULL; - CustomData_bmesh_set_default(data, &block); - CustomData_bmesh_copy_data(olddata, data, efa->head.data, &block); - CustomData_bmesh_free_block(olddata, &efa->head.data); - efa->head.data = block; - } - } - else { - /* should never reach this! */ - BLI_assert(0); - } - - if (oldpool) { - /* this should never happen but can when dissolve fails - [#28960] */ - BLI_assert(data->pool != oldpool); - - BLI_mempool_destroy(oldpool); - } + BMIter iter; + BLI_mempool *oldpool = olddata->pool; + void *block; + + if (data == &bm->vdata) { + BMVert *eve; + + CustomData_bmesh_init_pool(data, bm->totvert, BM_VERT); + + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + block = NULL; + CustomData_bmesh_set_default(data, &block); + CustomData_bmesh_copy_data(olddata, data, eve->head.data, &block); + CustomData_bmesh_free_block(olddata, &eve->head.data); + eve->head.data = block; + } + } + else if (data == &bm->edata) { + BMEdge *eed; + + CustomData_bmesh_init_pool(data, bm->totedge, BM_EDGE); + + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { + block = NULL; + CustomData_bmesh_set_default(data, &block); + CustomData_bmesh_copy_data(olddata, data, eed->head.data, &block); + CustomData_bmesh_free_block(olddata, &eed->head.data); + eed->head.data = block; + } + } + else if (data == &bm->ldata) { + BMIter liter; + BMFace *efa; + BMLoop *l; + + CustomData_bmesh_init_pool(data, bm->totloop, BM_LOOP); + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + block = NULL; + CustomData_bmesh_set_default(data, &block); + CustomData_bmesh_copy_data(olddata, data, l->head.data, &block); + CustomData_bmesh_free_block(olddata, &l->head.data); + l->head.data = block; + } + } + } + else if (data == &bm->pdata) { + BMFace *efa; + + CustomData_bmesh_init_pool(data, bm->totface, BM_FACE); + + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + block = NULL; + CustomData_bmesh_set_default(data, &block); + CustomData_bmesh_copy_data(olddata, data, efa->head.data, &block); + CustomData_bmesh_free_block(olddata, &efa->head.data); + efa->head.data = block; + } + } + else { + /* should never reach this! */ + BLI_assert(0); + } + + if (oldpool) { + /* this should never happen but can when dissolve fails - [#28960] */ + BLI_assert(data->pool != oldpool); + + BLI_mempool_destroy(oldpool); + } } void BM_data_layer_add(BMesh *bm, CustomData *data, int type) { - CustomData olddata; + CustomData olddata; - olddata = *data; - olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL; + olddata = *data; + olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL; - /* the pool is now owned by olddata and must not be shared */ - data->pool = NULL; + /* the pool is now owned by olddata and must not be shared */ + data->pool = NULL; - CustomData_add_layer(data, type, CD_DEFAULT, NULL, 0); + CustomData_add_layer(data, type, CD_DEFAULT, NULL, 0); - update_data_blocks(bm, &olddata, data); - if (olddata.layers) { - MEM_freeN(olddata.layers); - } + update_data_blocks(bm, &olddata, data); + if (olddata.layers) { + MEM_freeN(olddata.layers); + } } void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name) { - CustomData olddata; + CustomData olddata; - olddata = *data; - olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL; + olddata = *data; + olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL; - /* the pool is now owned by olddata and must not be shared */ - data->pool = NULL; + /* the pool is now owned by olddata and must not be shared */ + data->pool = NULL; - CustomData_add_layer_named(data, type, CD_DEFAULT, NULL, 0, name); + CustomData_add_layer_named(data, type, CD_DEFAULT, NULL, 0, name); - update_data_blocks(bm, &olddata, data); - if (olddata.layers) { - MEM_freeN(olddata.layers); - } + update_data_blocks(bm, &olddata, data); + if (olddata.layers) { + MEM_freeN(olddata.layers); + } } void BM_data_layer_free(BMesh *bm, CustomData *data, int type) { - CustomData olddata; - bool has_layer; + CustomData olddata; + bool has_layer; - olddata = *data; - olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL; + olddata = *data; + olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL; - /* the pool is now owned by olddata and must not be shared */ - data->pool = NULL; + /* the pool is now owned by olddata and must not be shared */ + data->pool = NULL; - has_layer = CustomData_free_layer_active(data, type, 0); - /* assert because its expensive to realloc - better not do if layer isnt present */ - BLI_assert(has_layer != false); - UNUSED_VARS_NDEBUG(has_layer); + has_layer = CustomData_free_layer_active(data, type, 0); + /* assert because its expensive to realloc - better not do if layer isnt present */ + BLI_assert(has_layer != false); + UNUSED_VARS_NDEBUG(has_layer); - update_data_blocks(bm, &olddata, data); - if (olddata.layers) { - MEM_freeN(olddata.layers); - } + update_data_blocks(bm, &olddata, data); + if (olddata.layers) { + MEM_freeN(olddata.layers); + } } void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n) { - CustomData olddata; - bool has_layer; + CustomData olddata; + bool has_layer; - olddata = *data; - olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL; + olddata = *data; + olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL; - /* the pool is now owned by olddata and must not be shared */ - data->pool = NULL; + /* the pool is now owned by olddata and must not be shared */ + data->pool = NULL; - has_layer = CustomData_free_layer(data, type, 0, CustomData_get_layer_index_n(data, type, n)); - /* assert because its expensive to realloc - better not do if layer isnt present */ - BLI_assert(has_layer != false); - UNUSED_VARS_NDEBUG(has_layer); + has_layer = CustomData_free_layer(data, type, 0, CustomData_get_layer_index_n(data, type, n)); + /* assert because its expensive to realloc - better not do if layer isnt present */ + BLI_assert(has_layer != false); + UNUSED_VARS_NDEBUG(has_layer); - update_data_blocks(bm, &olddata, data); - if (olddata.layers) { - MEM_freeN(olddata.layers); - } + update_data_blocks(bm, &olddata, data); + if (olddata.layers) { + MEM_freeN(olddata.layers); + } } void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int dst_n) { - BMIter iter; - - if (&bm->vdata == data) { - BMVert *eve; - - BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { - void *ptr = CustomData_bmesh_get_n(data, eve->head.data, type, src_n); - CustomData_bmesh_set_n(data, eve->head.data, type, dst_n, ptr); - } - } - else if (&bm->edata == data) { - BMEdge *eed; - - BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { - void *ptr = CustomData_bmesh_get_n(data, eed->head.data, type, src_n); - CustomData_bmesh_set_n(data, eed->head.data, type, dst_n, ptr); - } - } - else if (&bm->pdata == data) { - BMFace *efa; - - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - void *ptr = CustomData_bmesh_get_n(data, efa->head.data, type, src_n); - CustomData_bmesh_set_n(data, efa->head.data, type, dst_n, ptr); - } - } - else if (&bm->ldata == data) { - BMIter liter; - BMFace *efa; - BMLoop *l; - - BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - void *ptr = CustomData_bmesh_get_n(data, l->head.data, type, src_n); - CustomData_bmesh_set_n(data, l->head.data, type, dst_n, ptr); - } - } - } - else { - /* should never reach this! */ - BLI_assert(0); - } + BMIter iter; + + if (&bm->vdata == data) { + BMVert *eve; + + BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { + void *ptr = CustomData_bmesh_get_n(data, eve->head.data, type, src_n); + CustomData_bmesh_set_n(data, eve->head.data, type, dst_n, ptr); + } + } + else if (&bm->edata == data) { + BMEdge *eed; + + BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { + void *ptr = CustomData_bmesh_get_n(data, eed->head.data, type, src_n); + CustomData_bmesh_set_n(data, eed->head.data, type, dst_n, ptr); + } + } + else if (&bm->pdata == data) { + BMFace *efa; + + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + void *ptr = CustomData_bmesh_get_n(data, efa->head.data, type, src_n); + CustomData_bmesh_set_n(data, efa->head.data, type, dst_n, ptr); + } + } + else if (&bm->ldata == data) { + BMIter liter; + BMFace *efa; + BMLoop *l; + + BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + void *ptr = CustomData_bmesh_get_n(data, l->head.data, type, src_n); + CustomData_bmesh_set_n(data, l->head.data, type, dst_n, ptr); + } + } + } + else { + /* should never reach this! */ + BLI_assert(0); + } } float BM_elem_float_data_get(CustomData *cd, void *element, int type) { - const float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type); - return f ? *f : 0.0f; + const float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type); + return f ? *f : 0.0f; } void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val) { - float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type); - if (f) { - *f = val; - } + float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type); + if (f) { + *f = val; + } } /** \name Loop interpolation functions: BM_vert_loop_groups_data_layer_*** @@ -984,51 +1035,51 @@ void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float * \{ */ struct LoopWalkCtx { - /* same for all groups */ - int type; - int cd_layer_offset; - const float *loop_weights; - MemArena *arena; - - /* --- Per loop fan vars --- */ - - /* reference for this contiguous fan */ - const void *data_ref; - int data_len; - - /* accumulate 'LoopGroupCD.weight' to make unit length */ - float weight_accum; - - /* both arrays the size of the 'BM_vert_face_count(v)' - * each contiguous fan gets a slide of these arrays */ - void **data_array; - int *data_index_array; - float *weight_array; + /* same for all groups */ + int type; + int cd_layer_offset; + const float *loop_weights; + MemArena *arena; + + /* --- Per loop fan vars --- */ + + /* reference for this contiguous fan */ + const void *data_ref; + int data_len; + + /* accumulate 'LoopGroupCD.weight' to make unit length */ + float weight_accum; + + /* both arrays the size of the 'BM_vert_face_count(v)' + * each contiguous fan gets a slide of these arrays */ + void **data_array; + int *data_index_array; + float *weight_array; }; /* Store vars to pass into 'CustomData_bmesh_interp' */ struct LoopGroupCD { - /* direct customdata pointer array */ - void **data; - /* weights (aligned with 'data') */ - float *data_weights; - /* index-in-face */ - int *data_index; - /* number of loops in the fan */ - int data_len; + /* direct customdata pointer array */ + void **data; + /* weights (aligned with 'data') */ + float *data_weights; + /* index-in-face */ + int *data_index; + /* number of loops in the fan */ + int data_len; }; static void bm_loop_walk_add(struct LoopWalkCtx *lwc, BMLoop *l) { - const int i = BM_elem_index_get(l); - const float w = lwc->loop_weights[i]; - BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG); - lwc->data_array[lwc->data_len] = BM_ELEM_CD_GET_VOID_P(l, lwc->cd_layer_offset); - lwc->data_index_array[lwc->data_len] = i; - lwc->weight_array[lwc->data_len] = w; - lwc->weight_accum += w; - - lwc->data_len += 1; + const int i = BM_elem_index_get(l); + const float w = lwc->loop_weights[i]; + BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG); + lwc->data_array[lwc->data_len] = BM_ELEM_CD_GET_VOID_P(l, lwc->cd_layer_offset); + lwc->data_index_array[lwc->data_len] = i; + lwc->weight_array[lwc->data_len] = w; + lwc->weight_accum += w; + + lwc->data_len += 1; } /** @@ -1038,146 +1089,145 @@ static void bm_loop_walk_add(struct LoopWalkCtx *lwc, BMLoop *l) */ static void bm_loop_walk_data(struct LoopWalkCtx *lwc, BMLoop *l_walk) { - int i; - - BLI_assert(CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_walk, lwc->cd_layer_offset))); - BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG)); - - bm_loop_walk_add(lwc, l_walk); - - /* recurse around this loop-fan (in both directions) */ - for (i = 0; i < 2; i++) { - BMLoop *l_other = ((i == 0) ? l_walk : l_walk->prev)->radial_next; - if (l_other->radial_next != l_other) { - if (l_other->v != l_walk->v) { - l_other = l_other->next; - } - BLI_assert(l_other->v == l_walk->v); - if (BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) { - if (CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_other, lwc->cd_layer_offset))) { - bm_loop_walk_data(lwc, l_other); - } - } - } - } + int i; + + BLI_assert(CustomData_data_equals( + lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_walk, lwc->cd_layer_offset))); + BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG)); + + bm_loop_walk_add(lwc, l_walk); + + /* recurse around this loop-fan (in both directions) */ + for (i = 0; i < 2; i++) { + BMLoop *l_other = ((i == 0) ? l_walk : l_walk->prev)->radial_next; + if (l_other->radial_next != l_other) { + if (l_other->v != l_walk->v) { + l_other = l_other->next; + } + BLI_assert(l_other->v == l_walk->v); + if (BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) { + if (CustomData_data_equals( + lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_other, lwc->cd_layer_offset))) { + bm_loop_walk_data(lwc, l_other); + } + } + } + } } LinkNode *BM_vert_loop_groups_data_layer_create( - BMesh *bm, BMVert *v, const int layer_n, const float *loop_weights, MemArena *arena) + BMesh *bm, BMVert *v, const int layer_n, const float *loop_weights, MemArena *arena) { - struct LoopWalkCtx lwc; - LinkNode *groups = NULL; - BMLoop *l; - BMIter liter; - int loop_num; - - - lwc.type = bm->ldata.layers[layer_n].type; - lwc.cd_layer_offset = bm->ldata.layers[layer_n].offset; - lwc.loop_weights = loop_weights; - lwc.arena = arena; - - /* Enable 'BM_ELEM_INTERNAL_TAG', leaving the flag clean on completion. */ - loop_num = 0; - BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG); - BM_elem_index_set(l, loop_num); /* set_dirty! */ - loop_num++; - } - bm->elem_index_dirty |= BM_LOOP; - - lwc.data_len = 0; - lwc.data_array = BLI_memarena_alloc(lwc.arena, sizeof(void *) * loop_num); - lwc.data_index_array = BLI_memarena_alloc(lwc.arena, sizeof(int) * loop_num); - lwc.weight_array = BLI_memarena_alloc(lwc.arena, sizeof(float) * loop_num); - - BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - if (BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) { - struct LoopGroupCD *lf = BLI_memarena_alloc(lwc.arena, sizeof(*lf)); - int len_prev = lwc.data_len; - - lwc.data_ref = BM_ELEM_CD_GET_VOID_P(l, lwc.cd_layer_offset); - - /* assign len-last */ - lf->data = &lwc.data_array[lwc.data_len]; - lf->data_index = &lwc.data_index_array[lwc.data_len]; - lf->data_weights = &lwc.weight_array[lwc.data_len]; - lwc.weight_accum = 0.0f; - - /* new group */ - bm_loop_walk_data(&lwc, l); - lf->data_len = lwc.data_len - len_prev; - - if (LIKELY(lwc.weight_accum != 0.0f)) { - mul_vn_fl(lf->data_weights, lf->data_len, 1.0f / lwc.weight_accum); - } - else { - copy_vn_fl(lf->data_weights, lf->data_len, 1.0f / (float)lf->data_len); - } - - BLI_linklist_prepend_arena(&groups, lf, lwc.arena); - } - } - - BLI_assert(lwc.data_len == loop_num); - - return groups; + struct LoopWalkCtx lwc; + LinkNode *groups = NULL; + BMLoop *l; + BMIter liter; + int loop_num; + + lwc.type = bm->ldata.layers[layer_n].type; + lwc.cd_layer_offset = bm->ldata.layers[layer_n].offset; + lwc.loop_weights = loop_weights; + lwc.arena = arena; + + /* Enable 'BM_ELEM_INTERNAL_TAG', leaving the flag clean on completion. */ + loop_num = 0; + BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { + BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG); + BM_elem_index_set(l, loop_num); /* set_dirty! */ + loop_num++; + } + bm->elem_index_dirty |= BM_LOOP; + + lwc.data_len = 0; + lwc.data_array = BLI_memarena_alloc(lwc.arena, sizeof(void *) * loop_num); + lwc.data_index_array = BLI_memarena_alloc(lwc.arena, sizeof(int) * loop_num); + lwc.weight_array = BLI_memarena_alloc(lwc.arena, sizeof(float) * loop_num); + + BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { + if (BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) { + struct LoopGroupCD *lf = BLI_memarena_alloc(lwc.arena, sizeof(*lf)); + int len_prev = lwc.data_len; + + lwc.data_ref = BM_ELEM_CD_GET_VOID_P(l, lwc.cd_layer_offset); + + /* assign len-last */ + lf->data = &lwc.data_array[lwc.data_len]; + lf->data_index = &lwc.data_index_array[lwc.data_len]; + lf->data_weights = &lwc.weight_array[lwc.data_len]; + lwc.weight_accum = 0.0f; + + /* new group */ + bm_loop_walk_data(&lwc, l); + lf->data_len = lwc.data_len - len_prev; + + if (LIKELY(lwc.weight_accum != 0.0f)) { + mul_vn_fl(lf->data_weights, lf->data_len, 1.0f / lwc.weight_accum); + } + else { + copy_vn_fl(lf->data_weights, lf->data_len, 1.0f / (float)lf->data_len); + } + + BLI_linklist_prepend_arena(&groups, lf, lwc.arena); + } + } + + BLI_assert(lwc.data_len == loop_num); + + return groups; } -static void bm_vert_loop_groups_data_layer_merge__single( - BMesh *bm, void *lf_p, int layer_n, - void *data_tmp) +static void bm_vert_loop_groups_data_layer_merge__single(BMesh *bm, + void *lf_p, + int layer_n, + void *data_tmp) { - struct LoopGroupCD *lf = lf_p; - const int type = bm->ldata.layers[layer_n].type; - int i; - const float *data_weights; + struct LoopGroupCD *lf = lf_p; + const int type = bm->ldata.layers[layer_n].type; + int i; + const float *data_weights; - data_weights = lf->data_weights; + data_weights = lf->data_weights; - CustomData_bmesh_interp_n( - &bm->ldata, (const void **)lf->data, - data_weights, NULL, lf->data_len, data_tmp, layer_n); + CustomData_bmesh_interp_n( + &bm->ldata, (const void **)lf->data, data_weights, NULL, lf->data_len, data_tmp, layer_n); - for (i = 0; i < lf->data_len; i++) { - CustomData_copy_elements(type, data_tmp, lf->data[i], 1); - } + for (i = 0; i < lf->data_len; i++) { + CustomData_copy_elements(type, data_tmp, lf->data[i], 1); + } } static void bm_vert_loop_groups_data_layer_merge_weights__single( - BMesh *bm, void *lf_p, const int layer_n, void *data_tmp, - const float *loop_weights) + BMesh *bm, void *lf_p, const int layer_n, void *data_tmp, const float *loop_weights) { - struct LoopGroupCD *lf = lf_p; - const int type = bm->ldata.layers[layer_n].type; - int i; - const float *data_weights; - - /* re-weight */ - float *temp_weights = BLI_array_alloca(temp_weights, lf->data_len); - float weight_accum = 0.0f; - - for (i = 0; i < lf->data_len; i++) { - float w = loop_weights[lf->data_index[i]] * lf->data_weights[i]; - temp_weights[i] = w; - weight_accum += w; - } - - if (LIKELY(weight_accum != 0.0f)) { - mul_vn_fl(temp_weights, lf->data_len, 1.0f / weight_accum); - data_weights = temp_weights; - } - else { - data_weights = lf->data_weights; - } - - CustomData_bmesh_interp_n( - &bm->ldata, (const void **)lf->data, - data_weights, NULL, lf->data_len, data_tmp, layer_n); - - for (i = 0; i < lf->data_len; i++) { - CustomData_copy_elements(type, data_tmp, lf->data[i], 1); - } + struct LoopGroupCD *lf = lf_p; + const int type = bm->ldata.layers[layer_n].type; + int i; + const float *data_weights; + + /* re-weight */ + float *temp_weights = BLI_array_alloca(temp_weights, lf->data_len); + float weight_accum = 0.0f; + + for (i = 0; i < lf->data_len; i++) { + float w = loop_weights[lf->data_index[i]] * lf->data_weights[i]; + temp_weights[i] = w; + weight_accum += w; + } + + if (LIKELY(weight_accum != 0.0f)) { + mul_vn_fl(temp_weights, lf->data_len, 1.0f / weight_accum); + data_weights = temp_weights; + } + else { + data_weights = lf->data_weights; + } + + CustomData_bmesh_interp_n( + &bm->ldata, (const void **)lf->data, data_weights, NULL, lf->data_len, data_tmp, layer_n); + + for (i = 0; i < lf->data_len; i++) { + CustomData_copy_elements(type, data_tmp, lf->data[i], 1); + } } /** @@ -1185,29 +1235,32 @@ static void bm_vert_loop_groups_data_layer_merge_weights__single( */ void BM_vert_loop_groups_data_layer_merge(BMesh *bm, LinkNode *groups, const int layer_n) { - const int type = bm->ldata.layers[layer_n].type; - const int size = CustomData_sizeof(type); - void *data_tmp = alloca(size); + const int type = bm->ldata.layers[layer_n].type; + const int size = CustomData_sizeof(type); + void *data_tmp = alloca(size); - do { - bm_vert_loop_groups_data_layer_merge__single(bm, groups->link, layer_n, data_tmp); - } while ((groups = groups->next)); + do { + bm_vert_loop_groups_data_layer_merge__single(bm, groups->link, layer_n, data_tmp); + } while ((groups = groups->next)); } /** * A version of #BM_vert_loop_groups_data_layer_merge * that takes an array of loop-weights (aligned with #BM_LOOPS_OF_VERT iterator) */ -void BM_vert_loop_groups_data_layer_merge_weights( - BMesh *bm, LinkNode *groups, const int layer_n, const float *loop_weights) +void BM_vert_loop_groups_data_layer_merge_weights(BMesh *bm, + LinkNode *groups, + const int layer_n, + const float *loop_weights) { - const int type = bm->ldata.layers[layer_n].type; - const int size = CustomData_sizeof(type); - void *data_tmp = alloca(size); - - do { - bm_vert_loop_groups_data_layer_merge_weights__single(bm, groups->link, layer_n, data_tmp, loop_weights); - } while ((groups = groups->next)); + const int type = bm->ldata.layers[layer_n].type; + const int size = CustomData_sizeof(type); + void *data_tmp = alloca(size); + + do { + bm_vert_loop_groups_data_layer_merge_weights__single( + bm, groups->link, layer_n, data_tmp, loop_weights); + } while ((groups = groups->next)); } /** \} */ |