[Bf-blender-cvs] [49a3eaa] master: BMesh: face-flip, no need for temporary edge-array

Campbell Barton noreply at git.blender.org
Wed Nov 9 13:55:49 CET 2016


Commit: 49a3eaa3dc416d7f8c96c4c01da95c52a587821b
Author: Campbell Barton
Date:   Wed Nov 9 22:25:31 2016 +1100
Branches: master
https://developer.blender.org/rB49a3eaa3dc416d7f8c96c4c01da95c52a587821b

BMesh: face-flip, no need for temporary edge-array

Reverse loops in-place.

===================================================================

M	source/blender/bmesh/intern/bmesh_core.c
M	source/blender/bmesh/intern/bmesh_core.h

===================================================================

diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 6abc52d..ac4eb2c 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -1019,18 +1019,12 @@ static int UNUSED_FUNCTION(bm_loop_length)(BMLoop *l)
  * \brief Loop Reverse
  *
  * Changes the winding order of a face from CW to CCW or vice versa.
- * This euler is a bit peculiar in comparison to others as it is its
- * own inverse.
- *
- * BMESH_TODO: reinsert validation code.
  *
  * \param cd_loop_mdisp_offset: Cached result of `CustomData_get_offset(&bm->ldata, CD_MDISPS)`.
  * \param use_loop_mdisp_flip: When set, flip the Z-depth of the mdisp,
  * (use when flipping normals, disable when mirroring, eg: symmetrize).
- *
- * \return Success
  */
-static bool bm_loop_reverse_loop(
+static void bm_loop_reverse_loop(
         BMesh *bm, BMFace *f,
 #ifdef USE_BMESH_HOLES
         BMLoopList *lst,
@@ -1044,39 +1038,62 @@ static bool bm_loop_reverse_loop(
 	BMLoop *l_first = f->l_first;
 #endif
 
-	const int len = f->len;
-	BMLoop *l_iter;
-	BMEdge **edar = BLI_array_alloca(edar, len);
-	int i;
+	/* track previous cycles radial state */
+	BMEdge *e_prev = l_first->prev->e;
+	BMLoop *l_prev_radial_next = l_first->prev->radial_next;
+	BMLoop *l_prev_radial_prev = l_first->prev->radial_prev;
+	bool is_prev_boundary = l_prev_radial_next == l_prev_radial_next->radial_next;
 
-	for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
-		bmesh_radial_loop_remove((edar[i] = l_iter->e), l_iter);
-	}
+	BMLoop *l_iter = l_first;
+	do {
+		BMEdge *e_iter = l_iter->e;
+		BMLoop *l_iter_radial_next = l_iter->radial_next;
+		BMLoop *l_iter_radial_prev = l_iter->radial_prev;
+		bool is_iter_boundary = l_iter_radial_next == l_iter_radial_next->radial_next;
+
+#if 0
+		bmesh_radial_loop_remove(e_curr, l_iter);
+		bmesh_radial_loop_append(e_prev, l_iter);
+#else
+		/* inline loop reversal */
+		if (is_prev_boundary) {
+			/* boundary */
+			l_iter->radial_next = l_iter;
+			l_iter->radial_prev = l_iter;
+		}
+		else {
+			/* non-boundary, replace radial links */
+			l_iter->radial_next = l_prev_radial_next;
+			l_iter->radial_prev = l_prev_radial_prev;
+			l_prev_radial_next->radial_prev = l_iter;
+			l_prev_radial_prev->radial_next = l_iter;
+		}
+
+		if (e_iter->l == l_iter) {
+			e_iter->l = l_iter->next;
+		}
+		l_iter->e = e_prev;
+#endif
+
+		SWAP(BMLoop *, l_iter->next, l_iter->prev);
 
-	/* actually reverse the loop */
-	for (i = 0, l_iter = l_first; i < len; i++) {
-		BMLoop *oldnext = l_iter->next;
-		BMLoop *oldprev = l_iter->prev;
-		l_iter->next = oldprev;
-		l_iter->prev = oldnext;
-		l_iter = oldnext;
-		
 		if (cd_loop_mdisp_offset != -1) {
 			MDisps *md = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset);
 			BKE_mesh_mdisp_flip(md, use_loop_mdisp_flip);
 		}
-	}
 
-	/* rebuild radial */
-	for (i = 0, l_iter = l_first->prev; i < len; i++, l_iter = l_iter->prev) {
-		BLI_assert(BM_verts_in_edge(l_iter->v, l_iter->next->v, edar[i]));
-		l_iter->e = edar[i];
-		bmesh_radial_loop_append(l_iter->e, l_iter);
-	}
+		e_prev = e_iter;
+		l_prev_radial_next = l_iter_radial_next;
+		l_prev_radial_prev = l_iter_radial_prev;
+		is_prev_boundary = is_iter_boundary;
+
+		/* step to next (now swapped) */
+	} while ((l_iter = l_iter->prev) != l_first);
 
 #ifndef NDEBUG
 	/* validate radial */
-	for (i = 0, l_iter = l_first; i < len; i++, l_iter = l_iter->next) {
+	int i;
+	for (i = 0, l_iter = l_first; i < f->len; i++, l_iter = l_iter->next) {
 		BM_CHECK_ELEMENT(l_iter);
 		BM_CHECK_ELEMENT(l_iter->e);
 		BM_CHECK_ELEMENT(l_iter->v);
@@ -1088,21 +1105,19 @@ static bool bm_loop_reverse_loop(
 
 	/* Loop indices are no more valid! */
 	bm->elem_index_dirty |= BM_LOOP;
-
-	return true;
 }
 
 /**
  * \brief Flip the faces direction
  */
-bool bmesh_loop_reverse(
+void bmesh_loop_reverse(
         BMesh *bm, BMFace *f,
         const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
 {
 #ifdef USE_BMESH_HOLES
-	return bm_loop_reverse_loop(bm, f, f->loops.first, cd_loop_mdisp_offset, use_loop_mdisp_flip);
+	bm_loop_reverse_loop(bm, f, f->loops.first, cd_loop_mdisp_offset, use_loop_mdisp_flip);
 #else
-	return bm_loop_reverse_loop(bm, f, cd_loop_mdisp_offset, use_loop_mdisp_flip);
+	bm_loop_reverse_loop(bm, f, cd_loop_mdisp_offset, use_loop_mdisp_flip);
 #endif
 }
 
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index fb5702b..f72e9d7 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -75,7 +75,7 @@ void    bmesh_vert_separate(
         BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
         const bool copy_select);
 
-bool    bmesh_loop_reverse(
+void    bmesh_loop_reverse(
         BMesh *bm, BMFace *f,
         const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip);




More information about the Bf-blender-cvs mailing list