[Bf-blender-cvs] [04a9029] master: BMesh optimize face splitting by taking loops rather then verts
Campbell Barton
noreply at git.blender.org
Tue Dec 24 01:16:41 CET 2013
Commit: 04a902965e5e226e69c5c6e912dd2f513448d2ac
Author: Campbell Barton
Date: Tue Dec 24 11:04:03 2013 +1100
http://developer.blender.org/rB04a902965e5e226e69c5c6e912dd2f513448d2ac
BMesh optimize face splitting by taking loops rather then verts
- add BM_vert_pair_share_face
- add BM_loop_is_adjacent
- remove BM_verts_connect
===================================================================
M source/blender/bmesh/intern/bmesh_core.c
M source/blender/bmesh/intern/bmesh_core.h
M source/blender/bmesh/intern/bmesh_mods.c
M source/blender/bmesh/intern/bmesh_mods.h
M source/blender/bmesh/intern/bmesh_polygon.c
M source/blender/bmesh/intern/bmesh_queries.c
M source/blender/bmesh/intern/bmesh_queries.h
M source/blender/bmesh/intern/bmesh_queries_inline.h
M source/blender/bmesh/operators/bmo_connect.c
M source/blender/bmesh/operators/bmo_connect_nonplanar.c
M source/blender/bmesh/operators/bmo_dissolve.c
M source/blender/bmesh/operators/bmo_removedoubles.c
M source/blender/bmesh/operators/bmo_subdivide.c
M source/blender/bmesh/operators/bmo_subdivide_edgering.c
M source/blender/bmesh/tools/bmesh_bevel.c
M source/blender/bmesh/tools/bmesh_bisect_plane.c
M source/blender/bmesh/tools/bmesh_decimate_collapse.c
M source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
M source/blender/editors/mesh/editmesh_knife.c
M source/blender/python/bmesh/bmesh_py_utils.c
===================================================================
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index cbaffe2..7b3ca89 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -1258,7 +1258,7 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *UNUSED(example))
*
* \return A BMFace pointer
*/
-BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
+BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMLoop *l_v1, BMLoop *l_v2,
BMLoop **r_l,
#ifdef USE_BMESH_HOLES
ListBase *holes,
@@ -1275,21 +1275,12 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2,
BMFace *f2;
BMLoop *l_iter, *l_first;
- BMLoop *l_v1 = NULL, *l_v2 = NULL, *l_f1 = NULL, *l_f2 = NULL;
+ BMLoop *l_f1 = NULL, *l_f2 = NULL;
BMEdge *e;
- int i, len, f1len, f2len;
+ BMVert *v1 = l_v1->v, *v2 = l_v2->v;
+ int f1len, f2len;
- /* verify that v1 and v2 are in face */
- len = f->len;
- for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < len; i++, l_iter = l_iter->next) {
- if (l_iter->v == v1) l_v1 = l_iter;
- else if (l_iter->v == v2) l_v2 = l_iter;
- }
-
- if (!l_v1 || !l_v2) {
- BLI_assert(0);
- return NULL;
- }
+ BLI_assert(f == l_v1->f && f == l_v2->f);
/* allocate new edge between v1 and v2 */
e = BM_edge_create(bm, v1, v2, example, no_double ? BM_CREATE_NO_DOUBLE : BM_CREATE_NOP);
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index e9fd4e6..654698d 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -72,14 +72,15 @@ void BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len
BMEdge **e_in, int e_in_len);
/* EULER API - For modifying structure */
-BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1,
- BMVert *v2, BMLoop **r_l,
+BMFace *bmesh_sfme(BMesh *bm, BMFace *f,
+ BMLoop *l1, BMLoop *l2,
+ BMLoop **r_l,
#ifdef USE_BMESH_HOLES
- ListBase *holes,
+ ListBase *holes,
#endif
- BMEdge *example,
- const bool no_double
- );
+ BMEdge *example,
+ const bool no_double
+ );
BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e);
BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_edge_splice);
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 49c8c98..6d8dc53 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -252,48 +252,6 @@ BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f_a, BMFace *f_b, BMEdge *e, const
}
/**
- * \brief Connect Verts, Split Face
- *
- * connects two verts together, automatically (if very naively) finding the
- * face they both share (if there is one) and splitting it. Use this at your
- * own risk, as it doesn't handle the many complex cases it should (like zero-area faces,
- * multiple faces, etc).
- *
- * this is really only meant for cases where you don't know before hand the face
- * the two verts belong to for splitting (e.g. the subdivision operator).
- *
- * \return The newly created edge.
- */
-BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f)
-{
- BMIter fiter;
- BMIter viter;
- BMVert *v_iter;
- BMFace *f_iter;
-
- /* be warned: this can do weird things in some ngon situation, see BM_face_legal_splits */
- BM_ITER_ELEM (f_iter, &fiter, v1, BM_FACES_OF_VERT) {
- BM_ITER_ELEM (v_iter, &viter, f_iter, BM_FACES_OF_VERT) {
- if (v_iter == v2) {
- BMLoop *l_new;
-
- f_iter = BM_face_split(bm, f_iter, v1, v2, &l_new, NULL, false);
-
- if (r_f) {
- *r_f = f_iter;
- }
- return l_new->e;
- }
- }
- }
-
- if (r_f) {
- *r_f = NULL;
- }
- return NULL;
-}
-
-/**
* \brief Face Split
*
* Split a face along two vertices. returns the newly made face, and sets
@@ -310,13 +268,26 @@ BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f)
* if the split is successful (and the original original face will be the
* other side). NULL if the split fails.
*/
-BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l,
- BMEdge *example, const bool no_double)
+BMFace *BM_face_split(BMesh *bm, BMFace *f,
+ BMLoop *l_a, BMLoop *l_b,
+ BMLoop **r_l, BMEdge *example,
+ const bool no_double)
{
const bool has_mdisp = CustomData_has_layer(&bm->ldata, CD_MDISPS);
BMFace *f_new, *f_tmp;
- BLI_assert(v1 != v2);
+ BLI_assert(l_a != l_b);
+ BLI_assert(f == l_a->f && f == l_b->f);
+ BLI_assert(!BM_loop_is_adjacent(l_a, l_b));
+
+ /* could be an assert */
+ if (UNLIKELY(BM_loop_is_adjacent(l_a, l_b))) {
+ return NULL;
+ }
+
+ if (f != l_a->f || f != l_b->f) {
+ return NULL;
+ }
/* do we have a multires layer? */
if (has_mdisp) {
@@ -324,9 +295,9 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l
}
#ifdef USE_BMESH_HOLES
- f_new = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, no_double);
+ f_new = bmesh_sfme(bm, f, l_a, l_b, r_l, NULL, example, no_double);
#else
- f_new = bmesh_sfme(bm, f, v1, v2, r_l, example, no_double);
+ f_new = bmesh_sfme(bm, f, l_a, l_b, r_l, example, no_double);
#endif
if (f_new) {
@@ -369,7 +340,7 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l
*
* \param bm The bmesh
* \param f the original face
- * \param v1, v2 vertices which define the split edge, must be different
+ * \param l_a, l_b vertices which define the split edge, must be different
* \param cos Array of coordinates for intermediate points
* \param n Length of \a cos (must be > 0)
* \param r_l pointer which will receive the BMLoop for the first split edge (from \a v1) in the new face
@@ -379,16 +350,31 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l
* if the split is successful (and the original original face will be the
* other side). NULL if the split fails.
*/
-BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[][3], int n,
+BMFace *BM_face_split_n(BMesh *bm, BMFace *f,
+ BMLoop *l_a, BMLoop *l_b,
+ float cos[][3], int n,
BMLoop **r_l, BMEdge *example)
{
BMFace *f_new, *f_tmp;
BMLoop *l_dummy;
BMEdge *e, *e_new;
BMVert *v_new;
+ // BMVert *v_a = l_a->v; /* UNUSED */
+ BMVert *v_b = l_b->v;
int i, j;
- BLI_assert(v1 != v2);
+ BLI_assert(l_a != l_b);
+ BLI_assert(f == l_a->f && f == l_b->f);
+ BLI_assert(!BM_loop_is_adjacent(l_a, l_b));
+
+ /* could be an assert */
+ if (UNLIKELY(BM_loop_is_adjacent(l_a, l_b))) {
+ return NULL;
+ }
+
+ if (l_a->f != l_b->f) {
+ return NULL;
+ }
f_tmp = BM_face_copy(bm, bm, f, true, true);
@@ -396,12 +382,12 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
r_l = &l_dummy;
#ifdef USE_BMESH_HOLES
- f_new = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, false);
+ f_new = bmesh_sfme(bm, f, l_a, l_b, r_l, NULL, example, false);
#else
- f_new = bmesh_sfme(bm, f, v1, v2, r_l, example, false);
+ f_new = bmesh_sfme(bm, f, l_a, l_b, r_l, example, false);
#endif
- /* bmesh_sfme returns in r_l a Loop for f_new going from v1 to v2.
- * The radial_next is for f and goes from v2 to v1 */
+ /* bmesh_sfme returns in r_l a Loop for f_new going from v_a to v_b.
+ * The radial_next is for f and goes from v_b to v_a */
if (f_new) {
BM_elem_attrs_copy(bm, bm, f, f_new);
@@ -409,7 +395,7 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[
e = (*r_l)->e;
for (i = 0; i < n; i++) {
- v_new = bmesh_semv(bm, v2, e, &e_new);
+ v_new = bmesh_semv(bm, v_b, e, &e_new);
BLI_assert(v_new != NULL);
/* bmesh_semv returns in e_new the edge going from v_new to tv */
copy_v3_v3(v_new->co, cos[i]);
@@ -510,8 +496,14 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float
BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces), true);
if (f2) {
BMLoop *l_new = NULL;
- if (BM_face_split(bm, f2, tv, tv2, &l_new, NULL, false)) {
- e_new = l_new->e;
+ BMLoop *l_a, *l_b;
+
+ if ((l_a = BM_face_vert_share_loop(f2, tv)) &&
+ (l_b = BM_face_vert_share_loop(f2, tv2)))
+ {
+ if (BM_face_split(bm, f2, l_a, l_b, &l_new, NULL, false)) {
+ e_new = l_new->e;
+ }
}
}
}
@@ -1058,10 +1050,10 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_f
/* note, this assumes joining the faces _didnt_ also remove the verts.
* the #BM_edge_rotate_check will ensure this, but its possibly corrupt state or future edits
* break this */
- if (!BM_face_split(bm, f, v1, v2, NULL, NULL, true)) {
- return NULL;
- }
- else {
+ if ((l1 = BM_face_vert_share_loop(f, v1)) &&
+ (l2 = BM_face_vert_share_loop(f, v2)) &&
+ BM_face_split(bm, f, l1, l2, NULL, NULL, true))
+ {
/* we should really be able to know the faces some other way,
* rather then fetching them back from the edge, but this is predictable
* where using the return values from face split isn't. - campbell */
@@ -1071,6 +1063,9 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_f
fb->head.hflag = f_hflag_prev_2;
}
}
+ else {
+ return NULL;
+ }
return e_new;
}
diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h
index ca281c1..f3ed992 100644
--- a/source/blender/bmesh/intern/bmesh_mods.h
+++ b/source/blender/bmesh/intern/bmesh_mods.h
@@ -35,15 +35,13 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v);
BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, const bool do_del);
-BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f);
-
BMFace *BM_face_split(BMesh *bm, BMFace *f,
- BMVert *v1, BMV
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list