Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_marking.c')
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c188
1 files changed, 139 insertions, 49 deletions
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index ee35d8cd1d2..8aa64906019 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -41,6 +41,7 @@
#include "BLI_listbase.h"
#include "bmesh.h"
+#include "bmesh_structure.h"
static void recount_totsels(BMesh *bm)
{
@@ -69,6 +70,69 @@ static void recount_totsels(BMesh *bm)
}
}
+/** \name BMesh helper functions for selection flushing.
+ * \{ */
+
+static bool bm_vert_is_edge_select_any_other(BMVert *v, BMEdge *e_first)
+{
+ BMEdge *e_iter = e_first;
+
+ /* start by stepping over the current edge */
+ while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first) {
+ if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+#if 0
+static bool bm_vert_is_edge_select_any(BMVert *v)
+{
+ if (v->e) {
+ BMEdge *e_iter, *e_first;
+ e_iter = e_first = v->e;
+ do {
+ if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT)) {
+ return true;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return false;
+}
+#endif
+
+static bool bm_edge_is_face_select_any_other(BMLoop *l_first)
+{
+ BMLoop *l_iter = l_first;
+
+ /* start by stepping over the current face */
+ while ((l_iter = l_iter->radial_next) != l_first) {
+ if (BM_elem_flag_test(l_iter->f, BM_ELEM_SELECT)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+#if 0
+static bool bm_edge_is_face_select_any(BMEdge *e)
+{
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ if (BM_elem_flag_test(l_iter->f, BM_ELEM_SELECT)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ return false;
+}
+#endif
+
+/** \} */
+
/**
* \brief Select Mode Clean
*
@@ -341,8 +405,8 @@ void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select)
if (select) {
if (!BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- bm->totvertsel += 1;
BM_elem_flag_enable(v, BM_ELEM_SELECT);
+ bm->totvertsel += 1;
}
}
else {
@@ -367,39 +431,27 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
}
if (select) {
- if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) bm->totedgesel += 1;
-
- BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ bm->totedgesel += 1;
+ }
BM_vert_select_set(bm, e->v1, true);
BM_vert_select_set(bm, e->v2, true);
}
else {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) bm->totedgesel -= 1;
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ bm->totedgesel -= 1;
+ }
if ((bm->selectmode & SCE_SELECT_VERTEX) == 0) {
- BMIter iter;
- BMVert *verts[2] = {e->v1, e->v2};
- BMEdge *e2;
int i;
/* check if the vert is used by a selected edge */
for (i = 0; i < 2; i++) {
- bool deselect = true;
-
- for (e2 = BM_iter_new(&iter, bm, BM_EDGES_OF_VERT, verts[i]); e2; e2 = BM_iter_step(&iter)) {
- if (e2 == e) {
- continue;
- }
-
- if (BM_elem_flag_test(e2, BM_ELEM_SELECT)) {
- deselect = false;
- break;
- }
- }
-
- if (deselect) {
- BM_vert_select_set(bm, verts[i], false);
+ BMVert *v = *((&e->v1) + i);
+ if (bm_vert_is_edge_select_any_other(v, e) == false) {
+ BM_vert_select_set(bm, v, false);
}
}
}
@@ -430,10 +482,10 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
if (select) {
if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- bm->totfacesel++;
+ BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ bm->totfacesel += 1;
}
- BM_elem_flag_enable(f, BM_ELEM_SELECT);
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
BM_vert_select_set(bm, l_iter->v, true);
@@ -441,42 +493,80 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
} while ((l_iter = l_iter->next) != l_first);
}
else {
- BMIter liter;
- BMLoop *l;
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) bm->totfacesel -= 1;
- BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ bm->totfacesel -= 1;
+ }
/* flush down to edges */
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- BMIter fiter;
- BMFace *f2;
- BM_ITER_ELEM (f2, &fiter, l->e, BM_FACES_OF_EDGE) {
- if (BM_elem_flag_test(f2, BM_ELEM_SELECT))
- break;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ /* vertex flushing is handled below */
+ if (bm_edge_is_face_select_any_other(l_iter) == false) {
+ BM_edge_select_set_noflush(bm, l_iter->e, false);
}
+ } while ((l_iter = l_iter->next) != l_first);
- if (!f2) {
- BM_edge_select_set(bm, l->e, false);
+ /* flush down to verts */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (bm_vert_is_edge_select_any_other(l_iter->v, l_iter->e) == false) {
+ BM_vert_select_set(bm, l_iter->v, false);
}
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+}
+
+/** \name Non flushing versions element selection.
+ * \{ */
+
+void BM_edge_select_set_noflush(BMesh *bm, BMEdge *e, const bool select)
+{
+ BLI_assert(e->head.htype == BM_EDGE);
+
+ if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ return;
+ }
+
+ if (select) {
+ if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ bm->totedgesel += 1;
}
+ }
+ else {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ bm->totedgesel -= 1;
+ }
+ }
+}
- /* flush down to verts */
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- BMIter eiter;
- BMEdge *e;
- BM_ITER_ELEM (e, &eiter, l->v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT))
- break;
- }
+void BM_face_select_set_noflush(BMesh *bm, BMFace *f, const bool select)
+{
+ BLI_assert(f->head.htype == BM_FACE);
- if (!e) {
- BM_vert_select_set(bm, l->v, false);
- }
+ if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ return;
+ }
+
+ if (select) {
+ if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ bm->totfacesel += 1;
+ }
+ }
+ else {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ bm->totfacesel -= 1;
}
}
}
+/** \} */
+
/**
* Select Mode Set
*