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
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2016-11-09 14:25:31 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-11-09 16:08:26 +0300
commit49a3eaa3dc416d7f8c96c4c01da95c52a587821b (patch)
treed6a3daa41a75bdbf02a56de0ed7606b2eb08e412 /source
parente9689e1a204ee9b74fae7d0051b79649e79035f7 (diff)
BMesh: face-flip, no need for temporary edge-array
Reverse loops in-place.
Diffstat (limited to 'source')
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c85
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h2
2 files changed, 51 insertions, 36 deletions
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 6abc52d75ef..ac4eb2c33fd 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 fb5702bc574..f72e9d7b198 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);