From 06e1bc6178fc22178b79763d392c8d58d06285fe Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 18:22:00 +0000 Subject: internal editmesh api: add an extended version of EDBM_verts_mirror_cache_begin which takes arguments to give some more control. --- source/blender/editors/mesh/editmesh_utils.c | 74 +++++++++++++++++++--------- 1 file changed, 50 insertions(+), 24 deletions(-) (limited to 'source/blender/editors/mesh/editmesh_utils.c') diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index fa857edb6fc..ae2b25084bd 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1144,46 +1144,58 @@ static BMVert *cache_mirr_intptr_as_bmvert(intptr_t *index_lookup, int index) * preference */ #define BM_SEARCH_MAXDIST_MIRR 0.00002f #define BM_CD_LAYER_ID "__mirror_index" -void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select) +/** + * \param em Editmesh. + * \param use_self Allow a vertex to point to its self (middle verts). + * \param use_select Restrict to selected verts. + * \param is_topo Use topology mirror. + * \param maxdist Distance for close point test. + * \param r_index Optional array to write into, as an alternative to a customdata layer (length of total verts). + */ +void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const bool use_self, const bool use_select, + /* extra args */ + const bool is_topo, float maxdist, int *r_index) { Mesh *me = (Mesh *)em->ob->data; BMesh *bm = em->bm; BMIter iter; BMVert *v; - bool topo = false; int cd_vmirr_offset; + int i; /* one or the other is used depending if topo is enabled */ struct BMBVHTree *tree = NULL; MirrTopoStore_t mesh_topo_store = {NULL, -1, -1, -1}; - if (me && (me->editflag & ME_EDIT_MIRROR_TOPO)) { - topo = 1; - } - EDBM_index_arrays_ensure(em, BM_VERT); - em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); - if (em->mirror_cdlayer == -1) { - BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); - em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); - } + if (r_index == NULL) { + const char *layer_id = BM_CD_LAYER_ID; + em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id); + if (em->mirror_cdlayer == -1) { + BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, layer_id); + em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id); + } - cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT, - em->mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT)); + cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT, + em->mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT)); - bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY; + bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY; + } BM_mesh_elem_index_ensure(bm, BM_VERT); - if (topo) { + if (is_topo) { ED_mesh_mirrtopo_init(me, -1, &mesh_topo_store, true); } else { tree = BKE_bmbvh_new(em, 0, NULL, false); } - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { +#define VERT_INTPTR(_v, _i) r_index ? &r_index[_i] : BM_ELEM_CD_GET_VOID_P(_v, cd_vmirr_offset); + + BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { + BLI_assert(BM_elem_index_get(v) == i); /* temporary for testing, check for selection */ if (use_select && !BM_elem_flag_test(v, BM_ELEM_SELECT)) { @@ -1191,20 +1203,21 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo } else { BMVert *v_mirr; - int *idx = BM_ELEM_CD_GET_VOID_P(v, cd_vmirr_offset); + int *idx = VERT_INTPTR(v, i); - if (topo) { - v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, BM_elem_index_get(v)); + if (is_topo) { + v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i); } else { float co[3] = {-v->co[0], v->co[1], v->co[2]}; - v_mirr = BKE_bmbvh_find_vert_closest(tree, co, BM_SEARCH_MAXDIST_MIRR); + v_mirr = BKE_bmbvh_find_vert_closest(tree, co, maxdist); } if (v_mirr && (use_self || (v_mirr != v))) { - *idx = BM_elem_index_get(v_mirr); - idx = BM_ELEM_CD_GET_VOID_P(v_mirr, cd_vmirr_offset); - *idx = BM_elem_index_get(v); + const int i_mirr = BM_elem_index_get(v_mirr); + *idx = i_mirr; + idx = VERT_INTPTR(v_mirr, i_mirr); + *idx = i; } else { *idx = -1; @@ -1213,8 +1226,9 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo } +#undef VERT_INTPTR - if (topo) { + if (is_topo) { ED_mesh_mirrtopo_free(&mesh_topo_store); } else { @@ -1222,6 +1236,18 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo } } +void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select) +{ + Mesh *me = (Mesh *)em->ob->data; + bool is_topo; + + is_topo = (me && (me->editflag & ME_EDIT_MIRROR_TOPO)); + + EDBM_verts_mirror_cache_begin_ex(em, use_self, use_select, + /* extra args */ + is_topo, BM_SEARCH_MAXDIST_MIRR, NULL); +} + BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v) { int *mirr = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, em->mirror_cdlayer); -- cgit v1.2.3