diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-06-05 09:58:51 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-06-05 09:58:51 +0400 |
commit | 666c8b51ca667f2c91600a98745a4f115a82216d (patch) | |
tree | 40d3ab71c6e46d830ba7689e4f4b91bbe9eaf0ee /source/blender/editors | |
parent | e03bbcec651f35baca647b1c3fe79505ad546585 (diff) |
changes to mirror tools
- give feedback on how many mirror verts succeed/fail (for select mirror, shape key mirror, weight mirror)
... when a mirror failed it was confusing and not obvious what was going on.
- slight change to select mirror, now center vertices will remain selected.
- speedup to EDBM_verts_mirror_cache_begin, cache customdata layer offset.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_mesh.h | 10 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_select.c | 33 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_tools.c | 4 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_utils.c | 33 | ||||
-rw-r--r-- | source/blender/editors/mesh/mesh_data.c | 10 | ||||
-rw-r--r-- | source/blender/editors/object/object_shapekey.c | 23 | ||||
-rw-r--r-- | source/blender/editors/object/object_vgroup.c | 81 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 2 |
8 files changed, 138 insertions, 58 deletions
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 9aa405eda1d..e3d762dccfb 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -76,7 +76,7 @@ struct MeshStatVis; /* editmesh_utils.c */ -void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const bool use_select); /* note, replaces EM_cache_x_mirror_vert in trunk */ +void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const bool use_self, const bool use_select); void EDBM_verts_mirror_apply(struct BMEditMesh *em, const int sel_from, const int sel_to); struct BMVert *EDBM_verts_mirror_get(struct BMEditMesh *em, struct BMVert *v); void EDBM_verts_mirror_cache_clear(struct BMEditMesh *em, struct BMVert *v); @@ -141,7 +141,8 @@ bool BMBVH_EdgeVisible(struct BMBVHTree *tree, struct BMEdge *e, struct ARegion *ar, struct View3D *v3d, struct Object *obedit); /* editmesh_select.c */ -void EDBM_select_mirrored(struct Object *obedit, struct BMEditMesh *em, bool extend); +void EDBM_select_mirrored(struct BMEditMesh *em, bool extend, + int *r_totmirr, int *r_totfail); void EDBM_automerge(struct Scene *scene, struct Object *ob, bool update); bool EDBM_backbuf_border_init(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); @@ -237,7 +238,8 @@ void ED_vgroup_data_clamp_range(struct ID *id, const int total); bool ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot); bool ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from); void ED_vgroup_mirror(struct Object *ob, - const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups); + const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups, + int *r_totmirr, int *r_totfail); bool ED_vgroup_object_is_edit_mode(struct Object *ob); @@ -273,6 +275,8 @@ bool ED_mesh_color_remove_index(struct Mesh *me, const int n); bool ED_mesh_color_remove_active(struct Mesh *me); bool ED_mesh_color_remove_named(struct Mesh *me, const char *name); +void ED_mesh_report_mirror(struct wmOperator *op, int totmirr, int totfail); + /* mesh backup */ typedef struct BMBackup { struct BMesh *bmcopy; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 996331d2f8c..b0c76d23664 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -73,10 +73,15 @@ /* ****************************** MIRROR **************** */ -void EDBM_select_mirrored(Object *UNUSED(obedit), BMEditMesh *em, bool extend) +void EDBM_select_mirrored(BMEditMesh *em, bool extend, + int *r_totmirr, int *r_totfail) { BMVert *v1, *v2; BMIter iter; + int totmirr = 0; + int totfail = 0; + + *r_totmirr = *r_totfail = 0; BM_ITER_MESH (v1, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(v1, BM_ELEM_SELECT) || BM_elem_flag_test(v1, BM_ELEM_HIDDEN)) { @@ -87,7 +92,7 @@ void EDBM_select_mirrored(Object *UNUSED(obedit), BMEditMesh *em, bool extend) } } - EDBM_verts_mirror_cache_begin(em, true); + EDBM_verts_mirror_cache_begin(em, true, true); if (!extend) EDBM_flag_disable_all(em, BM_ELEM_SELECT); @@ -97,12 +102,21 @@ void EDBM_select_mirrored(Object *UNUSED(obedit), BMEditMesh *em, bool extend) continue; v2 = EDBM_verts_mirror_get(em, v1); - if (v2 && !BM_elem_flag_test(v2, BM_ELEM_HIDDEN)) { - BM_vert_select_set(em->bm, v2, true); + if (v2) { + if (!BM_elem_flag_test(v2, BM_ELEM_HIDDEN)) { + BM_vert_select_set(em->bm, v2, true); + totmirr++; + } + } + else { + totfail++; } } EDBM_verts_mirror_cache_end(em); + + *r_totmirr = totmirr; + *r_totfail = totfail; } void EDBM_automerge(Scene *scene, Object *obedit, bool update) @@ -2206,9 +2220,14 @@ static int edbm_select_mirror_exec(bContext *C, wmOperator *op) bool extend = RNA_boolean_get(op->ptr, "extend"); if (em->bm->totvert && em->bm->totvertsel) { - EDBM_select_mirrored(obedit, em, extend); - EDBM_selectmode_flush(em); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + int totmirr, totfail; + EDBM_select_mirrored(em, extend, &totmirr, &totfail); + if (totmirr) { + EDBM_selectmode_flush(em); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + } + + ED_mesh_report_mirror(op, totmirr, totfail); } return OPERATOR_FINISHED; diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 70f841e5e59..b3463915080 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1121,7 +1121,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op) /* mirror before smooth */ if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { - EDBM_verts_mirror_cache_begin(em, true); + EDBM_verts_mirror_cache_begin(em, false, true); } /* if there is a mirror modifier with clipping, flag the verts that @@ -1212,7 +1212,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op) /* mirror before smooth */ if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { - EDBM_verts_mirror_cache_begin(em, true); + EDBM_verts_mirror_cache_begin(em, false, true); } repeat = RNA_int_get(op->ptr, "repeat"); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index c2c79d337ea..fa857edb6fc 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1134,6 +1134,9 @@ static BMVert *cache_mirr_intptr_as_bmvert(intptr_t *index_lookup, int index) * ... * EDBM_verts_mirror_cache_end(em); * + * \param use_self Allow a vertex to reference its self. + * \param use_select Only cache selected verts. + * * \note why do we only allow x axis mirror editing? */ @@ -1141,13 +1144,14 @@ 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_select) +void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select) { Mesh *me = (Mesh *)em->ob->data; BMesh *bm = em->bm; BMIter iter; BMVert *v; - int li, topo = 0; + bool topo = false; + int cd_vmirr_offset; /* one or the other is used depending if topo is enabled */ struct BMBVHTree *tree = NULL; @@ -1159,13 +1163,16 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_select) EDBM_index_arrays_ensure(em, BM_VERT); - if (!CustomData_get_layer_named(&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 (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); } - li = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_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)); - bm->vdata.layers[li].flag |= CD_FLAG_TEMPORARY; + bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY; BM_mesh_elem_index_ensure(bm, BM_VERT); @@ -1183,20 +1190,20 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_select) /* do nothing */ } else { - BMVert *mirr; - int *idx = CustomData_bmesh_get_layer_n(&bm->vdata, v->head.data, li); + BMVert *v_mirr; + int *idx = BM_ELEM_CD_GET_VOID_P(v, cd_vmirr_offset); if (topo) { - mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, BM_elem_index_get(v)); + v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, BM_elem_index_get(v)); } else { float co[3] = {-v->co[0], v->co[1], v->co[2]}; - mirr = BKE_bmbvh_find_vert_closest(tree, co, BM_SEARCH_MAXDIST_MIRR); + v_mirr = BKE_bmbvh_find_vert_closest(tree, co, BM_SEARCH_MAXDIST_MIRR); } - if (mirr && mirr != v) { - *idx = BM_elem_index_get(mirr); - idx = CustomData_bmesh_get_layer_n(&bm->vdata, mirr->head.data, li); + 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); } else { @@ -1213,8 +1220,6 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_select) else { BKE_bmbvh_free(tree); } - - em->mirror_cdlayer = li; } BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v) diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 869b2fb8f2d..d0869a30cbf 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -1243,3 +1243,13 @@ void ED_mesh_calc_tessface(Mesh *mesh) BKE_mesh_tessface_calc(mesh); } } + +void ED_mesh_report_mirror(wmOperator *op, int totmirr, int totfail) +{ + if (totfail) { + BKE_reportf(op->reports, RPT_WARNING, "%d vertices mirrored, %d failed", totmirr, totfail); + } + else { + BKE_reportf(op->reports, RPT_INFO, "%d vertices mirrored", totmirr); + } +} diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index 2008e5ad4f3..af9f7220c26 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -152,10 +152,14 @@ static int ED_object_shape_key_remove(bContext *C, Object *ob) return 1; } -static int object_shape_key_mirror(bContext *C, Object *ob) +static bool object_shape_key_mirror(bContext *C, Object *ob, + int *r_totmirr, int *r_totfail) { KeyBlock *kb; Key *key; + int totmirr = 0, totfail = 0; + + *r_totmirr = *r_totfail = 0; key = BKE_key_from_object(ob); if (key == NULL) @@ -182,6 +186,7 @@ static int object_shape_key_mirror(bContext *C, Object *ob) fp1 = ((float *)kb->data) + i1 * 3; fp1[0] = -fp1[0]; tag_elem[i1] = 1; + totmirr++; } else if (i2 != -1) { if (tag_elem[i1] == 0 && tag_elem[i2] == 0) { @@ -195,9 +200,13 @@ static int object_shape_key_mirror(bContext *C, Object *ob) /* flip x axis */ fp1[0] = -fp1[0]; fp2[0] = -fp2[0]; + totmirr++; } tag_elem[i1] = tag_elem[i2] = 1; } + else { + totfail++; + } } mesh_octree_table(ob, NULL, NULL, 'e'); @@ -224,6 +233,7 @@ static int object_shape_key_mirror(bContext *C, Object *ob) i1 = LT_INDEX(lt, u, v, w); fp1 = ((float *)kb->data) + i1 * 3; fp1[0] = -fp1[0]; + totmirr++; } else { i1 = LT_INDEX(lt, u, v, w); @@ -237,6 +247,7 @@ static int object_shape_key_mirror(bContext *C, Object *ob) copy_v3_v3(fp2, tvec); fp1[0] = -fp1[0]; fp2[0] = -fp2[0]; + totmirr++; } } } @@ -246,6 +257,9 @@ static int object_shape_key_mirror(bContext *C, Object *ob) MEM_freeN(tag_elem); } + *r_totmirr = totmirr; + *r_totfail = totfail; + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); @@ -390,13 +404,16 @@ void OBJECT_OT_shape_key_retime(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -static int shape_key_mirror_exec(bContext *C, wmOperator *UNUSED(op)) +static int shape_key_mirror_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); + int totmirr = 0, totfail = 0; - if (!object_shape_key_mirror(C, ob)) + if (!object_shape_key_mirror(C, ob, &totmirr, &totfail)) return OPERATOR_CANCELLED; + ED_mesh_report_mirror(op, totmirr, totfail); + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index b3c8b1f720b..0b1fe03f5d5 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -2122,7 +2122,8 @@ static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, /* TODO, vgroup locking */ /* TODO, face masking */ void ED_vgroup_mirror(Object *ob, - const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups) + const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups, + int *r_totmirr, int *r_totfail) { #define VGROUP_MIRR_OP \ @@ -2136,8 +2137,11 @@ void ED_vgroup_mirror(Object *ob, BMVert *eve, *eve_mirr; MDeformVert *dvert, *dvert_mirr; char sel, sel_mirr; - int *flip_map, flip_map_len; + int *flip_map = NULL, flip_map_len; const int def_nr = ob->actdef - 1; + int totmirr = 0, totfail = 0; + + *r_totmirr = *r_totfail = 0; if ((mirror_weights == false && flip_vgroups == false) || (BLI_findlink(&ob->defbase, def_nr) == NULL)) @@ -2175,25 +2179,31 @@ void ED_vgroup_mirror(Object *ob, goto cleanup; } - EDBM_verts_mirror_cache_begin(em, false); + EDBM_verts_mirror_cache_begin(em, true, false); /* Go through the list of editverts and assign them */ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if ((eve_mirr = EDBM_verts_mirror_get(em, eve))) { - sel = BM_elem_flag_test(eve, BM_ELEM_SELECT); - sel_mirr = BM_elem_flag_test(eve_mirr, BM_ELEM_SELECT); + if (eve_mirr != eve) { + sel = BM_elem_flag_test(eve, BM_ELEM_SELECT); + sel_mirr = BM_elem_flag_test(eve_mirr, BM_ELEM_SELECT); - if ((sel || sel_mirr) && (eve != eve_mirr)) { - dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); - dvert_mirr = BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset); + if ((sel || sel_mirr) && (eve != eve_mirr)) { + dvert = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); + dvert_mirr = BM_ELEM_CD_GET_VOID_P(eve_mirr, cd_dvert_offset); - VGROUP_MIRR_OP; + VGROUP_MIRR_OP; + totmirr++; + } } /* don't use these again */ EDBM_verts_mirror_cache_clear(em, eve); EDBM_verts_mirror_cache_clear(em, eve_mirr); } + else { + totfail++; + } } EDBM_verts_mirror_cache_end(em); } @@ -2217,26 +2227,33 @@ void ED_vgroup_mirror(Object *ob, } for (vidx = 0, mv = me->mvert; vidx < me->totvert; vidx++, mv++) { - if ( ((mv->flag & ME_VERT_TMP_TAG) == 0) && - ((vidx_mirr = mesh_get_x_mirror_vert(ob, vidx)) != -1) && - (vidx != vidx_mirr) && - ((((mv_mirr = me->mvert + vidx_mirr)->flag) & ME_VERT_TMP_TAG) == 0)) - { - - if (use_vert_sel) { - sel = mv->flag & SELECT; - sel_mirr = mv_mirr->flag & SELECT; + if ((mv->flag & ME_VERT_TMP_TAG) == 0) { + if ((vidx_mirr = mesh_get_x_mirror_vert(ob, vidx)) != -1) { + if (vidx != vidx_mirr) { + mv_mirr = &me->mvert[vidx_mirr]; + if ((mv_mirr->flag & ME_VERT_TMP_TAG) == 0) { + + if (use_vert_sel) { + sel = mv->flag & SELECT; + sel_mirr = mv_mirr->flag & SELECT; + } + + if (sel || sel_mirr) { + dvert = &me->dvert[vidx]; + dvert_mirr = &me->dvert[vidx_mirr]; + + VGROUP_MIRR_OP; + totmirr++; + } + + mv->flag |= ME_VERT_TMP_TAG; + mv_mirr->flag |= ME_VERT_TMP_TAG; + } + } } - - if (sel || sel_mirr) { - dvert = &me->dvert[vidx]; - dvert_mirr = &me->dvert[vidx_mirr]; - - VGROUP_MIRR_OP; + else { + totfail++; } - - mv->flag |= ME_VERT_TMP_TAG; - mv_mirr->flag |= ME_VERT_TMP_TAG; } } } @@ -2278,6 +2295,7 @@ void ED_vgroup_mirror(Object *ob, dvert_mirr = <->dvert[i2]; VGROUP_MIRR_OP; + totmirr++; } } } @@ -2293,6 +2311,9 @@ void ED_vgroup_mirror(Object *ob, #endif cleanup: + *r_totmirr = totmirr; + *r_totfail = totfail; + if (flip_map) MEM_freeN(flip_map); #undef VGROUP_MIRR_OP @@ -3362,11 +3383,15 @@ void OBJECT_OT_vertex_group_limit_total(wmOperatorType *ot) static int vertex_group_mirror_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); + int totmirr = 0, totfail = 0; ED_vgroup_mirror(ob, RNA_boolean_get(op->ptr, "mirror_weights"), RNA_boolean_get(op->ptr, "flip_group_names"), - RNA_boolean_get(op->ptr, "all_groups")); + RNA_boolean_get(op->ptr, "all_groups"), + &totmirr, &totfail); + + ED_mesh_report_mirror(op, totmirr, totfail); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 2c548d330c0..b93f03bea0b 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1984,7 +1984,7 @@ static void createTransEditVerts(TransInfo *t) int cd_vert_bweight_offset = -1; if (t->flag & T_MIRROR) { - EDBM_verts_mirror_cache_begin(em, TRUE); + EDBM_verts_mirror_cache_begin(em, false, true); mirror = 1; } |