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>2015-11-19 10:12:20 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-11-19 14:52:17 +0300
commit9c044b4773a9e4b610b515cd369197a7c3e38f62 (patch)
treef8cff236fc8a846e6bb687e9b0588e94e65392f0 /source/blender/bmesh/intern
parent93fb07fbd55afcaac15e96b93892e65341bb92c4 (diff)
BMesh: new API call to collapse an edge
Existing collapse functions were strict regarding the number of verts sharing an edge. BM_edge_collapse allows any edge to be passed in without first having to manipulate geometry.
Diffstat (limited to 'source/blender/bmesh/intern')
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c98
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c10
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.h3
4 files changed, 115 insertions, 0 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 618407ba5b6..a018c11999c 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -1856,6 +1856,104 @@ BMEdge *bmesh_jekv(
}
/**
+ * \brief Join Vert Kill Edge (JVKE)
+ *
+ * Collapse an edge, merging surrounding data.
+ *
+ * Unlike #BM_vert_collapse_edge & #bmesh_jekv which only handle 2 valence verts,
+ * this can handle any number of connected edges/faces.
+ *
+ * <pre>
+ * Before: -> After:
+ * +-+-+-+ +-+-+-+
+ * | | | | | \ / |
+ * +-+-+-+ +--+--+
+ * | | | | | / \ |
+ * +-+-+-+ +-+-+-+
+ * </pre>
+ */
+BMVert *bmesh_jvke(
+ BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
+ const bool do_del, const bool check_edge_double,
+ const bool kill_degenerate_faces)
+{
+ BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *);
+ BMVert *v_target = BM_edge_other_vert(e_kill, v_kill);
+
+ BLI_assert(BM_vert_in_edge(e_kill, v_kill));
+
+ if (e_kill->l) {
+ BMLoop *l_kill, *l_first, *l_kill_next;
+ l_kill = l_first = e_kill->l;
+ do {
+ /* relink loops and fix vertex pointer */
+ if (l_kill->next->v == v_kill) {
+ l_kill->next->v = v_target;
+ }
+
+ l_kill->next->prev = l_kill->prev;
+ l_kill->prev->next = l_kill->next;
+ if (BM_FACE_FIRST_LOOP(l_kill->f) == l_kill) {
+ BM_FACE_FIRST_LOOP(l_kill->f) = l_kill->next;
+ }
+
+ /* fix len attribute of face */
+ l_kill->f->len--;
+ if (kill_degenerate_faces) {
+ if (l_kill->f->len < 3) {
+ BLI_SMALLSTACK_PUSH(faces_degenerate, l_kill->f);
+ }
+ }
+ l_kill_next = l_kill->radial_next;
+
+ bm_kill_only_loop(bm, l_kill);
+
+ } while ((l_kill = l_kill_next) != l_first);
+
+ e_kill->l = NULL;
+ }
+
+ BM_edge_kill(bm, e_kill);
+ BM_CHECK_ELEMENT(v_kill);
+ BM_CHECK_ELEMENT(v_target);
+
+ if (v_target->e && v_kill->e) {
+ /* inline BM_vert_splice(bm, v_target, v_kill); */
+ BMEdge *e;
+ while ((e = v_kill->e)) {
+ BMEdge *e_target;
+
+ if (check_edge_double) {
+ e_target = BM_edge_exists(v_target, BM_edge_other_vert(e, v_kill));
+ }
+
+ bmesh_edge_vert_swap(e, v_target, v_kill);
+ BLI_assert(e->v1 != e->v2);
+
+ if (check_edge_double) {
+ if (e_target) {
+ BM_edge_splice(bm, e_target, e);
+ }
+ }
+ }
+ }
+
+ if (kill_degenerate_faces) {
+ BMFace *f_kill;
+ while ((f_kill = BLI_SMALLSTACK_POP(faces_degenerate))) {
+ BM_face_kill(bm, f_kill);
+ }
+ }
+
+ if (do_del) {
+ BLI_assert(v_kill->e == NULL);
+ bm_kill_only_vert(bm, v_kill);
+ }
+
+ return v_target;
+}
+
+/**
* \brief Join Face Kill Edge (JFKE)
*
* Takes two faces joined by a single 2-manifold edge and fuses them together.
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index d6d5a4d7296..a18d96824b7 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -100,6 +100,10 @@ BMEdge *bmesh_jekv(
BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
const bool do_del, const bool check_edge_splice,
const bool kill_degenerate_faces);
+BMVert *bmesh_jvke(
+ BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
+ const bool do_del, const bool check_edge_double,
+ const bool kill_degenerate_faces);
BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep);
BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep);
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 66be8e0e757..cde231b4494 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -1117,6 +1117,16 @@ BMEdge *BM_vert_collapse_edge(
#undef DO_V_INTERP
/**
+ * Collapse and edge into a single vertex.
+ */
+BMVert *BM_edge_collapse(
+ BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
+ const bool do_del, const bool kill_degenerate_faces)
+{
+ return bmesh_jvke(bm, e_kill, v_kill, do_del, true, kill_degenerate_faces);
+}
+
+/**
* \brief Edge Split
*
* <pre>
diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h
index 1b826b1e0b2..142568e6e1a 100644
--- a/source/blender/bmesh/intern/bmesh_mods.h
+++ b/source/blender/bmesh/intern/bmesh_mods.h
@@ -59,6 +59,9 @@ BMEdge *BM_vert_collapse_edge(
BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
const bool do_del, const bool kill_degenerate_faces);
+BMVert *BM_edge_collapse(
+ BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
+ const bool do_del, const bool kill_degenerate_faces);
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float percent);