From c68ae745b677c02899fda37a1f573ab688a99fac Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 10 Apr 2013 23:25:44 +0000 Subject: interpolate verts as well as loops for inset. - add vertex option to BM_face_interp_from_face, also expose via python. --- source/blender/bmesh/intern/bmesh_interp.c | 21 ++++++++++++-------- source/blender/bmesh/intern/bmesh_interp.h | 8 ++++---- source/blender/bmesh/operators/bmo_inset.c | 29 +++++++++++++++++----------- source/blender/python/bmesh/bmesh_py_types.c | 11 +++++++---- 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index c1b10e3537f..c0975897090 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -167,8 +167,8 @@ void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BM * * \note Only handles loop customdata. multires is handled. */ -void BM_face_interp_from_face_ex(BMesh *bm, BMFace *target, BMFace *source, - void **blocks, float (*cos_2d)[2], float axis_mat[3][3]) +void BM_face_interp_from_face_ex(BMesh *bm, BMFace *target, BMFace *source, const bool do_vertex, + void **blocks_l, void **blocks_v, float (*cos_2d)[2], float axis_mat[3][3]) { BMLoop *l_iter; BMLoop *l_first; @@ -186,16 +186,20 @@ void BM_face_interp_from_face_ex(BMesh *bm, BMFace *target, BMFace *source, do { mul_v2_m3v3(co, axis_mat, l_iter->v->co); interp_weights_poly_v2(w, cos_2d, source->len, co); - CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, l_iter->head.data); + CustomData_bmesh_interp(&bm->ldata, blocks_l, w, NULL, source->len, l_iter->head.data); + if (do_vertex) { + CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, source->len, l_iter->v->head.data); + } } while (i++, (l_iter = l_iter->next) != l_first); } -void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source) +void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source, const bool do_vertex) { BMLoop *l_iter; BMLoop *l_first; - void **blocks = BLI_array_alloca(blocks, source->len); + void **blocks_l = BLI_array_alloca(blocks_l, source->len); + void **blocks_v = do_vertex ? BLI_array_alloca(blocks_v, source->len) : NULL; float (*cos_2d)[2] = BLI_array_alloca(cos_2d, source->len); float axis_mat[3][3]; /* use normal to transform into 2d xy coords */ int i; @@ -207,11 +211,12 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source) l_iter = l_first = BM_FACE_FIRST_LOOP(source); do { mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co); - blocks[i] = l_iter->head.data; + blocks_l[i] = l_iter->head.data; + if (do_vertex) blocks_v[i] = l_iter->v->head.data; } while (i++, (l_iter = l_iter->next) != l_first); - BM_face_interp_from_face_ex(bm, target, source, - blocks, cos_2d, axis_mat); + BM_face_interp_from_face_ex(bm, target, source, do_vertex, + blocks_l, blocks_v, cos_2d, axis_mat); } /** diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h index 1a1ca241224..2a3b5190ece 100644 --- a/source/blender/bmesh/intern/bmesh_interp.h +++ b/source/blender/bmesh/intern/bmesh_interp.h @@ -42,11 +42,11 @@ void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int d float BM_elem_float_data_get(CustomData *cd, void *element, int type); void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val); -void BM_face_interp_from_face_ex(BMesh *bm, BMFace *target, BMFace *source, - void **blocks, float (*cos_2d)[2], float axis_mat[3][3]); -void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source); +void BM_face_interp_from_face_ex(BMesh *bm, BMFace *target, BMFace *source, const bool do_vertex, + void **blocks, void **blocks_v, float (*cos_2d)[2], float axis_mat[3][3]); +void BM_face_interp_from_face(BMesh *bm, BMFace *target, BMFace *source, const bool do_vertex); void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source, - const bool do_vertex, const bool do_multires); + const bool do_vertex, const bool do_multires); void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f); diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index c99e6060a50..f799d589b3c 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -169,7 +169,7 @@ void bmo_inset_individual_exec(BMesh *bm, BMOperator *op) /* Copy Face Data */ /* interpolate loop data or just stretch */ if (use_interpolate) { - BM_face_interp_from_face(bm, f_new_inner, f); + BM_face_interp_from_face(bm, f_new_inner, f, true); } else { BM_elem_attrs_copy(bm, bm, f, f_new_inner); @@ -256,7 +256,8 @@ typedef struct SplitEdgeInfo { /* just enough of a face to store interpolation data we can use once the inset is done */ typedef struct InterpFace { BMFace *f; - void **blocks; + void **blocks_l; + void **blocks_v; float (*cos_2d)[2]; float axis_mat[3][3]; } InterpFace; @@ -265,7 +266,8 @@ typedef struct InterpFace { static void bm_interp_face_store(InterpFace *iface, BMesh *bm, BMFace *f, MemArena *interp_arena) { BMLoop *l_iter, *l_first; - void **blocks = iface->blocks = BLI_memarena_alloc(interp_arena, sizeof(*iface->blocks) * f->len); + void **blocks_l = iface->blocks_l = BLI_memarena_alloc(interp_arena, sizeof(*iface->blocks_l) * f->len); + void **blocks_v = iface->blocks_v = BLI_memarena_alloc(interp_arena, sizeof(*iface->blocks_v) * f->len); float (*cos_2d)[2] = iface->cos_2d = BLI_memarena_alloc(interp_arena, sizeof(*iface->cos_2d) * f->len); void *axis_mat = iface->axis_mat; int i; @@ -278,22 +280,27 @@ static void bm_interp_face_store(InterpFace *iface, BMesh *bm, BMFace *f, MemAre l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co); - blocks[i] = NULL; - CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, l_iter->head.data, &blocks[i]); + blocks_l[i] = NULL; + CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, l_iter->head.data, &blocks_l[i]); /* if we were not modifying the loops later we would do... */ // blocks[i] = l_iter->head.data; + blocks_v[i] = NULL; + CustomData_bmesh_copy_data(&bm->vdata, &bm->vdata, l_iter->v->head.data, &blocks_v[i]); + /* use later for index lookups */ BM_elem_index_set(l_iter, i); /* set_ok */ } while (i++, (l_iter = l_iter->next) != l_first); } static void bm_interp_face_free(InterpFace *iface, BMesh *bm) { - void **blocks = iface->blocks; + void **blocks_l = iface->blocks_l; + void **blocks_v = iface->blocks_v; int i; for (i = 0; i < iface->f->len; i++) { - CustomData_bmesh_free_block(&bm->ldata, &blocks[i]); + CustomData_bmesh_free_block(&bm->ldata, &blocks_l[i]); + CustomData_bmesh_free_block(&bm->vdata, &blocks_v[i]); } } @@ -724,8 +731,8 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) for (i = 0; i < iface_array_len; i++) { if (iface_array[i]) { InterpFace *iface = iface_array[i]; - BM_face_interp_from_face_ex(bm, iface->f, iface->f, - iface->blocks, iface->cos_2d, iface->axis_mat); + BM_face_interp_from_face_ex(bm, iface->f, iface->f, true, + iface->blocks_l, iface->blocks_v, iface->cos_2d, iface->axis_mat); } } } @@ -800,8 +807,8 @@ void bmo_inset_region_exec(BMesh *bm, BMOperator *op) InterpFace *iface = iface_array[BM_elem_index_get(es->l->f)]; const int i_a = BM_elem_index_get(l_a_other); const int i_b = BM_elem_index_get(l_b_other); - CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, iface->blocks[i_a], &l_b->head.data); - CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, iface->blocks[i_b], &l_a->head.data); + CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, iface->blocks_l[i_a], &l_b->head.data); + CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, iface->blocks_l[i_b], &l_a->head.data); } else { BM_elem_attrs_copy(bm, bm, l_a_other, l_b); diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index f49018d6e18..e7ca0cd5708 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1597,21 +1597,24 @@ static PyObject *bpy_bmedge_normal_update(BPy_BMEdge *self) * ---- */ PyDoc_STRVAR(bpy_bmface_copy_from_face_interp_doc, -".. method:: copy_from_face_interp(face)\n" +".. method:: copy_from_face_interp(face, vert=True)\n" "\n" " Interpolate the customdata from another face onto this one (faces should overlap).\n" "\n" " :arg face: The face to interpolate data from.\n" " :type face: :class:`BMFace`\n" +" :arg vert: When True, also copy vertex data.\n" +" :type vert: boolean\n" ); static PyObject *bpy_bmface_copy_from_face_interp(BPy_BMFace *self, PyObject *args) { BPy_BMFace *py_face = NULL; + int do_vertex = true; BPY_BM_CHECK_OBJ(self); - if (!PyArg_ParseTuple(args, "O!:BMFace.copy_from_face_interp", - &BPy_BMFace_Type, &py_face)) + if (!PyArg_ParseTuple(args, "O!|i:BMFace.copy_from_face_interp", + &BPy_BMFace_Type, &py_face, &do_vertex)) { return NULL; } @@ -1620,7 +1623,7 @@ static PyObject *bpy_bmface_copy_from_face_interp(BPy_BMFace *self, PyObject *ar BPY_BM_CHECK_SOURCE_OBJ(py_face, bm, "BMFace.copy_from_face_interp(face)"); - BM_face_interp_from_face(bm, self->f, py_face->f); + BM_face_interp_from_face(bm, self->f, py_face->f, do_vertex); Py_RETURN_NONE; } -- cgit v1.2.3