fix [#35939] [Edit - Vertex mode] [Select]-[Mirror] did not returns right result.
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user