fix [#35939] [Edit - Vertex mode] [Select]-[Mirror] did not returns right result.

This commit is contained in:
2013-07-01 21:56:59 +00:00
parent 3d845b4a17
commit d0ce73c548
4 changed files with 119 additions and 21 deletions

View File

@@ -82,6 +82,8 @@ void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const int ax
const bool use_self, const bool use_select, const bool use_toplogy);
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);
struct BMEdge *EDBM_verts_mirror_get_edge(struct BMEditMesh *em, struct BMEdge *e);
struct BMFace *EDBM_verts_mirror_get_face(struct BMEditMesh *em, struct BMFace *f);
void EDBM_verts_mirror_cache_clear(struct BMEditMesh *em, struct BMVert *v);
void EDBM_verts_mirror_cache_end(struct BMEditMesh *em);
@@ -281,6 +283,8 @@ 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);
void ED_mesh_report_mirror_ex(struct wmOperator *op, int totmirr, int totfail,
char selectmode);
/* mesh backup */
typedef struct BMBackup {

View File

@@ -78,7 +78,7 @@ void EDBM_select_mirrored(BMEditMesh *em, bool extend,
int *r_totmirr, int *r_totfail)
{
Mesh *me = (Mesh *)em->ob->data;
BMVert *v1, *v2;
BMesh *bm = em->bm;
BMIter iter;
int totmirr = 0;
int totfail = 0;
@@ -86,12 +86,23 @@ void EDBM_select_mirrored(BMEditMesh *em, bool extend,
*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)) {
BM_elem_flag_disable(v1, BM_ELEM_TAG);
/* select -> tag */
if (bm->selectmode & SCE_SELECT_VERTEX) {
BMVert *v;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
BM_elem_flag_set(v, BM_ELEM_TAG, BM_elem_flag_test(v, BM_ELEM_SELECT));
}
else {
BM_elem_flag_enable(v1, BM_ELEM_TAG);
}
else if (em->selectmode & SCE_SELECT_EDGE) {
BMEdge *e;
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT));
}
}
else {
BMFace *f;
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
BM_elem_flag_set(f, BM_ELEM_TAG, BM_elem_flag_test(f, BM_ELEM_SELECT));
}
}
@@ -100,19 +111,50 @@ void EDBM_select_mirrored(BMEditMesh *em, bool extend,
if (!extend)
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
BM_ITER_MESH (v1, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(v1, BM_ELEM_TAG) || BM_elem_flag_test(v1, BM_ELEM_HIDDEN))
continue;
v2 = EDBM_verts_mirror_get(em, v1);
if (v2) {
if (!BM_elem_flag_test(v2, BM_ELEM_HIDDEN)) {
BM_vert_select_set(em->bm, v2, true);
totmirr++;
if (bm->selectmode & SCE_SELECT_VERTEX) {
BMVert *v;
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN) && BM_elem_flag_test(v, BM_ELEM_TAG)) {
BMVert *v_mirr = EDBM_verts_mirror_get(em, v);
if (v_mirr && !BM_elem_flag_test(v_mirr, BM_ELEM_HIDDEN)) {
BM_vert_select_set(bm, v_mirr, true);
totmirr++;
}
else {
totfail++;
}
}
}
else {
totfail++;
}
else if (em->selectmode & SCE_SELECT_EDGE) {
BMEdge *e;
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN) && BM_elem_flag_test(e, BM_ELEM_TAG)) {
BMEdge *e_mirr = EDBM_verts_mirror_get_edge(em, e);
if (e_mirr && !BM_elem_flag_test(e_mirr, BM_ELEM_HIDDEN)) {
BM_edge_select_set(bm, e_mirr, true);
totmirr++;
}
else {
totfail++;
}
}
}
}
else {
BMFace *f;
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN) && BM_elem_flag_test(f, BM_ELEM_TAG)) {
BMFace *f_mirr = EDBM_verts_mirror_get_face(em, f);
if (f_mirr && !BM_elem_flag_test(f_mirr, BM_ELEM_HIDDEN)) {
BM_face_select_set(bm, f_mirr, true);
totmirr++;
}
else {
totfail++;
}
}
}
}
@@ -2215,13 +2257,14 @@ static int edbm_select_mirror_exec(bContext *C, wmOperator *op)
if (em->bm->totvert && em->bm->totvertsel) {
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);
ED_mesh_report_mirror_ex(op, totmirr, totfail, em->bm->selectmode);
}
return OPERATOR_FINISHED;

View File

@@ -35,6 +35,7 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
#include "BLI_array.h"
#include "BKE_DerivedMesh.h"
#include "BKE_context.h"
@@ -1270,6 +1271,38 @@ BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v)
return NULL;
}
BMEdge *EDBM_verts_mirror_get_edge(BMEditMesh *em, BMEdge *e)
{
BMVert *v1_mirr = EDBM_verts_mirror_get(em, e->v1);
if (v1_mirr) {
BMVert *v2_mirr = EDBM_verts_mirror_get(em, e->v2);
if (v2_mirr) {
return BM_edge_exists(v1_mirr, v2_mirr);
}
}
return NULL;
}
BMFace *EDBM_verts_mirror_get_face(BMEditMesh *em, BMFace *f)
{
BMFace *f_mirr = NULL;
BMVert **v_mirr_arr = BLI_array_alloca(v_mirr_arr, f->len);
BMLoop *l_iter, *l_first;
unsigned int i = 0;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
if ((v_mirr_arr[i++] = EDBM_verts_mirror_get(em, l_iter->v)) == NULL) {
return NULL;
}
} while ((l_iter = l_iter->next) != l_first);
BM_face_exists(v_mirr_arr, f->len, &f_mirr);
return f_mirr;
}
void EDBM_verts_mirror_cache_clear(BMEditMesh *em, BMVert *v)
{
int *mirr = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, em->mirror_cdlayer);

View File

@@ -1244,12 +1244,30 @@ void ED_mesh_calc_tessface(Mesh *mesh)
}
}
void ED_mesh_report_mirror(wmOperator *op, int totmirr, int totfail)
void ED_mesh_report_mirror_ex(wmOperator *op, int totmirr, int totfail,
char selectmode)
{
if (totfail) {
BKE_reportf(op->reports, RPT_WARNING, "%d vertices mirrored, %d failed", totmirr, totfail);
const char *elem_type;
if (selectmode & SCE_SELECT_VERTEX) {
elem_type = "vertices";
}
else if (selectmode & SCE_SELECT_EDGE) {
elem_type = "edges";
}
else {
BKE_reportf(op->reports, RPT_INFO, "%d vertices mirrored", totmirr);
elem_type = "faces";
}
if (totfail) {
BKE_reportf(op->reports, RPT_WARNING, "%d %s mirrored, %d failed", totmirr, elem_type, totfail);
}
else {
BKE_reportf(op->reports, RPT_INFO, "%d %s mirrored", totmirr, elem_type);
}
}
void ED_mesh_report_mirror(wmOperator *op, int totmirr, int totfail)
{
ED_mesh_report_mirror_ex(op, totmirr, totfail, SCE_SELECT_VERTEX);
}