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:
authorCampbell Barton <ideasman42@gmail.com>2019-01-17 04:34:05 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-01-17 04:36:17 +0300
commit2f372654b6f30a643a5c448895d2ffae536c86c5 (patch)
tree0e539d83059b060150d5403d0846e811ee46f6c1 /source/blender/bmesh/intern
parent371006ddea9ef3df7b1e8c83ad28bd41bc833f87 (diff)
BMesh: keep selection history when removing doubles
Auto-merge would loose the active vertex.
Diffstat (limited to 'source/blender/bmesh/intern')
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c65
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.h3
2 files changed, 68 insertions, 0 deletions
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index add4529e18d..5ac5dedb595 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -43,6 +43,9 @@
#include "bmesh.h"
#include "bmesh_structure.h"
+/* For '_FLAG_OVERLAP'. */
+#include "bmesh_private.h"
+
static void recount_totsels(BMesh *bm)
{
const char iter_types[3] = {BM_VERTS_OF_MESH,
@@ -1058,6 +1061,68 @@ GHash *BM_select_history_map_create(BMesh *bm)
return map;
}
+/**
+ * Map arguments may all be the same pointer.
+ */
+void BM_select_history_merge_from_targetmap(
+ BMesh *bm,
+ GHash *vert_map,
+ GHash *edge_map,
+ GHash *face_map,
+ const bool use_chain)
+{
+
+#ifdef DEBUG
+ for (BMEditSelection *ese = bm->selected.first; ese; ese = ese->next) {
+ BLI_assert(BM_ELEM_API_FLAG_TEST(ese->ele, _FLAG_OVERLAP) == 0);
+ }
+#endif
+
+ for (BMEditSelection *ese = bm->selected.first; ese; ese = ese->next) {
+ BM_ELEM_API_FLAG_ENABLE(ese->ele, _FLAG_OVERLAP);
+
+ /* Only loop when (use_chain == true). */
+ GHash *map = NULL;
+ switch (ese->ele->head.htype) {
+ case BM_VERT: map = vert_map; break;
+ case BM_EDGE: map = edge_map; break;
+ case BM_FACE: map = face_map; break;
+ default: BMESH_ASSERT(0); break;
+ }
+ if (map != NULL) {
+ BMElem *ele_dst = ese->ele;
+ while (true) {
+ BMElem *ele_dst_next = BLI_ghash_lookup(map, ele_dst);
+ BLI_assert(ele_dst != ele_dst_next);
+ if (ele_dst_next == NULL) {
+ break;
+ }
+ ele_dst = ele_dst_next;
+ /* Break loop on circular reference (should never happen). */
+ if (UNLIKELY(ele_dst == ese->ele)) {
+ BLI_assert(0);
+ break;
+ }
+ if (use_chain == false) {
+ break;
+ }
+ }
+ ese->ele = ele_dst;
+ }
+ }
+
+ /* Remove overlapping duplicates. */
+ for (BMEditSelection *ese = bm->selected.first, *ese_next; ese; ese = ese_next) {
+ ese_next = ese->next;
+ if (BM_ELEM_API_FLAG_TEST(ese->ele, _FLAG_OVERLAP)) {
+ BM_ELEM_API_FLAG_DISABLE(ese->ele, _FLAG_OVERLAP);
+ }
+ else {
+ BLI_freelinkN(&bm->selected, ese);
+ }
+ }
+}
+
void BM_mesh_elem_hflag_disable_test(
BMesh *bm, const char htype, const char hflag,
const bool respecthide, const bool overwrite, const char hflag_test)
diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h
index 4730af66a74..8e6a8f9e991 100644
--- a/source/blender/bmesh/intern/bmesh_marking.h
+++ b/source/blender/bmesh/intern/bmesh_marking.h
@@ -114,6 +114,9 @@ void BM_select_history_clear(BMesh *bm);
bool BM_select_history_active_get(BMesh *bm, struct BMEditSelection *ese);
struct GHash *BM_select_history_map_create(BMesh *bm);
+void BM_select_history_merge_from_targetmap(
+ BMesh *bm, GHash *vert_map, GHash *edge_map, GHash *face_map, const bool use_chain);
+
#define BM_SELECT_HISTORY_BACKUP(bm) { \
ListBase _bm_prev_selected = (bm)->selected; BLI_listbase_clear(&(bm)->selected)