diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-03-18 04:48:59 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-03-18 04:48:59 +0400 |
commit | c1ceab1281ccf061f03f8000bf190a082a5385d8 (patch) | |
tree | 01b9a9cfca80432d316bdad6c18c74eb025e9eb0 /source/blender/bmesh | |
parent | 0d9c98c4bbfbc8c70c4772086dd09a51d01921ef (diff) | |
parent | 66a35e089a64d27bfc09c2225a530069eca05875 (diff) |
Merged changes in the trunk up to revision 55357.
Resolved conflicts:
release/datafiles/startup.blend
source/blender/editors/space_nla/nla_buttons.c
Also updated source/blender/blenkernel/intern/linestyle.c as a follow-up of
recent changes for the use of bool.
Diffstat (limited to 'source/blender/bmesh')
37 files changed, 809 insertions, 658 deletions
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index bf719a5c790..c3ec5dd83b3 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -57,7 +57,6 @@ set(SRC operators/bmo_smooth_laplacian.c operators/bmo_symmetrize.c operators/bmo_subdivide.c - operators/bmo_subdivide.h operators/bmo_triangulate.c operators/bmo_unsubdivide.c operators/bmo_utils.c diff --git a/source/blender/bmesh/SConscript b/source/blender/bmesh/SConscript index fa6bdbcf26f..de839f7f6a6 100644 --- a/source/blender/bmesh/SConscript +++ b/source/blender/bmesh/SConscript @@ -34,16 +34,16 @@ sources += env.Glob('operators/*.c') sources += env.Glob('tools/*.c') incs = [ - './', - '../blenfont', - '../blenlib', - '../makesdna', - '../blenkernel', - '#/intern/guardedalloc', - '#/extern/bullet2/src', - '#/extern/rangetree', - '#/intern/opennl/extern' - ] + './', + '../blenfont', + '../blenlib', + '../makesdna', + '../blenkernel', + '#/intern/guardedalloc', + '#/extern/bullet2/src', + '#/extern/rangetree', + '#/intern/opennl/extern' + ] defs = [] diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 6dc0218da93..845785a26d7 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -252,6 +252,9 @@ enum { * not have functions clobber them */ }; +struct BPy_BMGeneric; +extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self); + /* defines */ #define BM_ELEM_CD_GET_VOID_P(ele, offset) \ (assert(offset != -1), (void *)((char *)(ele)->head.data + (offset))) diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 643e73e02b4..a11d45a7a5a 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -942,7 +942,7 @@ static bool disk_is_flagged(BMVert *v, int flag) */ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del) { - BMFace *f, *newf; + BMFace *f, *f_new; #ifdef USE_BMESH_HOLES BMLoopList *lst; ListBase holes = {NULL, NULL}; @@ -1036,15 +1036,15 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del) } /* create region face */ - newf = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL; - if (UNLIKELY(!newf || BMO_error_occurred(bm))) { + f_new = tote ? BM_face_create_ngon(bm, v1, v2, edges, tote, 0) : NULL; + if (UNLIKELY(!f_new || BMO_error_occurred(bm))) { if (!BMO_error_occurred(bm)) err = N_("Invalid boundary region to join faces"); goto error; } /* copy over loop data */ - l_iter = l_first = BM_FACE_FIRST_LOOP(newf); + l_iter = l_first = BM_FACE_FIRST_LOOP(f_new); do { BMLoop *l2 = l_iter->radial_next; @@ -1064,34 +1064,34 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del) } } while ((l_iter = l_iter->next) != l_first); - BM_elem_attrs_copy(bm, bm, faces[0], newf); + BM_elem_attrs_copy(bm, bm, faces[0], f_new); #ifdef USE_BMESH_HOLES /* add holes */ - BLI_movelisttolist(&newf->loops, &holes); + BLI_movelisttolist(&f_new->loops, &holes); #endif /* update loop face pointer */ #ifdef USE_BMESH_HOLES - for (lst = newf->loops.first; lst; lst = lst->next) + for (lst = f_new->loops.first; lst; lst = lst->next) #endif { #ifdef USE_BMESH_HOLES l_iter = l_first = lst->first; #else - l_iter = l_first = BM_FACE_FIRST_LOOP(newf); + l_iter = l_first = BM_FACE_FIRST_LOOP(f_new); #endif do { - l_iter->f = newf; + l_iter->f = f_new; } while ((l_iter = l_iter->next) != l_first); } bm_elements_systag_disable(faces, totface, _FLAG_JF); - BM_ELEM_API_FLAG_DISABLE(newf, _FLAG_JF); + BM_ELEM_API_FLAG_DISABLE(f_new, _FLAG_JF); /* handle multi-res data */ if (CustomData_has_layer(&bm->ldata, CD_MDISPS)) { - l_iter = l_first = BM_FACE_FIRST_LOOP(newf); + l_iter = l_first = BM_FACE_FIRST_LOOP(f_new); do { for (i = 0; i < totface; i++) { BM_loop_interp_multires(bm, l_iter, faces[i]); @@ -1120,8 +1120,8 @@ BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del) BLI_array_free(deledges); BLI_array_free(delverts); - BM_CHECK_ELEMENT(newf); - return newf; + BM_CHECK_ELEMENT(f_new); + return f_new; error: bm_elements_systag_disable(faces, totface, _FLAG_JF); @@ -1210,18 +1210,18 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMFace *f2; BMLoop *l_iter, *l_first; - BMLoop *v1loop = NULL, *v2loop = NULL, *f1loop = NULL, *f2loop = NULL; + BMLoop *l_v1 = NULL, *l_v2 = NULL, *l_f1 = NULL, *l_f2 = NULL; BMEdge *e; int i, len, 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) v1loop = l_iter; - else if (l_iter->v == v2) v2loop = l_iter; + if (l_iter->v == v1) l_v1 = l_iter; + else if (l_iter->v == v2) l_v2 = l_iter; } - if (!v1loop || !v2loop) { + if (!l_v1 || !l_v2) { return NULL; } @@ -1229,28 +1229,28 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, e = BM_edge_create(bm, v1, v2, example, no_double ? BM_CREATE_NO_DOUBLE : 0); f2 = bm_face_create__sfme(bm, f); - f1loop = bm_loop_create(bm, v2, e, f, v2loop, 0); - f2loop = bm_loop_create(bm, v1, e, f2, v1loop, 0); + l_f1 = bm_loop_create(bm, v2, e, f, l_v2, 0); + l_f2 = bm_loop_create(bm, v1, e, f2, l_v1, 0); - f1loop->prev = v2loop->prev; - f2loop->prev = v1loop->prev; - v2loop->prev->next = f1loop; - v1loop->prev->next = f2loop; + l_f1->prev = l_v2->prev; + l_f2->prev = l_v1->prev; + l_v2->prev->next = l_f1; + l_v1->prev->next = l_f2; - f1loop->next = v1loop; - f2loop->next = v2loop; - v1loop->prev = f1loop; - v2loop->prev = f2loop; + l_f1->next = l_v1; + l_f2->next = l_v2; + l_v1->prev = l_f1; + l_v2->prev = l_f2; #ifdef USE_BMESH_HOLES lst = f->loops.first; lst2 = f2->loops.first; - lst2->first = lst2->last = f2loop; - lst->first = lst->last = f1loop; + lst2->first = lst2->last = l_f2; + lst->first = lst->last = l_f1; #else /* find which of the faces the original first loop is in */ - l_iter = l_first = f1loop; + l_iter = l_first = l_f1; first_loop_f1 = 0; do { if (l_iter == f->l_first) @@ -1261,23 +1261,23 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, /* original first loop was in f1, find a suitable first loop for f2 * which is as similar as possible to f1. the order matters for tools * such as duplifaces. */ - if (f->l_first->prev == f1loop) - f2->l_first = f2loop->prev; - else if (f->l_first->next == f1loop) - f2->l_first = f2loop->next; + if (f->l_first->prev == l_f1) + f2->l_first = l_f2->prev; + else if (f->l_first->next == l_f1) + f2->l_first = l_f2->next; else - f2->l_first = f2loop; + f2->l_first = l_f2; } else { /* original first loop was in f2, further do same as above */ f2->l_first = f->l_first; - if (f->l_first->prev == f2loop) - f->l_first = f1loop->prev; - else if (f->l_first->next == f2loop) - f->l_first = f1loop->next; + if (f->l_first->prev == l_f2) + f->l_first = l_f1->prev; + else if (f->l_first->next == l_f2) + f->l_first = l_f1->next; else - f->l_first = f1loop; + f->l_first = l_f1; } #endif @@ -1293,8 +1293,8 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, } while ((l_iter = l_iter->next) != l_first); /* link up the new loops into the new edges radial */ - bmesh_radial_append(e, f1loop); - bmesh_radial_append(e, f2loop); + bmesh_radial_append(e, l_f1); + bmesh_radial_append(e, l_f2); f2->len = f2len; @@ -1306,7 +1306,7 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, f->len = f1len; - if (r_l) *r_l = f2loop; + if (r_l) *r_l = l_f2; #ifdef USE_BMESH_HOLES if (holes) { @@ -1349,77 +1349,77 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, */ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) { - BMLoop *nextl; - BMEdge *ne; - BMVert *nv, *ov; + BMLoop *l_next; + BMEdge *e_new; + BMVert *v_new, *v_old; int i, valence1 = 0, valence2 = 0; bool edok; BLI_assert(bmesh_vert_in_edge(e, tv) != false); - ov = bmesh_edge_other_vert_get(e, tv); + v_old = bmesh_edge_other_vert_get(e, tv); - valence1 = bmesh_disk_count(ov); + valence1 = bmesh_disk_count(v_old); valence2 = bmesh_disk_count(tv); - nv = BM_vert_create(bm, tv->co, tv, 0); - ne = BM_edge_create(bm, nv, tv, e, 0); + v_new = BM_vert_create(bm, tv->co, tv, 0); + e_new = BM_edge_create(bm, v_new, tv, e, 0); - bmesh_disk_edge_remove(ne, tv); - bmesh_disk_edge_remove(ne, nv); + bmesh_disk_edge_remove(e_new, tv); + bmesh_disk_edge_remove(e_new, v_new); /* remove e from tv's disk cycle */ bmesh_disk_edge_remove(e, tv); - /* swap out tv for nv in e */ - bmesh_edge_swapverts(e, tv, nv); + /* swap out tv for v_new in e */ + bmesh_edge_swapverts(e, tv, v_new); - /* add e to nv's disk cycle */ - bmesh_disk_edge_append(e, nv); + /* add e to v_new's disk cycle */ + bmesh_disk_edge_append(e, v_new); - /* add ne to nv's disk cycle */ - bmesh_disk_edge_append(ne, nv); + /* add e_new to v_new's disk cycle */ + bmesh_disk_edge_append(e_new, v_new); - /* add ne to tv's disk cycle */ - bmesh_disk_edge_append(ne, tv); + /* add e_new to tv's disk cycle */ + bmesh_disk_edge_append(e_new, tv); /* verify disk cycles */ - edok = bmesh_disk_validate(valence1, ov->e, ov); + edok = bmesh_disk_validate(valence1, v_old->e, v_old); BMESH_ASSERT(edok != false); edok = bmesh_disk_validate(valence2, tv->e, tv); BMESH_ASSERT(edok != false); - edok = bmesh_disk_validate(2, nv->e, nv); + edok = bmesh_disk_validate(2, v_new->e, v_new); BMESH_ASSERT(edok != false); /* Split the radial cycle if present */ - nextl = e->l; + l_next = e->l; e->l = NULL; - if (nextl) { - BMLoop *nl, *l; - int radlen = bmesh_radial_length(nextl); + if (l_next) { + BMLoop *l_new, *l; + int radlen = bmesh_radial_length(l_next); int first1 = 0, first2 = 0; /* Take the next loop. Remove it from radial. Split it. Append to appropriate radials */ - while (nextl) { - l = nextl; + while (l_next) { + l = l_next; l->f->len++; - nextl = nextl != nextl->radial_next ? nextl->radial_next : NULL; + l_next = l_next != l_next->radial_next ? l_next->radial_next : NULL; bmesh_radial_loop_remove(l, NULL); - nl = bm_loop_create(bm, NULL, NULL, l->f, l, 0); - nl->prev = l; - nl->next = (l->next); - nl->prev->next = nl; - nl->next->prev = nl; - nl->v = nv; + l_new = bm_loop_create(bm, NULL, NULL, l->f, l, 0); + l_new->prev = l; + l_new->next = (l->next); + l_new->prev->next = l_new; + l_new->next->prev = l_new; + l_new->v = v_new; /* assign the correct edge to the correct loop */ - if (bmesh_verts_in_edge(nl->v, nl->next->v, e)) { - nl->e = e; - l->e = ne; + if (bmesh_verts_in_edge(l_new->v, l_new->next->v, e)) { + l_new->e = e; + l->e = e_new; - /* append l into ne's rad cycle */ + /* append l into e_new's rad cycle */ if (!first1) { first1 = 1; l->radial_next = l->radial_prev = NULL; @@ -1430,14 +1430,14 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) l->radial_next = l->radial_prev = NULL; } - bmesh_radial_append(nl->e, nl); + bmesh_radial_append(l_new->e, l_new); bmesh_radial_append(l->e, l); } - else if (bmesh_verts_in_edge(nl->v, nl->next->v, ne)) { - nl->e = ne; + else if (bmesh_verts_in_edge(l_new->v, l_new->next->v, e_new)) { + l_new->e = e_new; l->e = e; - /* append l into ne's rad cycle */ + /* append l into e_new's rad cycle */ if (!first1) { first1 = 1; l->radial_next = l->radial_prev = NULL; @@ -1448,7 +1448,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) l->radial_next = l->radial_prev = NULL; } - bmesh_radial_append(nl->e, nl); + bmesh_radial_append(l_new->e, l_new); bmesh_radial_append(l->e, l); } @@ -1457,14 +1457,14 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) /* verify length of radial cycle */ edok = bmesh_radial_validate(radlen, e->l); BMESH_ASSERT(edok != false); - edok = bmesh_radial_validate(radlen, ne->l); + edok = bmesh_radial_validate(radlen, e_new->l); BMESH_ASSERT(edok != false); /* verify loop->v and loop->next->v pointers for e */ for (i = 0, l = e->l; i < radlen; i++, l = l->radial_next) { BMESH_ASSERT(l->e == e); //BMESH_ASSERT(l->radial_next == l); - BMESH_ASSERT(!(l->prev->e != ne && l->next->e != ne)); + BMESH_ASSERT(!(l->prev->e != e_new && l->next->e != e_new)); edok = bmesh_verts_in_edge(l->v, l->next->v, e); BMESH_ASSERT(edok != false); @@ -1477,12 +1477,12 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) BM_CHECK_ELEMENT(l->e); BM_CHECK_ELEMENT(l->f); } - /* verify loop->v and loop->next->v pointers for ne */ - for (i = 0, l = ne->l; i < radlen; i++, l = l->radial_next) { - BMESH_ASSERT(l->e == ne); + /* verify loop->v and loop->next->v pointers for e_new */ + for (i = 0, l = e_new->l; i < radlen; i++, l = l->radial_next) { + BMESH_ASSERT(l->e == e_new); // BMESH_ASSERT(l->radial_next == l); BMESH_ASSERT(!(l->prev->e != e && l->next->e != e)); - edok = bmesh_verts_in_edge(l->v, l->next->v, ne); + edok = bmesh_verts_in_edge(l->v, l->next->v, e_new); BMESH_ASSERT(edok != false); BMESH_ASSERT(l->v != l->next->v); BMESH_ASSERT(l->e != l->next->e); @@ -1494,20 +1494,20 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) } } - BM_CHECK_ELEMENT(ne); - BM_CHECK_ELEMENT(nv); - BM_CHECK_ELEMENT(ov); + BM_CHECK_ELEMENT(e_new); + BM_CHECK_ELEMENT(v_new); + BM_CHECK_ELEMENT(v_old); BM_CHECK_ELEMENT(e); BM_CHECK_ELEMENT(tv); - if (r_e) *r_e = ne; - return nv; + if (r_e) *r_e = e_new; + return v_new; } /** * \brief Join Edge Kill Vert (JEKV) * - * Takes an edge \a ke and pointer to one of its vertices \a kv + * Takes an edge \a e_kill and pointer to one of its vertices \a v_kill * and collapses the edge on that vertex. * * \par Examples: @@ -1535,25 +1535,25 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) * faces with just 2 edges. It is up to the caller to decide what to do with * these faces. */ -BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_double) +BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_edge_double) { - BMEdge *oe; - BMVert *ov, *tv; - BMLoop *killoop, *l; + BMEdge *e_old; + BMVert *v_old, *tv; + BMLoop *l_kill, *l; int len, radlen = 0, i, valence1, valence2; bool edok, halt = false; - if (bmesh_vert_in_edge(ke, kv) == 0) { + if (bmesh_vert_in_edge(e_kill, v_kill) == 0) { return NULL; } - len = bmesh_disk_count(kv); + len = bmesh_disk_count(v_kill); if (len == 2) { - oe = bmesh_disk_edge_next(ke, kv); - tv = bmesh_edge_other_vert_get(ke, kv); - ov = bmesh_edge_other_vert_get(oe, kv); - halt = bmesh_verts_in_edge(kv, tv, oe); /* check for double edges */ + e_old = bmesh_disk_edge_next(e_kill, v_kill); + tv = bmesh_edge_other_vert_get(e_kill, v_kill); + v_old = bmesh_edge_other_vert_get(e_old, v_kill); + halt = bmesh_verts_in_edge(v_kill, tv, e_old); /* check for double edges */ if (halt) { return NULL; @@ -1561,56 +1561,56 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub else { BMEdge *e_splice; - /* For verification later, count valence of ov and tv */ - valence1 = bmesh_disk_count(ov); + /* For verification later, count valence of v_old and tv */ + valence1 = bmesh_disk_count(v_old); valence2 = bmesh_disk_count(tv); if (check_edge_double) { - e_splice = BM_edge_exists(tv, ov); + e_splice = BM_edge_exists(tv, v_old); } - /* remove oe from kv's disk cycle */ - bmesh_disk_edge_remove(oe, kv); - /* relink oe->kv to be oe->tv */ - bmesh_edge_swapverts(oe, kv, tv); - /* append oe to tv's disk cycle */ - bmesh_disk_edge_append(oe, tv); - /* remove ke from tv's disk cycle */ - bmesh_disk_edge_remove(ke, tv); - - /* deal with radial cycle of ke */ - radlen = bmesh_radial_length(ke->l); - if (ke->l) { - /* first step, fix the neighboring loops of all loops in ke's radial cycle */ - for (i = 0, killoop = ke->l; i < radlen; i++, killoop = killoop->radial_next) { + /* remove e_old from v_kill's disk cycle */ + bmesh_disk_edge_remove(e_old, v_kill); + /* relink e_old->v_kill to be e_old->tv */ + bmesh_edge_swapverts(e_old, v_kill, tv); + /* append e_old to tv's disk cycle */ + bmesh_disk_edge_append(e_old, tv); + /* remove e_kill from tv's disk cycle */ + bmesh_disk_edge_remove(e_kill, tv); + + /* deal with radial cycle of e_kill */ + radlen = bmesh_radial_length(e_kill->l); + if (e_kill->l) { + /* first step, fix the neighboring loops of all loops in e_kill's radial cycle */ + for (i = 0, l_kill = e_kill->l; i < radlen; i++, l_kill = l_kill->radial_next) { /* relink loops and fix vertex pointer */ - if (killoop->next->v == kv) { - killoop->next->v = tv; + if (l_kill->next->v == v_kill) { + l_kill->next->v = tv; } - killoop->next->prev = killoop->prev; - killoop->prev->next = killoop->next; - if (BM_FACE_FIRST_LOOP(killoop->f) == killoop) { - BM_FACE_FIRST_LOOP(killoop->f) = killoop->next; + 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; } - killoop->next = NULL; - killoop->prev = NULL; + l_kill->next = NULL; + l_kill->prev = NULL; /* fix len attribute of face */ - killoop->f->len--; + l_kill->f->len--; } - /* second step, remove all the hanging loops attached to ke */ - radlen = bmesh_radial_length(ke->l); + /* second step, remove all the hanging loops attached to e_kill */ + radlen = bmesh_radial_length(e_kill->l); if (LIKELY(radlen)) { BMLoop **loops = BLI_array_alloca(loops, radlen); - killoop = ke->l; + l_kill = e_kill->l; /* this should be wrapped into a bme_free_radial function to be used by bmesh_KF as well... */ for (i = 0; i < radlen; i++) { - loops[i] = killoop; - killoop = killoop->radial_next; + loops[i] = l_kill; + l_kill = l_kill->radial_next; } for (i = 0; i < radlen; i++) { bm->totloop--; @@ -1618,27 +1618,27 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub } } - /* Validate radial cycle of oe */ - edok = bmesh_radial_validate(radlen, oe->l); + /* Validate radial cycle of e_old */ + edok = bmesh_radial_validate(radlen, e_old->l); BMESH_ASSERT(edok != false); } /* deallocate edge */ - bm_kill_only_edge(bm, ke); + bm_kill_only_edge(bm, e_kill); /* deallocate vertex */ - bm_kill_only_vert(bm, kv); + bm_kill_only_vert(bm, v_kill); - /* Validate disk cycle lengths of ov, tv are unchanged */ - edok = bmesh_disk_validate(valence1, ov->e, ov); + /* Validate disk cycle lengths of v_old, tv are unchanged */ + edok = bmesh_disk_validate(valence1, v_old->e, v_old); BMESH_ASSERT(edok != false); edok = bmesh_disk_validate(valence2, tv->e, tv); BMESH_ASSERT(edok != false); - /* Validate loop cycle of all faces attached to 'oe' */ - for (i = 0, l = oe->l; i < radlen; i++, l = l->radial_next) { - BMESH_ASSERT(l->e == oe); - edok = bmesh_verts_in_edge(l->v, l->next->v, oe); + /* Validate loop cycle of all faces attached to 'e_old' */ + for (i = 0, l = e_old->l; i < radlen; i++, l = l->radial_next) { + BMESH_ASSERT(l->e == e_old); + edok = bmesh_verts_in_edge(l->v, l->next->v, e_old); BMESH_ASSERT(edok != false); edok = bmesh_loop_validate(l->f); BMESH_ASSERT(edok != false); @@ -1652,15 +1652,15 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub if (check_edge_double) { if (e_splice) { /* removes e_splice */ - BM_edge_splice(bm, e_splice, oe); + BM_edge_splice(bm, e_splice, e_old); } } - BM_CHECK_ELEMENT(ov); + BM_CHECK_ELEMENT(v_old); BM_CHECK_ELEMENT(tv); - BM_CHECK_ELEMENT(oe); + BM_CHECK_ELEMENT(e_old); - return oe; + return e_old; } } return NULL; @@ -1699,9 +1699,9 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_doub */ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) { - BMLoop *l_iter, *f1loop = NULL, *f2loop = NULL; - int newlen = 0, i, f1len = 0, f2len = 0, edok; - + BMLoop *l_iter, *l_f1 = NULL, *l_f2 = NULL; + int newlen = 0, i, f1len = 0, f2len = 0; + bool edok; /* can't join a face to itself */ if (f1 == f2) { return NULL; @@ -1716,23 +1716,23 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) f1len = f1->len; f2len = f2->len; - if (!((f1loop = BM_face_edge_share_loop(f1, e)) && - (f2loop = BM_face_edge_share_loop(f2, e)))) + if (!((l_f1 = BM_face_edge_share_loop(f1, e)) && + (l_f2 = BM_face_edge_share_loop(f2, e)))) { return NULL; } /* validate direction of f2's loop cycle is compatible */ - if (f1loop->v == f2loop->v) { + if (l_f1->v == l_f2->v) { return NULL; } /* validate that for each face, each vertex has another edge in its disk cycle that is * not e, and not shared. */ - if (bmesh_radial_face_find(f1loop->next->e, f2) || - bmesh_radial_face_find(f1loop->prev->e, f2) || - bmesh_radial_face_find(f2loop->next->e, f1) || - bmesh_radial_face_find(f2loop->prev->e, f1) ) + if (bmesh_radial_face_find(l_f1->next->e, f2) || + bmesh_radial_face_find(l_f1->prev->e, f2) || + bmesh_radial_face_find(l_f2->next->e, f1) || + bmesh_radial_face_find(l_f2->prev->e, f1) ) { return NULL; } @@ -1751,12 +1751,12 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) } for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) { - if (l_iter != f1loop) { + if (l_iter != l_f1) { BM_elem_flag_enable(l_iter->v, BM_ELEM_INTERNAL_TAG); } } for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) { - if (l_iter != f2loop) { + if (l_iter != l_f2) { /* as soon as a duplicate is found, bail out */ if (BM_elem_flag_test(l_iter->v, BM_ELEM_INTERNAL_TAG)) { return NULL; @@ -1765,15 +1765,15 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) } /* join the two loop */ - f1loop->prev->next = f2loop->next; - f2loop->next->prev = f1loop->prev; + l_f1->prev->next = l_f2->next; + l_f2->next->prev = l_f1->prev; - f1loop->next->prev = f2loop->prev; - f2loop->prev->next = f1loop->next; + l_f1->next->prev = l_f2->prev; + l_f2->prev->next = l_f1->next; - /* if f1loop was baseloop, make f1loop->next the base. */ - if (BM_FACE_FIRST_LOOP(f1) == f1loop) - BM_FACE_FIRST_LOOP(f1) = f1loop->next; + /* if l_f1 was baseloop, make l_f1->next the base. */ + if (BM_FACE_FIRST_LOOP(f1) == l_f1) + BM_FACE_FIRST_LOOP(f1) = l_f1->next; /* increase length of f1 */ f1->len += (f2->len - 2); @@ -1784,18 +1784,18 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) l_iter->f = f1; /* remove edge from the disk cycle of its two vertices */ - bmesh_disk_edge_remove(f1loop->e, f1loop->e->v1); - bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2); + bmesh_disk_edge_remove(l_f1->e, l_f1->e->v1); + bmesh_disk_edge_remove(l_f1->e, l_f1->e->v2); /* deallocate edge and its two loops as well as f2 */ if (bm->etoolflagpool) { - BLI_mempool_free(bm->etoolflagpool, f1loop->e->oflags); + BLI_mempool_free(bm->etoolflagpool, l_f1->e->oflags); } - BLI_mempool_free(bm->epool, f1loop->e); + BLI_mempool_free(bm->epool, l_f1->e); bm->totedge--; - BLI_mempool_free(bm->lpool, f1loop); + BLI_mempool_free(bm->lpool, l_f1); bm->totloop--; - BLI_mempool_free(bm->lpool, f2loop); + BLI_mempool_free(bm->lpool, l_f2); bm->totloop--; if (bm->ftoolflagpool) { BLI_mempool_free(bm->ftoolflagpool, f2->oflags); @@ -1889,7 +1889,7 @@ bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len BMLoop *l; BMEdge *e; int i, maxindex; - BMLoop *nl; + BMLoop *l_new; visithash = BLI_ghash_ptr_new(__func__); @@ -1908,9 +1908,9 @@ bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len BLI_ghash_insert(visithash, e, SET_INT_IN_POINTER(maxindex)); BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) { - nl = (l->v == v) ? l->prev : l->next; - if (!BLI_ghash_haskey(visithash, nl->e)) { - BLI_array_append(stack, nl->e); + l_new = (l->v == v) ? l->prev : l->next; + if (!BLI_ghash_haskey(visithash, l_new->e)) { + BLI_array_append(stack, l_new->e); } } } @@ -2072,7 +2072,7 @@ bool BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target) */ bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep) { - BMEdge *ne; + BMEdge *e_new; int radlen; BLI_assert(l_sep->e == e); @@ -2088,15 +2088,15 @@ bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep) e->l = l_sep->radial_next; } - ne = BM_edge_create(bm, e->v1, e->v2, e, 0); + e_new = BM_edge_create(bm, e->v1, e->v2, e, 0); bmesh_radial_loop_remove(l_sep, e); - bmesh_radial_append(ne, l_sep); - l_sep->e = ne; + bmesh_radial_append(e_new, l_sep); + l_sep->e = e_new; BLI_assert(bmesh_radial_length(e->l) == radlen - 1); - BLI_assert(bmesh_radial_length(ne->l) == 1); + BLI_assert(bmesh_radial_length(e_new->l) == 1); - BM_CHECK_ELEMENT(ne); + BM_CHECK_ELEMENT(e_new); BM_CHECK_ELEMENT(e); return true; @@ -2105,57 +2105,57 @@ bool bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep) /** * \brief Un-glue Region Make Vert (URMV) * - * Disconnects a face from its vertex fan at loop \a sl + * Disconnects a face from its vertex fan at loop \a l_sep * * \return The newly created BMVert */ -BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl) +BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep) { BMVert **vtar; int len, i; - BMVert *nv = NULL; - BMVert *sv = sl->v; + BMVert *v_new = NULL; + BMVert *v_sep = l_sep->v; /* peel the face from the edge radials on both sides of the * loop vert, disconnecting the face from its fan */ - bmesh_edge_separate(bm, sl->e, sl); - bmesh_edge_separate(bm, sl->prev->e, sl->prev); + bmesh_edge_separate(bm, l_sep->e, l_sep); + bmesh_edge_separate(bm, l_sep->prev->e, l_sep->prev); - if (bmesh_disk_count(sv) == 2) { - /* If there are still only two edges out of sv, then + if (bmesh_disk_count(v_sep) == 2) { + /* If there are still only two edges out of v_sep, then * this whole URMV was just a no-op, so exit now. */ - return sv; + return v_sep; } /* Update the disk start, so that v->e points to an edge * not touching the split loop. This is so that BM_vert_split - * will leave the original sv on some *other* fan (not the + * will leave the original v_sep on some *other* fan (not the * one-face fan that holds the unglue face). */ - while (sv->e == sl->e || sv->e == sl->prev->e) { - sv->e = bmesh_disk_edge_next(sv->e, sv); + while (v_sep->e == l_sep->e || v_sep->e == l_sep->prev->e) { + v_sep->e = bmesh_disk_edge_next(v_sep->e, v_sep); } /* Split all fans connected to the vert, duplicating it for * each fans. */ - bmesh_vert_separate(bm, sv, &vtar, &len); + bmesh_vert_separate(bm, v_sep, &vtar, &len); /* There should have been at least two fans cut apart here, * otherwise the early exit would have kicked in. */ BLI_assert(len >= 2); - nv = sl->v; + v_new = l_sep->v; /* Desired result here is that a new vert should always be * created for the unglue face. This is so we can glue any * extras back into the original vert. */ - BLI_assert(nv != sv); - BLI_assert(sv == vtar[0]); + BLI_assert(v_new != v_sep); + BLI_assert(v_sep == vtar[0]); /* If there are more than two verts as a result, glue together * all the verts except the one this URMV intended to create */ if (len > 2) { for (i = 0; i < len; i++) { - if (vtar[i] == nv) { + if (vtar[i] == v_new) { break; } } @@ -2174,18 +2174,18 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl) MEM_freeN(vtar); - return nv; + return v_new; } /** * \brief Unglue Region Make Vert (URMV) * - * Disconnects sf from the vertex fan at \a sv + * Disconnects f_sep from the vertex fan at \a v_sep * * \return The newly created BMVert */ -BMVert *bmesh_urmv(BMesh *bm, BMFace *sf, BMVert *sv) +BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep) { - BMLoop *l = BM_face_vert_share_loop(sf, sv); + BMLoop *l = BM_face_vert_share_loop(f_sep, v_sep); return bmesh_urmv_loop(bm, l); } diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index d8cfc973394..a1f378aaa5d 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -73,9 +73,9 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, ); BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e); -BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const bool check_edge_splice); +BMEdge *bmesh_jekv(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool check_edge_splice); BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e); -BMVert *bmesh_urmv(BMesh *bm, BMFace *sf, BMVert *sv); -BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl); +BMVert *bmesh_urmv(BMesh *bm, BMFace *f_sep, BMVert *v_sep); +BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *l_sep); #endif /* __BMESH_CORE_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c index 44b8baace4c..d0ab0ea5d60 100644 --- a/source/blender/bmesh/intern/bmesh_interp.c +++ b/source/blender/bmesh/intern/bmesh_interp.c @@ -126,7 +126,7 @@ void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BM { void *src[2]; float w[2]; - BMLoop *v1loop = NULL, *vloop = NULL, *v2loop = NULL; + BMLoop *l_v1 = NULL, *l_v = NULL, *l_v2 = NULL; BMLoop *l_iter = NULL; if (!e1->l) { @@ -139,23 +139,23 @@ void BM_data_interp_face_vert_edge(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BM l_iter = e1->l; do { if (l_iter->v == v1) { - v1loop = l_iter; - vloop = v1loop->next; - v2loop = vloop->next; + l_v1 = l_iter; + l_v = l_v1->next; + l_v2 = l_v->next; } else if (l_iter->v == v) { - v1loop = l_iter->next; - vloop = l_iter; - v2loop = l_iter->prev; + l_v1 = l_iter->next; + l_v = l_iter; + l_v2 = l_iter->prev; } - if (!v1loop || !v2loop) + if (!l_v1 || !l_v2) return; - src[0] = v1loop->head.data; - src[1] = v2loop->head.data; + src[0] = l_v1->head.data; + src[1] = l_v2->head.data; - CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, vloop->head.data); + CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_v->head.data); } while ((l_iter = l_iter->radial_next) != e1->l); } diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index 36a5412e401..c7be4424a21 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -20,11 +20,11 @@ #include "MEM_guardedalloc.h" +#include "BLI_utildefines.h" #include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_mempool.h" -#include "BLI_utildefines.h" #include "BKE_customdata.h" diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 3c4fa490477..b9352a25063 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -247,8 +247,6 @@ void BM_mesh_free(BMesh *bm) if (bm->py_handle) { /* keep this out of 'BM_mesh_data_free' because we want python * to be able to clear the mesh and maintain access. */ - extern void bpy_bm_generic_invalidate(void *self); - bpy_bm_generic_invalidate(bm->py_handle); bm->py_handle = NULL; } diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index 4c0c1507dbf..e0c8cb61900 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -782,7 +782,9 @@ void BM_mesh_bm_to_me(BMesh *bm, Mesh *me, bool do_tessface) hmd->indexar[j++] = BM_elem_index_get(eve); } } - else j++; + else { + j++; + } } hmd->totindex = j; diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index d98598cac89..afb3fc8112c 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -300,14 +300,14 @@ BMEdge *BM_verts_connect(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f) 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 *nl; + BMLoop *l_new; - f_iter = BM_face_split(bm, f_iter, v1, v2, &nl, NULL, false); + f_iter = BM_face_split(bm, f_iter, v1, v2, &l_new, NULL, false); if (r_f) { *r_f = f_iter; } - return nl->e; + return l_new->e; } } } @@ -339,51 +339,51 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l BMEdge *example, const bool no_double) { const bool has_mdisp = CustomData_has_layer(&bm->ldata, CD_MDISPS); - BMFace *nf, *of; + BMFace *f_new, *f_tmp; BLI_assert(v1 != v2); /* do we have a multires layer? */ if (has_mdisp) { - of = BM_face_copy(bm, f, false, false); + f_tmp = BM_face_copy(bm, f, false, false); } #ifdef USE_BMESH_HOLES - nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, no_double); + f_new = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, no_double); #else - nf = bmesh_sfme(bm, f, v1, v2, r_l, example, no_double); + f_new = bmesh_sfme(bm, f, v1, v2, r_l, example, no_double); #endif - if (nf) { - BM_elem_attrs_copy(bm, bm, f, nf); - copy_v3_v3(nf->no, f->no); + if (f_new) { + BM_elem_attrs_copy(bm, bm, f, f_new); + copy_v3_v3(f_new->no, f->no); /* handle multires update */ - if (has_mdisp && (nf != f)) { + if (has_mdisp && (f_new != f)) { BMLoop *l_iter; BMLoop *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(f); do { - BM_loop_interp_multires(bm, l_iter, of); + BM_loop_interp_multires(bm, l_iter, f_tmp); } while ((l_iter = l_iter->next) != l_first); - l_iter = l_first = BM_FACE_FIRST_LOOP(nf); + l_iter = l_first = BM_FACE_FIRST_LOOP(f_new); do { - BM_loop_interp_multires(bm, l_iter, of); + BM_loop_interp_multires(bm, l_iter, f_tmp); } while ((l_iter = l_iter->next) != l_first); - BM_face_kill(bm, of); + BM_face_kill(bm, f_tmp); #if 0 /* BM_face_multires_bounds_smooth doesn't flip displacement correct */ BM_face_multires_bounds_smooth(bm, f); - BM_face_multires_bounds_smooth(bm, nf); + BM_face_multires_bounds_smooth(bm, f_new); #endif } } - return nf; + return f_new; } /** @@ -406,62 +406,62 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **r_l BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[][3], int n, BMLoop **r_l, BMEdge *example) { - BMFace *nf, *of; + BMFace *f_new, *f_tmp; BMLoop *l_dummy; - BMEdge *e, *newe; - BMVert *newv; + BMEdge *e, *e_new; + BMVert *v_new; int i, j; BLI_assert(v1 != v2); - of = BM_face_copy(bm, f, true, true); + f_tmp = BM_face_copy(bm, f, true, true); if (!r_l) r_l = &l_dummy; #ifdef USE_BMESH_HOLES - nf = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, false); + f_new = bmesh_sfme(bm, f, v1, v2, r_l, NULL, example, false); #else - nf = bmesh_sfme(bm, f, v1, v2, r_l, example, false); + f_new = bmesh_sfme(bm, f, v1, v2, r_l, example, false); #endif - /* bmesh_sfme returns in r_l a Loop for nf going from v1 to v2. + /* 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 */ - if (nf) { - BM_elem_attrs_copy(bm, bm, f, nf); - copy_v3_v3(nf->no, f->no); + if (f_new) { + BM_elem_attrs_copy(bm, bm, f, f_new); + copy_v3_v3(f_new->no, f->no); e = (*r_l)->e; for (i = 0; i < n; i++) { - newv = bmesh_semv(bm, v2, e, &newe); - BLI_assert(newv != NULL); - /* bmesh_semv returns in newe the edge going from newv to tv */ - copy_v3_v3(newv->co, cos[i]); + v_new = bmesh_semv(bm, v2, 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]); - /* interpolate the loop data for the loops with (v == newv), using orig face */ + /* interpolate the loop data for the loops with (v == v_new), using orig face */ for (j = 0; j < 2; j++) { - BMEdge *e_iter = (j == 0) ? e : newe; + BMEdge *e_iter = (j == 0) ? e : e_new; BMLoop *l_iter = e_iter->l; do { - if (l_iter->v == newv) { + if (l_iter->v == v_new) { /* this interpolates both loop and vertex data */ - BM_loop_interp_from_face(bm, l_iter, of, true, true); + BM_loop_interp_from_face(bm, l_iter, f_tmp, true, true); } } while ((l_iter = l_iter->radial_next) != e_iter->l); } - e = newe; + e = e_new; } } - BM_face_verts_kill(bm, of); + BM_face_verts_kill(bm, f_tmp); - return nf; + return f_new; } /** * \brief Vert Collapse Faces * - * Collapses vertex \a kv that has only two manifold edges + * Collapses vertex \a v_kill that has only two manifold edges * onto a vertex it shares an edge with. * \a fac defines the amount of interpolation for Custom Data. * @@ -472,8 +472,8 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[ * Except this takes a factor and merges custom data. * * \param bm The bmesh - * \param ke The edge to collapse - * \param kv The vertex to collapse into the edge + * \param e_kill The edge to collapse + * \param v_kill The vertex to collapse into the edge * \param fac The factor along the edge * \param join_faces When true the faces around the vertex will be joined * otherwise collapse the vertex by merging the 2 edges this vert touches into one. @@ -481,11 +481,11 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, float cos[ * * \returns The New Edge */ -BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, +BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float fac, const bool join_faces, const bool kill_degenerate_faces) { - BMEdge *ne = NULL; - BMVert *tv = bmesh_edge_other_vert_get(ke, kv); + BMEdge *e_new = NULL; + BMVert *tv = bmesh_edge_other_vert_get(e_kill, v_kill); BMEdge *e2; BMVert *tv2; @@ -497,17 +497,17 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, float w[2]; /* Only intended to be called for 2-valence vertices */ - BLI_assert(bmesh_disk_count(kv) <= 2); + BLI_assert(bmesh_disk_count(v_kill) <= 2); /* first modify the face loop data */ w[0] = 1.0f - fac; w[1] = fac; - if (ke->l) { - l_iter = ke->l; + if (e_kill->l) { + l_iter = e_kill->l; do { - if (l_iter->v == tv && l_iter->next->v == kv) { + if (l_iter->v == tv && l_iter->next->v == v_kill) { tvloop = l_iter; kvloop = l_iter->next; @@ -515,30 +515,30 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, src[1] = tvloop->head.data; CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, kvloop->head.data); } - } while ((l_iter = l_iter->radial_next) != ke->l); + } while ((l_iter = l_iter->radial_next) != e_kill->l); } /* now interpolate the vertex data */ - BM_data_interp_from_verts(bm, kv, tv, kv, fac); + BM_data_interp_from_verts(bm, v_kill, tv, v_kill, fac); - e2 = bmesh_disk_edge_next(ke, kv); - tv2 = BM_edge_other_vert(e2, kv); + e2 = bmesh_disk_edge_next(e_kill, v_kill); + tv2 = BM_edge_other_vert(e2, v_kill); if (join_faces) { BMFace **faces = NULL; BMFace *f; BLI_array_staticdeclare(faces, 8); - BM_ITER_ELEM (f, &iter, kv, BM_FACES_OF_VERT) { + BM_ITER_ELEM (f, &iter, v_kill, BM_FACES_OF_VERT) { BLI_array_append(faces, f); } if (BLI_array_count(faces) >= 2) { BMFace *f2 = BM_faces_join(bm, faces, BLI_array_count(faces), true); if (f2) { - BMLoop *nl = NULL; - if (BM_face_split(bm, f2, tv, tv2, &nl, NULL, false)) { - ne = nl->e; + BMLoop *l_new = NULL; + if (BM_face_split(bm, f2, tv, tv2, &l_new, NULL, false)) { + e_new = l_new->e; } } } @@ -549,16 +549,16 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, /* single face or no faces */ /* same as BM_vert_collapse_edge() however we already * have vars to perform this operation so don't call. */ - ne = bmesh_jekv(bm, ke, kv, true); - /* ne = BM_edge_exists(tv, tv2); */ /* same as return above */ + e_new = bmesh_jekv(bm, e_kill, v_kill, true); + /* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */ - if (ne && kill_degenerate_faces) { + if (e_new && kill_degenerate_faces) { BLI_array_declare(bad_faces); BMFace **bad_faces = NULL; BMIter fiter; BMFace *f; - BMVert *verts[2] = {ne->v1, ne->v2}; + BMVert *verts[2] = {e_new->v1, e_new->v2}; int i; for (i = 0; i < 2; i++) { @@ -577,7 +577,7 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, } } - return ne; + return e_new; } @@ -588,37 +588,37 @@ BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, * * \return The New Edge */ -BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv, +BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool kill_degenerate_faces) { /* nice example implementation but we want loops to have their customdata * accounted for */ #if 0 - BMEdge *ne = NULL; + BMEdge *e_new = NULL; /* Collapse between 2 edges */ /* in this case we want to keep all faces and not join them, * rather just get rid of the vertex - see bug [#28645] */ - BMVert *tv = bmesh_edge_other_vert_get(ke, kv); + BMVert *tv = bmesh_edge_other_vert_get(e_kill, v_kill); if (tv) { - BMEdge *e2 = bmesh_disk_edge_next(ke, kv); + BMEdge *e2 = bmesh_disk_edge_next(e_kill, v_kill); if (e2) { - BMVert *tv2 = BM_edge_other_vert(e2, kv); + BMVert *tv2 = BM_edge_other_vert(e2, v_kill); if (tv2) { /* only action, other calls here only get the edge to return */ - ne = bmesh_jekv(bm, ke, kv); + e_new = bmesh_jekv(bm, e_kill, v_kill); - /* ne = BM_edge_exists(tv, tv2); */ /* same as return above */ + /* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */ } } } - return ne; + return e_new; #else /* with these args faces are never joined, same as above * but account for loop customdata */ - return BM_vert_collapse_faces(bm, ke, kv, 1.0f, false, kill_degenerate_faces); + return BM_vert_collapse_faces(bm, e_kill, v_kill, 1.0f, false, kill_degenerate_faces); #endif } @@ -637,7 +637,7 @@ BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv, */ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float percent) { - BMVert *nv, *v2; + BMVert *v_new, *v2; BMFace **oldfaces = NULL; BMEdge *e_dummy; BLI_array_staticdeclare(oldfaces, 32); @@ -668,21 +668,21 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce } v2 = bmesh_edge_other_vert_get(e, v); - nv = bmesh_semv(bm, v, e, r_e); + v_new = bmesh_semv(bm, v, e, r_e); - BLI_assert(nv != NULL); + BLI_assert(v_new != NULL); - sub_v3_v3v3(nv->co, v2->co, v->co); - madd_v3_v3v3fl(nv->co, v->co, nv->co, percent); + sub_v3_v3v3(v_new->co, v2->co, v->co); + madd_v3_v3v3fl(v_new->co, v->co, v_new->co, percent); if (r_e) { (*r_e)->head.hflag = e->head.hflag; BM_elem_attrs_copy(bm, bm, e, *r_e); } - /* v->nv->v2 */ - BM_data_interp_face_vert_edge(bm, v2, v, nv, e, percent); - BM_data_interp_from_verts(bm, v, v2, nv, percent); + /* v->v_new->v2 */ + BM_data_interp_face_vert_edge(bm, v2, v, v_new, e, percent); + BM_data_interp_from_verts(bm, v, v2, v_new, percent); if (do_mdisp) { int i, j; @@ -742,7 +742,7 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float perce BLI_array_free(oldfaces); } - return nv; + return v_new; } /** @@ -752,13 +752,13 @@ BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts) { int i; float percent; - BMVert *nv = NULL; + BMVert *v_new = NULL; for (i = 0; i < numcuts; i++) { percent = 1.0f / (float)(numcuts + 1 - i); - nv = BM_edge_split(bm, e, e->v2, NULL, percent); + v_new = BM_edge_split(bm, e, e->v2, NULL, percent); } - return nv; + return v_new; } #if 0 diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h index 358268cb589..93d6ca10edb 100644 --- a/source/blender/bmesh/intern/bmesh_mods.h +++ b/source/blender/bmesh/intern/bmesh_mods.h @@ -47,9 +47,9 @@ BMFace *BM_face_split_n(BMesh *bm, BMFace *f, float cos[][3], int n, BMLoop **r_l, BMEdge *example); -BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, +BMEdge *BM_vert_collapse_faces(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float fac, const bool join_faces, const bool kill_degenerate_faces); -BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *ke, BMVert *kv, +BMEdge *BM_vert_collapse_edge(BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool kill_degenerate_faces); diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index fd6571d136e..978aec0c610 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -451,7 +451,7 @@ typedef struct BMOIter { char restrictmask; /* bitwise '&' with BMHeader.htype */ } BMOIter; -void *BMO_slot_buffer_elem_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name); +void *BMO_slot_buffer_get_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name); void *BMO_iter_new(BMOIter *iter, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h index 053d70349e8..0e1d4fec4d3 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h +++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h @@ -120,13 +120,13 @@ BLI_INLINE void BMO_slot_map_empty_insert(BMOperator *op, BMOpSlot *slot, BMO_slot_map_insert(op, slot, element, NULL, 0); } -BLI_INLINE int BMO_slot_map_contains(BMOpSlot *slot, const void *element) +BLI_INLINE bool BMO_slot_map_contains(BMOpSlot *slot, const void *element) { BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING); /* sanity check */ if (UNLIKELY(slot->data.ghash == NULL)) { - return 0; + return false; } return BLI_ghash_haskey(slot->data.ghash, element); diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 00f8dbe06bf..f52dd7f2be9 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -1355,7 +1355,7 @@ static void bmo_flag_layer_clear(BMesh *bm) bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE); } -void *BMO_slot_buffer_elem_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name) +void *BMO_slot_buffer_get_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name) { BMOpSlot *slot = BMO_slot_get(slot_args, slot_name); @@ -1521,7 +1521,7 @@ static int bmo_name_to_slotcode(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char int i = 0; while (slot_args->slot_name) { - if (strncmp(identifier, slot_args->slot_name, MAX_SLOTNAME) == 0) { + if (STREQLEN(identifier, slot_args->slot_name, MAX_SLOTNAME)) { return i; } slot_args++; @@ -1546,7 +1546,7 @@ static int bmo_opname_to_opcode(const char *opname) int i; for (i = 0; i < bmo_opdefines_total; i++) { - if (!strcmp(opname, bmo_opdefines[i]->opname)) { + if (STREQ(opname, bmo_opdefines[i]->opname)) { return i; } } diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index ea9ad2ed151..1aa4383d761 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -30,9 +30,6 @@ struct BMesh; struct BMOperator; -void BMO_push(BMesh *bm, BMOperator *op); -void BMO_pop(BMesh *bm); - void bmo_automerge_exec(BMesh *bm, BMOperator *op); void bmo_average_vert_facedata_exec(BMesh *bm, BMOperator *op); void bmo_beautify_fill_exec(BMesh *bm, BMOperator *op); diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 9592c34fc75..4041fc2c755 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -35,12 +35,17 @@ * degenerate faces. */ -#include "BLI_math.h" -#include "BLI_array.h" +#include "DNA_listBase.h" #include "MEM_guardedalloc.h" +#include "BLI_math.h" +#include "BLI_array.h" +#include "BLI_scanfill.h" +#include "BLI_listbase.h" + #include "bmesh.h" + #include "intern/bmesh_private.h" /** @@ -151,6 +156,103 @@ static void bm_face_calc_poly_normal_vertex_cos(BMFace *f, float n[3], } /** + * For tools that insist on using triangles, ideally we would cache this data. + * + * \param r_loops Store face loop pointers, (f->len) + * \param r_index Store triangle triples, indicies into \a r_loops, ((f->len - 2) * 3) + */ +int BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*_r_index)[3]) +{ + int *r_index = (int *)_r_index; + BMLoop *l_first = BM_FACE_FIRST_LOOP(f); + BMLoop *l_iter; + int totfilltri; + + if (f->len == 3) { + *r_loops++ = (l_iter = l_first); + *r_loops++ = (l_iter = l_iter->next); + *r_loops++ = ( l_iter->next); + + r_index[0] = 0; + r_index[1] = 1; + r_index[2] = 2; + totfilltri = 1; + } + else if (f->len == 4) { + *r_loops++ = (l_iter = l_first); + *r_loops++ = (l_iter = l_iter->next); + *r_loops++ = (l_iter = l_iter->next); + *r_loops++ = ( l_iter->next); + + r_index[0] = 0; + r_index[1] = 1; + r_index[2] = 2; + + r_index[3] = 0; + r_index[4] = 2; + r_index[5] = 3; + totfilltri = 2; + } + else { + int j; + + ScanFillContext sf_ctx; + ScanFillVert *sf_vert, *sf_vert_last = NULL, *sf_vert_first = NULL; + /* ScanFillEdge *e; */ /* UNUSED */ + ScanFillFace *sf_tri; + + BLI_scanfill_begin(&sf_ctx); + + j = 0; + l_iter = l_first; + do { + sf_vert = BLI_scanfill_vert_add(&sf_ctx, l_iter->v->co); + sf_vert->tmp.p = l_iter; + + if (sf_vert_last) { + /* e = */ BLI_scanfill_edge_add(&sf_ctx, sf_vert_last, sf_vert); + } + + sf_vert_last = sf_vert; + if (sf_vert_first == NULL) { + sf_vert_first = sf_vert; + } + + r_loops[j] = l_iter; + + /* mark order */ + BM_elem_index_set(l_iter, j++); /* set_loop */ + + } while ((l_iter = l_iter->next) != l_first); + + /* complete the loop */ + BLI_scanfill_edge_add(&sf_ctx, sf_vert_first, sf_vert); + + totfilltri = BLI_scanfill_calc_ex(&sf_ctx, 0, f->no); + BLI_assert(totfilltri <= f->len - 2); + BLI_assert(totfilltri == BLI_countlist(&sf_ctx.fillfacebase)); + + for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { + int i1 = BM_elem_index_get((BMLoop *)sf_tri->v1->tmp.p); + int i2 = BM_elem_index_get((BMLoop *)sf_tri->v2->tmp.p); + int i3 = BM_elem_index_get((BMLoop *)sf_tri->v3->tmp.p); + + if (i1 > i2) { SWAP(int, i1, i2); } + if (i2 > i3) { SWAP(int, i2, i3); } + if (i1 > i2) { SWAP(int, i1, i2); } + + *r_index++ = i1; + *r_index++ = i2; + *r_index++ = i3; + } + + BLI_scanfill_end(&sf_ctx); + } + + return totfilltri; +} + +/** * get the area of the face */ float BM_face_calc_area(BMFace *f) diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index 601caae2337..c439a41f672 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -27,6 +27,12 @@ * \ingroup bmesh */ +int BM_face_calc_tessellation(BMFace *f, BMLoop **r_loops, int (*r_index)[3]) +#ifdef __GNUC__ + __attribute__((warn_unused_result)) + __attribute__((nonnull)) +#endif +; float BM_face_calc_area(BMFace *f); float BM_face_calc_perimeter(BMFace *f); void BM_face_calc_center_bounds(BMFace *f, float center[3]); diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 44dc483d5a7..26b0e42a1c1 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -680,7 +680,7 @@ bool BM_edge_is_wire(BMEdge *e) */ bool BM_vert_is_manifold(BMVert *v) { - BMEdge *e, *oe; + BMEdge *e, *e_old; BMLoop *l; int len, count, flag; @@ -691,7 +691,7 @@ bool BM_vert_is_manifold(BMVert *v) /* count edges while looking for non-manifold edges */ len = 0; - oe = e = v->e; + e_old = e = v->e; do { /* loose edge or edge shared by more than two faces, * edges with 1 face user are OK, otherwise we could @@ -700,14 +700,14 @@ bool BM_vert_is_manifold(BMVert *v) return false; } len++; - } while ((e = bmesh_disk_edge_next(e, v)) != oe); + } while ((e = bmesh_disk_edge_next(e, v)) != e_old); count = 1; flag = 1; e = NULL; - oe = v->e; - l = oe->l; - while (e != oe) { + e_old = v->e; + l = e_old->l; + while (e != e_old) { l = (l->v == v) ? l->prev : l->next; e = l->e; count++; /* count the edges */ @@ -716,13 +716,13 @@ bool BM_vert_is_manifold(BMVert *v) /* we've hit the edge of an open mesh, reset once */ flag = 0; count = 1; - oe = e; + e_old = e; e = NULL; - l = oe->l; + l = e_old->l; } else if (l->radial_next == l) { /* break the loop */ - e = oe; + e = e_old; } else { l = l->radial_next; @@ -769,9 +769,9 @@ int BM_edge_is_manifold(BMEdge *e) bool BM_edge_is_contiguous(BMEdge *e) { const BMLoop *l = e->l; - const BMLoop *l_other = l->radial_next; - return (l && (l_other != l) && /* not 0 or 1 face users */ - (l_other->radial_next == l) && /* 2 face users */ + const BMLoop *l_other; + return (l && ((l_other = l->radial_next) != l) && /* not 0 or 1 face users */ + (l_other->radial_next == l) && /* 2 face users */ (l_other->v != l->v)); } @@ -1352,6 +1352,8 @@ BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2) BMIter iter; BMEdge *e; + BLI_assert(v1 != v2); + BM_ITER_ELEM (e, &iter, v1, BM_EDGES_OF_VERT) { if (e->v1 == v2 || e->v2 == v2) return e; @@ -1652,3 +1654,38 @@ bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag) } while ((l_iter = l_iter->next) != l_first); return false; } + +static void bm_mesh_calc_volume_face(BMFace *f, float *r_vol) +{ + int tottri = f->len - 2; + BMLoop **loops = BLI_array_alloca(loops, f->len); + int (*index)[3] = BLI_array_alloca(index, tottri); + int j; + + tottri = BM_face_calc_tessellation(f, loops, index); + BLI_assert(tottri <= f->len - 2); + + for (j = 0; j < tottri; j++) { + const float *p1 = loops[index[j][0]]->v->co; + const float *p2 = loops[index[j][1]]->v->co; + const float *p3 = loops[index[j][2]]->v->co; + + /* co1.dot(co2.cross(co3)) / 6.0 */ + float cross[3]; + cross_v3_v3v3(cross, p2, p3); + *r_vol += (1.0f / 6.0f) * dot_v3v3(p1, cross); + } +} +float BM_mesh_calc_volume(BMesh *bm) +{ + /* warning, calls own tessellation function, may be slow */ + float vol = 0.0f; + BMFace *f; + BMIter fiter; + + BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { + bm_mesh_calc_volume_face(f, &vol); + } + + return fabsf(vol); +} diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 7cb5749a4bf..f894912aad3 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -110,4 +110,6 @@ bool BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag); bool BM_face_is_any_vert_flag_test(BMFace *f, const char hflag); bool BM_face_is_any_edge_flag_test(BMFace *f, const char hflag); +float BM_mesh_calc_volume(BMesh *bm); + #endif /* __BMESH_QUERIES_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index 2f568a498c5..0398f9c558f 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -63,15 +63,15 @@ BMVert *bmesh_edge_other_vert_get(BMEdge *e, BMVert *v) return NULL; } -bool bmesh_edge_swapverts(BMEdge *e, BMVert *orig, BMVert *newv) +bool bmesh_edge_swapverts(BMEdge *e, BMVert *v_orig, BMVert *v_new) { - if (e->v1 == orig) { - e->v1 = newv; + if (e->v1 == v_orig) { + e->v1 = v_new; e->v1_disk_link.next = e->v1_disk_link.prev = NULL; return true; } - else if (e->v2 == orig) { - e->v2 = newv; + else if (e->v2 == v_orig) { + e->v2 = v_new; e->v2_disk_link.next = e->v2_disk_link.prev = NULL; return true; } diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index ac6d4089372..a50b708961c 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -163,7 +163,7 @@ static void *bmw_ShellWalker_step(BMWalker *walker) static void *bmw_ShellWalker_step(BMWalker *walker) { BMEdge *curedge, *next = NULL; - BMVert *ov = NULL; + BMVert *v_old = NULL; bool restrictpass = true; BMwShellWalker shellWalk = *((BMwShellWalker *)BMW_current_state(walker)); @@ -183,7 +183,7 @@ static void *bmw_ShellWalker_step(BMWalker *walker) { BMwShellWalker *newstate; - ov = BM_edge_other_vert(curedge, shellWalk.base); + v_old = BM_edge_other_vert(curedge, shellWalk.base); /* push a new state onto the stac */ newState = BMW_state_add(walker); @@ -191,7 +191,7 @@ static void *bmw_ShellWalker_step(BMWalker *walker) /* populate the new stat */ - newState->base = ov; + newState->base = v_old; newState->curedge = curedge; } } diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 795531d6776..052ae9336ab 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -55,7 +55,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } } - BM_mesh_bevel(bm, offset, seg, vonly, false, NULL, -1); + BM_mesh_bevel(bm, offset, seg, vonly, false, false, NULL, -1); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); } diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index 9a17ebea38d..dc00d020083 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -44,10 +44,10 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op) { BMIter iter, liter; - BMFace *f, *nf; + BMFace *f, *f_new; BMLoop *(*loops_split)[2] = NULL; BLI_array_declare(loops_split); - BMLoop *l, *nl, *lastl = NULL; + BMLoop *l, *l_new; BMVert *(*verts_pair)[2] = NULL; BLI_array_declare(verts_pair); int i; @@ -56,7 +56,8 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op) /* BMESH_TODO, loop over vert faces: * faster then looping over all faces, then searching each for flagged verts*/ - for (f = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); f; f = BM_iter_step(&iter)) { + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BMLoop *l_last; BLI_array_empty(loops_split); BLI_array_empty(verts_pair); @@ -64,22 +65,21 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op) continue; } - l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f); - lastl = NULL; - for ( ; l; l = BM_iter_step(&liter)) { + l_last = NULL; + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { if (BMO_elem_flag_test(bm, l->v, VERT_INPUT)) { - if (!lastl) { - lastl = l; + if (!l_last) { + l_last = l; continue; } - if (lastl != l->prev && lastl != l->next) { + if (l_last != l->prev && l_last != l->next) { BLI_array_grow_one(loops_split); - loops_split[BLI_array_count(loops_split) - 1][0] = lastl; + loops_split[BLI_array_count(loops_split) - 1][0] = l_last; loops_split[BLI_array_count(loops_split) - 1][1] = l; } - lastl = l; + l_last = l; } } @@ -106,16 +106,16 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op) } for (i = 0; i < BLI_array_count(verts_pair); i++) { - nf = BM_face_split(bm, f, verts_pair[i][0], verts_pair[i][1], &nl, NULL, false); - f = nf; + f_new = BM_face_split(bm, f, verts_pair[i][0], verts_pair[i][1], &l_new, NULL, false); + f = f_new; - if (!nl || !nf) { + if (!l_new || !f_new) { BMO_error_raise(bm, op, BMERR_CONNECTVERT_FAILED, NULL); BLI_array_free(loops_split); return; } - BMO_elem_flag_enable(bm, nf, FACE_NEW); - BMO_elem_flag_enable(bm, nl->e, EDGE_OUT); + BMO_elem_flag_enable(bm, f_new, FACE_NEW); + BMO_elem_flag_enable(bm, l_new->e, EDGE_OUT); } } @@ -160,19 +160,19 @@ static int clamp_index(const int x, const int len) * isn't there should be... */ #define ARRAY_SWAP(elemtype, arr1, arr2) \ { \ - int i; \ + int i_; \ elemtype *arr_tmp = NULL; \ BLI_array_declare(arr_tmp); \ - for (i = 0; i < BLI_array_count(arr1); i++) { \ - BLI_array_append(arr_tmp, arr1[i]); \ + for (i_ = 0; i_ < BLI_array_count(arr1); i_++) { \ + BLI_array_append(arr_tmp, arr1[i_]); \ } \ BLI_array_empty(arr1); \ - for (i = 0; i < BLI_array_count(arr2); i++) { \ - BLI_array_append(arr1, arr2[i]); \ + for (i_ = 0; i_ < BLI_array_count(arr2); i_++) { \ + BLI_array_append(arr1, arr2[i_]); \ } \ BLI_array_empty(arr2); \ - for (i = 0; i < BLI_array_count(arr_tmp); i++) { \ - BLI_array_append(arr2, arr_tmp[i]); \ + for (i_ = 0; i_ < BLI_array_count(arr_tmp); i_++) { \ + BLI_array_append(arr2, arr_tmp[i_]); \ } \ BLI_array_free(arr_tmp); \ } (void)0 @@ -228,8 +228,8 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { if (!BMO_elem_flag_test(bm, e, EDGE_DONE)) { - BMVert *v, *ov; - /* BMEdge *e2, *e3, *oe = e; */ /* UNUSED */ + BMVert *v, *v_old; + /* BMEdge *e2, *e3, *e_old = e; */ /* UNUSED */ BMEdge *e2, *e3; if (c > 2) { @@ -265,7 +265,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) e2 = e; e = e2; - ov = v; + v_old = v; do { if (c == 0) { BLI_array_append(ee1, e2); @@ -301,7 +301,7 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) } /* test for connected loops, and set cl1 or cl2 if so */ - if (v == ov) { + if (v == v_old) { if (c == 0) { cl1 = 1; } diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index ae07c2cf0bc..9fab89f8e0a 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -26,12 +26,12 @@ #include "MEM_guardedalloc.h" -#include "BLI_heap.h" #include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_array.h" #include "BLI_smallhash.h" #include "BLI_rand.h" +#include "BLI_heap.h" #include "bmesh.h" @@ -810,9 +810,9 @@ static EPath *edge_find_shortest_path(BMesh *bm, BMOperator *op, BMEdge *edge, E } if (use_restrict) { - int *group = (int *)BMO_slot_map_data_get(slot_restrict, e); - if (group) { - if (!(*group & path->group)) { + int *group_flag = (int *)BMO_slot_map_data_get(slot_restrict, e); + if (group_flag) { + if (!(*group_flag & path->group)) { v2 = NULL; continue; } @@ -925,15 +925,12 @@ void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op) BMO_elem_flag_enable(bm, f, ELE_ORIG); } - i = 0; - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) { BM_elem_index_set(e, i); /* set_inline */ if (!BMO_elem_flag_test(bm, e, EDGE_MARK)) { edata[i].tag = 2; } - - i++; } bm->elem_index_dirty &= ~BM_EDGE; @@ -1491,6 +1488,7 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) if (use_smooth) { BM_elem_flag_enable(f, BM_ELEM_SMOOTH); } + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, ELE_OUT); } MEM_freeN(vert_arr); diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index 47b2497816f..a78a8ec5197 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -41,7 +41,7 @@ #define VERT_MARK 1 -static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh * bm, BMFace * f) +static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh *bm, BMFace *f) { BMWalker regwalker; BMIter liter2; @@ -75,11 +75,12 @@ static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh * bm, BMFace * f) void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) { BMOIter oiter; - BMFace *f, *f2 /* , *nf = NULL */; + BMFace *f; BLI_array_declare(faces); BLI_array_declare(regions); BMFace ***regions = NULL; BMFace **faces = NULL; + BMFace *act_face = bm->act_face; BMWalker regwalker; int i; @@ -100,7 +101,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) /* collect region */ BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) { - + BMFace *f_iter; if (!BMO_elem_flag_test(bm, f, FACE_MARK)) { continue; } @@ -113,15 +114,15 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) BMW_FLAG_NOP, /* no need to check BMW_FLAG_TEST_HIDDEN, faces are already marked by the bmo */ BMW_NIL_LAY); - for (f2 = BMW_begin(®walker, f); f2; f2 = BMW_step(®walker)) { - BLI_array_append(faces, f2); + for (f_iter = BMW_begin(®walker, f); f_iter; f_iter = BMW_step(®walker)) { + BLI_array_append(faces, f_iter); } BMW_end(®walker); for (i = 0; i < BLI_array_count(faces); i++) { - f2 = faces[i]; - BMO_elem_flag_disable(bm, f2, FACE_MARK); - BMO_elem_flag_enable(bm, f2, FACE_ORIG); + f_iter = faces[i]; + BMO_elem_flag_disable(bm, f_iter, FACE_MARK); + BMO_elem_flag_enable(bm, f_iter, FACE_ORIG); } if (BMO_error_occurred(bm)) { @@ -135,6 +136,7 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) } for (i = 0; i < BLI_array_count(regions); i++) { + BMFace *f_new; int tot = 0; faces = regions[i]; @@ -147,8 +149,15 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) while (faces[tot]) tot++; - f = BM_faces_join(bm, faces, tot, true); - if (!f) { + f_new = BM_faces_join(bm, faces, tot, true); + + if (f_new) { + /* maintain active face */ + if (act_face && bm->act_face == NULL) { + bm->act_face = f_new; + } + } + else { BMO_error_raise(bm, op, BMERR_DISSOLVEFACES_FAILED, "Could not create merged face"); goto cleanup; @@ -156,8 +165,8 @@ void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op) /* if making the new face failed (e.g. overlapping test) * unmark the original faces for deletion */ - BMO_elem_flag_disable(bm, f, FACE_ORIG); - BMO_elem_flag_enable(bm, f, FACE_NEW); + BMO_elem_flag_disable(bm, f_new, FACE_ORIG); + BMO_elem_flag_enable(bm, f_new, FACE_NEW); } @@ -196,23 +205,33 @@ cleanup: void bmo_dissolve_edgeloop_exec(BMesh *bm, BMOperator *op) { /* BMOperator fop; */ + BMFace *act_face = bm->act_face; BMOIter oiter; BMIter iter; BMVert *v, **verts = NULL; BLI_array_declare(verts); BMEdge *e; - BMFace *fa, *fb; int i; BMO_ITER (e, &oiter, op->slots_in, "edges", BM_EDGE) { + BMFace *fa, *fb; + if (BM_edge_face_pair(e, &fa, &fb)) { + BMFace *f_new; BMO_elem_flag_enable(bm, e->v1, VERT_MARK); BMO_elem_flag_enable(bm, e->v2, VERT_MARK); /* BMESH_TODO - check on delaying edge removal since we may end up removing more then * one edge, and later reference a removed edge */ - BM_faces_join_pair(bm, fa, fb, e, true); + f_new = BM_faces_join_pair(bm, fa, fb, e, true); + + if (f_new) { + /* maintain active face */ + if (act_face && bm->act_face == NULL) { + bm->act_face = f_new; + } + } } } @@ -245,9 +264,9 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op) /* might want to make this an option or mode - campbell */ /* BMOperator fop; */ + BMFace *act_face = bm->act_face; BMOIter eiter; BMEdge *e; - BMIter viter; BMVert *v; @@ -263,12 +282,20 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op) BMFace *fa, *fb; if (BM_edge_face_pair(e, &fa, &fb)) { + BMFace *f_new; /* join faces */ /* BMESH_TODO - check on delaying edge removal since we may end up removing more then * one edge, and later reference a removed edge */ - BM_faces_join_pair(bm, fa, fb, e, true); + f_new = BM_faces_join_pair(bm, fa, fb, e, true); + + if (f_new) { + /* maintain active face */ + if (act_face && bm->act_face == NULL) { + bm->act_face = f_new; + } + } } } @@ -285,34 +312,32 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op) static bool test_extra_verts(BMesh *bm, BMVert *v) { - BMIter iter, liter, iter2, iter3; - BMFace *f, *f2; + BMIter fiter, liter, eiter, fiter_sub; + BMFace *f; BMLoop *l; BMEdge *e; - bool found; /* test faces around verts for verts that would be wrongly killed * by dissolve faces. */ - f = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v); - for ( ; f; f = BM_iter_step(&iter)) { - l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f); - for ( ; l; l = BM_iter_step(&liter)) { + BM_ITER_ELEM(f, &fiter, v, BM_FACES_OF_VERT) { + BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) { if (!BMO_elem_flag_test(bm, l->v, VERT_MARK)) { /* if an edge around a vert is a boundary edge, * then dissolve faces won't destroy it. * also if it forms a boundary with one * of the face region */ - found = false; - e = BM_iter_new(&iter2, bm, BM_EDGES_OF_VERT, l->v); - for ( ; e; e = BM_iter_step(&iter2)) { + bool found = false; + BM_ITER_ELEM(e, &eiter, l->v, BM_EDGES_OF_VERT) { + BMFace *f_iter; if (BM_edge_is_boundary(e)) { found = true; } - f2 = BM_iter_new(&iter3, bm, BM_FACES_OF_EDGE, e); - for ( ; f2; f2 = BM_iter_step(&iter3)) { - if (!BMO_elem_flag_test(bm, f2, FACE_MARK)) { - found = true; - break; + else { + BM_ITER_ELEM(f_iter, &fiter_sub, e, BM_FACES_OF_EDGE) { + if (!BMO_elem_flag_test(bm, f_iter, FACE_MARK)) { + found = true; + break; + } } } if (found == true) { diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 4fde6150f05..62220510623 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -30,6 +30,7 @@ #include "BLI_math.h" #include "BLI_array.h" +#include "BLI_buffer.h" #include "BKE_customdata.h" @@ -271,7 +272,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) BMOIter siter; BMIter iter, fiter, viter; BMEdge *e, *e_new; - BMVert *v, *v2; + BMVert *v; BMFace *f; bool found, fwd, delorig = false; BMOpSlot *slot_facemap_out; @@ -441,7 +442,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) /* link isolated vert */ for (v = BMO_iter_new(&siter, dupeop.slots_out, "isovert_map.out", 0); v; v = BMO_iter_step(&siter)) { - v2 = *((void **)BMO_iter_map_value(&siter)); + BMVert *v2 = *((void **)BMO_iter_map_value(&siter)); BM_edge_create(bm, v, v2, v->e, BM_CREATE_NO_DOUBLE); } @@ -612,15 +613,18 @@ static void solidify_add_thickness(BMesh *bm, const float dist) float *vert_accum = vert_angles + bm->totvert; int i, index; + BLI_buffer_declare_static(float, face_angles_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); + BLI_buffer_declare_static(float *, verts_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); + BM_mesh_elem_index_ensure(bm, BM_VERT); BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { if (BMO_elem_flag_test(bm, f, FACE_MARK)) { /* array for passing verts to angle_poly_v3 */ - float *face_angles = BLI_array_alloca(face_angles, f->len); + float *face_angles = BLI_buffer_resize_data(&face_angles_buf, float, f->len); /* array for receiving angles from angle_poly_v3 */ - float **verts = BLI_array_alloca(verts, f->len); + float **verts = BLI_buffer_resize_data(&verts_buf, float *, f->len); BM_ITER_ELEM_INDEX (l, &loopIter, f, BM_LOOPS_OF_FACE, i) { verts[i] = l->v->co; @@ -639,6 +643,9 @@ static void solidify_add_thickness(BMesh *bm, const float dist) } } + BLI_buffer_free(&face_angles_buf); + BLI_buffer_free(&verts_buf); + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { index = BM_elem_index_get(v); if (vert_accum[index]) { /* zero if unselected */ diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c index 5e2404c9919..7dc2884c5ed 100644 --- a/source/blender/bmesh/operators/bmo_hull.c +++ b/source/blender/bmesh/operators/bmo_hull.c @@ -28,11 +28,11 @@ #include "MEM_guardedalloc.h" +#include "BLI_utildefines.h" #include "BLI_array.h" #include "BLI_ghash.h" #include "BLI_listbase.h" #include "BLI_math.h" -#include "BLI_utildefines.h" #include "Bullet-C-Api.h" diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index 7beac676868..8b65764fe1c 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -40,7 +40,7 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot { BMIter liter; BMLoop *l; - BMVert *v2, *doub; + BMVert *v2, *v_double; bool split = false; BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { @@ -51,15 +51,15 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot (v2 != l->prev->v) && (v2 != l->next->v)) { - doub = l->v; + v_double = l->v; split = true; break; } } - if (split && doub != v2) { - BMLoop *nl; - BMFace *f2 = BM_face_split(bm, f, doub, v2, &nl, NULL, false); + if (split && v_double != v2) { + BMLoop *l_new; + BMFace *f2 = BM_face_split(bm, f, v_double, v2, &l_new, NULL, false); remdoubles_splitface(f, bm, op, slot_targetmap); remdoubles_splitface(f2, bm, op, slot_targetmap); diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c index ba755a866de..6b91d5fded9 100644 --- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c +++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c @@ -29,10 +29,10 @@ #include "DNA_meshdata_types.h" #include "BLI_array.h" -#include "BLI_heap.h" #include "BLI_math.h" #include "BLI_math_geom.h" #include "BLI_smallhash.h" +#include "BLI_heap.h" #include "BKE_customdata.h" #include "BKE_mesh.h" @@ -69,7 +69,6 @@ struct BLaplacianSystem { }; typedef struct BLaplacianSystem LaplacianSystem; -static float compute_volume(BMesh *bm); static float cotan_weight(float *v1, float *v2, float *v3); static int vert_is_boundary(BMVert *v); static LaplacianSystem *init_laplacian_system(int a_numEdges, int a_numFaces, int a_numVerts); @@ -85,7 +84,6 @@ static void delete_void_pointer(void *data) { if (data) { MEM_freeN(data); - data = NULL; } } @@ -416,45 +414,6 @@ static int vert_is_boundary(BMVert *v) return 0; } -static float compute_volume(BMesh *bm) -{ - float vol = 0.0f; - float x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4; - int i; - BMFace *f; - BMIter fiter; - BMIter vi; - BMVert *vn; - BMVert *vf[4]; - - BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) { - BM_ITER_ELEM_INDEX (vn, &vi, f, BM_VERTS_OF_FACE, i) { - vf[i] = vn; - } - x1 = vf[0]->co[0]; - y1 = vf[0]->co[1]; - z1 = vf[0]->co[2]; - - x2 = vf[1]->co[0]; - y2 = vf[1]->co[1]; - z2 = vf[1]->co[2]; - - x3 = vf[2]->co[0]; - y3 = vf[2]->co[1]; - z3 = vf[2]->co[2]; - - vol += (1.0f / 6.0f) * (0.0f - x3 * y2 * z1 + x2 * y3 * z1 + x3 * y1 * z2 - x1 * y3 * z2 - x2 * y1 * z3 + x1 * y2 * z3); - - if (i == 4) { - x4 = vf[3]->co[0]; - y4 = vf[3]->co[1]; - z4 = vf[3]->co[2]; - vol += (1.0f / 6.0f) * (x1 * y3 * z4 - x1 * y4 * z3 - x3 * y1 * z4 + x3 * z1 * y4 + y1 * x4 * z3 - x4 * y3 * z1); - } - } - return fabs(vol); -} - static void volume_preservation(BMOperator *op, float vini, float vend, int usex, int usey, int usez) { float beta; @@ -510,7 +469,7 @@ static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez } if (preserve_volume) { - vini = compute_volume(sys->bm); + vini = BM_mesh_calc_volume(sys->bm); } BMO_ITER (v, &siter, sys->op->slots_in, "verts", BM_VERT) { m_vertex_id = BM_elem_index_get(v); @@ -527,7 +486,7 @@ static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez } } if (preserve_volume) { - vend = compute_volume(sys->bm); + vend = BM_mesh_calc_volume(sys->bm); volume_preservation(sys->op, vini, vend, usex, usey, usez); } diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 36ad8ef506b..88e903c1651 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -40,7 +40,47 @@ #include "intern/bmesh_operators_private.h" /* own include */ -#include "bmo_subdivide.h" /* own include */ +typedef struct SubDParams { + int numcuts; + float smooth; + float fractal; + float along_normal; + //int beauty; + bool use_smooth; + bool use_sphere; + bool use_fractal; + int seed; + int origkey; /* shapekey holding displaced vertex coordinates for current geometry */ + BMOperator *op; + BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */ + BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */ + float fractal_ofs[3]; +} SubDParams; + +typedef void (*subd_pattern_fill_fp)(BMesh *bm, BMFace *face, BMVert **verts, + const SubDParams *params); + +/* + * note: this is a pattern-based edge subdivider. + * it tries to match a pattern to edge selections on faces, + * then executes functions to cut them. + */ +typedef struct SubDPattern { + int seledges[20]; /* selected edges mask, for splitting */ + + /* verts starts at the first new vert cut, not the first vert in the face */ + subd_pattern_fill_fp connectexec; + int len; /* total number of verts, before any subdivision */ +} SubDPattern; + +/* generic subdivision rules: + * + * - two selected edges in a face should make a link + * between them. + * + * - one edge should do, what? make pretty topology, or just + * split the edge only? + */ /* flags for all elements share a common bitfield space */ #define SUBD_SPLIT 1 @@ -71,29 +111,29 @@ /* connects face with smallest len, which I think should always be correct for * edge subdivision */ -static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_nf) +static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f_new) { BMIter iter, iter2; BMVert *v; - BMLoop *nl; - BMFace *face, *curf = NULL; + BMLoop *l_new; + BMFace *f, *f_cur = NULL; /* this isn't the best thing in the world. it doesn't handle cases where there's * multiple faces yet. that might require a convexity test to figure out which * face is "best" and who knows what for non-manifold conditions. */ - for (face = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v1); face; face = BM_iter_step(&iter)) { - for (v = BM_iter_new(&iter2, bm, BM_VERTS_OF_FACE, face); v; v = BM_iter_step(&iter2)) { + for (f = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v1); f; f = BM_iter_step(&iter)) { + for (v = BM_iter_new(&iter2, bm, BM_VERTS_OF_FACE, f); v; v = BM_iter_step(&iter2)) { if (v == v2) { - if (!curf || face->len < curf->len) curf = face; + if (!f_cur || f->len < f_cur->len) f_cur = f; } } } - if (curf) { - face = BM_face_split(bm, curf, v1, v2, &nl, NULL, false); + if (f_cur) { + f = BM_face_split(bm, f_cur, v1, v2, &l_new, NULL, false); - if (r_nf) *r_nf = face; - return nl ? nl->e : NULL; + if (r_f_new) *r_f_new = f; + return l_new ? l_new->e : NULL; } return NULL; @@ -151,7 +191,7 @@ static void alter_co(BMesh *bm, BMVert *v, BMEdge *UNUSED(origed), const SubDPar mid_v3_v3v3(normal, vsta->no, vend->no); ortho_basis_v3v3_v3(base1, base2, normal); - add_v3_v3v3(co2, v->co, params->off); + add_v3_v3v3(co2, v->co, params->fractal_ofs); mul_v3_fl(co2, 10.0f); tvec[0] = fac * (BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 2) - 0.5f); @@ -242,31 +282,31 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge, static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, const SubDParams *params, BMVert *vsta, BMVert *vend) { - BMEdge *eed = edge, *newe, temp = *edge; - BMVert *v, ov1 = *edge->v1, ov2 = *edge->v2, *v1 = edge->v1, *v2 = edge->v2; + BMEdge *eed = edge, *e_new, e_tmp = *edge; + BMVert *v, v1_tmp = *edge->v1, v2_tmp = *edge->v2, *v1 = edge->v1, *v2 = edge->v2; int i, numcuts = params->numcuts; - temp.v1 = &ov1; - temp.v2 = &ov2; + e_tmp.v1 = &v1_tmp; + e_tmp.v2 = &v2_tmp; for (i = 0; i < numcuts; i++) { - v = subdivideedgenum(bm, eed, &temp, i, params->numcuts, params, &newe, vsta, vend); + v = subdivideedgenum(bm, eed, &e_tmp, i, params->numcuts, params, &e_new, vsta, vend); BMO_elem_flag_enable(bm, v, SUBD_SPLIT); BMO_elem_flag_enable(bm, eed, SUBD_SPLIT); - BMO_elem_flag_enable(bm, newe, SUBD_SPLIT); + BMO_elem_flag_enable(bm, e_new, SUBD_SPLIT); BMO_elem_flag_enable(bm, v, ELE_SPLIT); BMO_elem_flag_enable(bm, eed, ELE_SPLIT); - BMO_elem_flag_enable(bm, newe, SUBD_SPLIT); + BMO_elem_flag_enable(bm, e_new, SUBD_SPLIT); BM_CHECK_ELEMENT(v); if (v->e) BM_CHECK_ELEMENT(v->e); if (v->e && v->e->l) BM_CHECK_ELEMENT(v->e->l->f); } - alter_co(bm, v1, &temp, params, 0, &ov1, &ov2); - alter_co(bm, v2, &temp, params, 1.0, &ov1, &ov2); + alter_co(bm, v1, &e_tmp, params, 0, &v1_tmp, &v2_tmp); + alter_co(bm, v2, &e_tmp, params, 1.0, &v1_tmp, &v2_tmp); } /* note: the patterns are rotated as necessary to @@ -286,7 +326,7 @@ static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, const SubDParams *par static void quad_1edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params) { - BMFace *nf; + BMFace *f_new; int i, add, numcuts = params->numcuts; /* if it's odd, the middle face is a quad, otherwise it's a triangle */ @@ -296,16 +336,16 @@ static void quad_1edge_split(BMesh *bm, BMFace *UNUSED(face), if (i == numcuts / 2) { add -= 1; } - connect_smallest_face(bm, verts[i], verts[numcuts + add], &nf); + connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new); } } else { add = 2; for (i = 0; i < numcuts; i++) { - connect_smallest_face(bm, verts[i], verts[numcuts + add], &nf); + connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new); if (i == numcuts / 2) { add -= 1; - connect_smallest_face(bm, verts[i], verts[numcuts + add], &nf); + connect_smallest_face(bm, verts[i], verts[numcuts + add], &f_new); } } @@ -332,13 +372,13 @@ static const SubDPattern quad_1edge = { static void quad_2edge_split_path(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params) { - BMFace *nf; + BMFace *f_new; int i, numcuts = params->numcuts; for (i = 0; i < numcuts; i++) { - connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &nf); + connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &f_new); } - connect_smallest_face(bm, verts[numcuts * 2 + 3], verts[numcuts * 2 + 1], &nf); + connect_smallest_face(bm, verts[numcuts * 2 + 3], verts[numcuts * 2 + 1], &f_new); } static const SubDPattern quad_2edge_path = { @@ -360,27 +400,27 @@ static const SubDPattern quad_2edge_path = { static void quad_2edge_split_innervert(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params) { - BMFace *nf; - BMVert *v, *lastv; - BMEdge *e, *ne, olde; + BMFace *f_new; + BMVert *v, *v_last; + BMEdge *e, *e_new, e_tmp; int i, numcuts = params->numcuts; - lastv = verts[numcuts]; + v_last = verts[numcuts]; for (i = numcuts - 1; i >= 0; i--) { - e = connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &nf); + e = connect_smallest_face(bm, verts[i], verts[numcuts + (numcuts - i)], &f_new); - olde = *e; - v = bm_subdivide_edge_addvert(bm, e, &olde, params, 0.5f, 0.5f, &ne, e->v1, e->v2); + e_tmp = *e; + v = bm_subdivide_edge_addvert(bm, e, &e_tmp, params, 0.5f, 0.5f, &e_new, e->v1, e->v2); if (i != numcuts - 1) { - connect_smallest_face(bm, lastv, v, &nf); + connect_smallest_face(bm, v_last, v, &f_new); } - lastv = v; + v_last = v; } - connect_smallest_face(bm, lastv, verts[numcuts * 2 + 2], &nf); + connect_smallest_face(bm, v_last, verts[numcuts * 2 + 2], &f_new); } static const SubDPattern quad_2edge_innervert = { @@ -402,15 +442,15 @@ static const SubDPattern quad_2edge_innervert = { static void quad_2edge_split_fan(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params) { - BMFace *nf; + BMFace *f_new; /* BMVert *v; */ /* UNUSED */ - /* BMVert *lastv = verts[2]; */ /* UNUSED */ - /* BMEdge *e, *ne; */ /* UNUSED */ + /* BMVert *v_last = verts[2]; */ /* UNUSED */ + /* BMEdge *e, *e_new; */ /* UNUSED */ int i, numcuts = params->numcuts; for (i = 0; i < numcuts; i++) { - connect_smallest_face(bm, verts[i], verts[numcuts * 2 + 2], &nf); - connect_smallest_face(bm, verts[numcuts + (numcuts - i)], verts[numcuts * 2 + 2], &nf); + connect_smallest_face(bm, verts[i], verts[numcuts * 2 + 2], &f_new); + connect_smallest_face(bm, verts[numcuts + (numcuts - i)], verts[numcuts * 2 + 2], &f_new); } } @@ -435,21 +475,21 @@ static const SubDPattern quad_2edge_fan = { static void quad_3edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params) { - BMFace *nf; + BMFace *f_new; int i, add = 0, numcuts = params->numcuts; for (i = 0; i < numcuts; i++) { if (i == numcuts / 2) { if (numcuts % 2 != 0) { - connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &nf); + connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &f_new); } add = numcuts * 2 + 2; } - connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &nf); + connect_smallest_face(bm, verts[numcuts - i - 1 + add], verts[i + numcuts + 1], &f_new); } for (i = 0; i < numcuts / 2 + 1; i++) { - connect_smallest_face(bm, verts[i], verts[(numcuts - i) + numcuts * 2 + 1], &nf); + connect_smallest_face(bm, verts[i], verts[(numcuts - i) + numcuts * 2 + 1], &f_new); } } @@ -474,9 +514,9 @@ static const SubDPattern quad_3edge = { static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params) { - BMFace *nf; + BMFace *f_new; BMVert *v, *v1, *v2; - BMEdge *e, *ne, temp; + BMEdge *e, *e_new, e_tmp; BMVert **lines; int numcuts = params->numcuts; int i, j, a, b, s = numcuts + 2 /* , totv = numcuts * 4 + 4 */; @@ -501,25 +541,25 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts a = i; b = numcuts + 1 + numcuts + 1 + (numcuts - i - 1); - e = connect_smallest_face(bm, verts[a], verts[b], &nf); + e = connect_smallest_face(bm, verts[a], verts[b], &f_new); if (!e) continue; BMO_elem_flag_enable(bm, e, ELE_INNER); - BMO_elem_flag_enable(bm, nf, ELE_INNER); + BMO_elem_flag_enable(bm, f_new, ELE_INNER); v1 = lines[(i + 1) * s] = verts[a]; v2 = lines[(i + 1) * s + s - 1] = verts[b]; - temp = *e; + e_tmp = *e; for (a = 0; a < numcuts; a++) { - v = subdivideedgenum(bm, e, &temp, a, numcuts, params, &ne, + v = subdivideedgenum(bm, e, &e_tmp, a, numcuts, params, &e_new, v1, v2); BMESH_ASSERT(v != NULL); - BMO_elem_flag_enable(bm, ne, ELE_INNER); + BMO_elem_flag_enable(bm, e_new, ELE_INNER); lines[(i + 1) * s + a + 1] = v; } } @@ -528,12 +568,12 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts for (j = 1; j < numcuts + 1; j++) { a = i * s + j; b = (i - 1) * s + j; - e = connect_smallest_face(bm, lines[a], lines[b], &nf); + e = connect_smallest_face(bm, lines[a], lines[b], &f_new); if (!e) continue; BMO_elem_flag_enable(bm, e, ELE_INNER); - BMO_elem_flag_enable(bm, nf, ELE_INNER); + BMO_elem_flag_enable(bm, f_new, ELE_INNER); } } @@ -555,11 +595,11 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts static void tri_1edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params) { - BMFace *nf; + BMFace *f_new; int i, numcuts = params->numcuts; for (i = 0; i < numcuts; i++) { - connect_smallest_face(bm, verts[i], verts[numcuts + 1], &nf); + connect_smallest_face(bm, verts[i], verts[numcuts + 1], &f_new); } } @@ -584,9 +624,9 @@ static const SubDPattern tri_1edge = { static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, const SubDParams *params) { - BMFace *nf; - BMEdge *e, *ne, temp; - BMVert ***lines, *v, ov1, ov2; + BMFace *f_new; + BMEdge *e, *e_new, e_tmp; + BMVert ***lines, *v, v1_tmp, v2_tmp; void *stackarr[1]; int i, j, a, b, numcuts = params->numcuts; @@ -607,26 +647,26 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, lines[i + 1] = MEM_callocN(sizeof(void *) * (2 + i), "triangle vert table row"); a = numcuts * 2 + 2 + i; b = numcuts + numcuts - i; - e = connect_smallest_face(bm, verts[a], verts[b], &nf); + e = connect_smallest_face(bm, verts[a], verts[b], &f_new); if (!e) goto cleanup; BMO_elem_flag_enable(bm, e, ELE_INNER); - BMO_elem_flag_enable(bm, nf, ELE_INNER); + BMO_elem_flag_enable(bm, f_new, ELE_INNER); lines[i + 1][0] = verts[a]; lines[i + 1][i + 1] = verts[b]; - temp = *e; - ov1 = *verts[a]; - ov2 = *verts[b]; - temp.v1 = &ov1; - temp.v2 = &ov2; + e_tmp = *e; + v1_tmp = *verts[a]; + v2_tmp = *verts[b]; + e_tmp.v1 = &v1_tmp; + e_tmp.v2 = &v2_tmp; for (j = 0; j < i; j++) { - v = subdivideedgenum(bm, e, &temp, j, i, params, &ne, + v = subdivideedgenum(bm, e, &e_tmp, j, i, params, &e_new, verts[a], verts[b]); lines[i + 1][j + 1] = v; - BMO_elem_flag_enable(bm, ne, ELE_INNER); + BMO_elem_flag_enable(bm, e_new, ELE_INNER); } } @@ -644,15 +684,15 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, */ for (i = 1; i < numcuts + 1; i++) { for (j = 0; j < i; j++) { - e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &nf); + e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &f_new); BMO_elem_flag_enable(bm, e, ELE_INNER); - BMO_elem_flag_enable(bm, nf, ELE_INNER); + BMO_elem_flag_enable(bm, f_new, ELE_INNER); - e = connect_smallest_face(bm, lines[i][j + 1], lines[i + 1][j + 1], &nf); + e = connect_smallest_face(bm, lines[i][j + 1], lines[i + 1][j + 1], &f_new); BMO_elem_flag_enable(bm, e, ELE_INNER); - BMO_elem_flag_enable(bm, nf, ELE_INNER); + BMO_elem_flag_enable(bm, f_new, ELE_INNER); } } @@ -711,7 +751,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) BLI_array_declare(loops_split); BMLoop **loops = NULL; BLI_array_declare(loops); - BMLoop *nl, *l; + BMLoop *l_new, *l; BMFace *face; BLI_array_declare(verts); float smooth, fractal, along_normal; @@ -731,9 +771,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) use_grid_fill = BMO_slot_bool_get(op->slots_in, "use_grid_fill"); use_only_quads = BMO_slot_bool_get(op->slots_in, "use_only_quads"); use_sphere = BMO_slot_bool_get(op->slots_in, "use_sphere"); - - BLI_srandom(seed); - + patterns[1] = NULL; /* straight cut is patterns[1] == NULL */ switch (cornertype) { @@ -790,9 +828,14 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) params.use_fractal = (fractal != 0.0f); params.use_sphere = use_sphere; params.origkey = skey; - params.off[0] = (float)BLI_drand() * 200.0f; - params.off[1] = (float)BLI_drand() * 200.0f; - params.off[2] = (float)BLI_drand() * 200.0f; + + if (params.use_fractal) { + BLI_srandom(seed); + + params.fractal_ofs[0] = (float)BLI_drand() * 200.0f; + params.fractal_ofs[1] = (float)BLI_drand() * 200.0f; + params.fractal_ofs[2] = (float)BLI_drand() * 200.0f; + } BMO_slot_map_to_flag(bm, op->slots_in, "custom_patterns", BM_FACE, FACE_CUSTOMFILL); @@ -820,9 +863,9 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) matched = 0; totesel = 0; - BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, i) { - edges[i] = nl->e; - verts[i] = nl->v; + BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, i) { + edges[i] = l_new->e; + verts[i] = l_new->v; if (BMO_elem_flag_test(bm, edges[i], SUBD_SPLIT)) { if (!e1) e1 = edges[i]; @@ -1042,8 +1085,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) if (loops_split[j][0]) { BLI_assert(BM_edge_exists(loops_split[j][0]->v, loops_split[j][1]->v) == NULL); - /* BMFace *nf = */ /* UNUSED */ - BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &nl, NULL, false); + /* BMFace *f_new = */ /* UNUSED */ + BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &l_new, NULL, false); } } @@ -1054,8 +1097,8 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) } a = 0; - BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, j) { - if (nl->v == facedata[i].start) { + BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, j) { + if (l_new->v == facedata[i].start) { a = j + 1; break; } @@ -1063,9 +1106,9 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) BLI_array_grow_items(verts, face->len); - BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, j) { + BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, j) { b = (j - a + face->len) % face->len; - verts[b] = nl->v; + verts[b] = l_new->v; } BM_CHECK_ELEMENT(face); diff --git a/source/blender/bmesh/operators/bmo_subdivide.h b/source/blender/bmesh/operators/bmo_subdivide.h deleted file mode 100644 index 529075aab02..00000000000 --- a/source/blender/bmesh/operators/bmo_subdivide.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributor(s): Joseph Eagar. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/bmesh/operators/bmo_subdivide.h - * \ingroup bmesh - */ - -#ifndef __BMO_SUBDIVIDE_H__ -#define __BMO_SUBDIVIDE_H__ - -typedef struct SubDParams { - int numcuts; - float smooth; - float fractal; - float along_normal; - //int beauty; - short use_smooth; - short use_sphere; - short use_fractal; - int seed; - int origkey; /* shapekey holding displaced vertex coordinates for current geometry */ - BMOperator *op; - BMOpSlot *slot_edge_percents; /* BMO_slot_get(params->op->slots_in, "edge_percents"); */ - BMOpSlot *slot_custom_patterns; /* BMO_slot_get(params->op->slots_in, "custom_patterns"); */ - float off[3]; -} SubDParams; - -typedef void (*subd_pattern_fill_fp)(BMesh *bm, BMFace *face, BMVert **verts, - const SubDParams *params); - -/* - * note: this is a pattern-based edge subdivider. - * it tries to match a pattern to edge selections on faces, - * then executes functions to cut them. - */ -typedef struct SubDPattern { - int seledges[20]; /* selected edges mask, for splitting */ - - /* verts starts at the first new vert cut, not the first vert in the face */ - subd_pattern_fill_fp connectexec; - int len; /* total number of verts, before any subdivision */ -} SubDPattern; - -/* generic subdivision rules: - * - * - two selected edges in a face should make a link - * between them. - * - * - one edge should do, what? make pretty topology, or just - * split the edge only? - */ - -#endif /* __BMO_SUBDIVIDE_H__ */ diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c index 0d603faf3c4..00838533104 100644 --- a/source/blender/bmesh/operators/bmo_wireframe.c +++ b/source/blender/bmesh/operators/bmo_wireframe.c @@ -151,8 +151,6 @@ static bool bm_loop_is_radial_boundary(BMLoop *l_first) return true; } -extern float BM_vert_calc_mean_tagged_edge_length(BMVert *v); - void bmo_wireframe_exec(BMesh *bm, BMOperator *op) { const bool use_boundary = BMO_slot_bool_get(op->slots_in, "use_boundary"); diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 5adef16de14..f685b741176 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -375,8 +375,8 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, } } -/* Like offset_meet, but here f1 and f2 must not be NULL and give the - * planes in which to run the offset lines. +/* Like offset_meet, but with a mid edge between them that is used + * to calculate the planes in which to run the offset lines. * They may not meet exactly: the offsets for the edges may be different * or both the planes and the lines may be angled so that they can't meet. * In that case, pick a close point on emid, which should be the dividing @@ -384,16 +384,13 @@ static void offset_meet(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, BMFace *f, * TODO: should have a global 'offset consistency' prepass to adjust offset * widths so that all edges have the same offset at both ends. */ static void offset_in_two_planes(EdgeHalf *e1, EdgeHalf *e2, EdgeHalf *emid, - BMVert *v, BMFace *f1, BMFace *f2, float meetco[3]) + BMVert *v, float meetco[3]) { float dir1[3], dir2[3], dirmid[3], norm_perp1[3], norm_perp2[3], off1a[3], off1b[3], off2a[3], off2b[3], isect2[3], co[3], f1no[3], f2no[3]; int iret; - BLI_assert(f1 != NULL && f2 != NULL); - (void)f1, (void)f2; /* UNUSED */ - /* get direction vectors for two offset lines */ sub_v3_v3v3(dir1, v->co, BM_edge_other_vert(e1->e, v)->co); sub_v3_v3v3(dir2, BM_edge_other_vert(e2->e, v)->co, v->co); @@ -692,8 +689,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv) if (e->prev->prev->is_bev) { BLI_assert(e->prev->prev != e); /* see: edgecount 2, selcount 1 case */ /* find meet point between e->prev->prev and e and attach e->prev there */ - offset_in_two_planes(e->prev->prev, e, e->prev, bv->v, - e->prev->prev->fnext, e->fprev, co); + offset_in_two_planes(e->prev->prev, e, e->prev, bv->v, co); v = add_new_bound_vert(mem_arena, vm, co); v->efirst = e->prev->prev; v->elast = v->ebev = e; @@ -2056,6 +2052,51 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) } } +/* + * Calculate and return an offset that is the lesser of the current + * bp.offset and the maximum possible offset before geometry + * collisions happen. + * Currently this is a quick and dirty estimate of the max + * possible: half the minimum edge length of any vertex involved + * in a bevel. This is usually conservative. + * The correct calculation is quite complicated. + * TODO: implement this correctly. + */ +static float bevel_limit_offset(BMesh *bm, BevelParams *bp) +{ + BMVert *v; + BMEdge *e; + BMIter v_iter, e_iter; + float limited_offset, half_elen; + bool vbeveled; + + limited_offset = bp->offset; + BM_ITER_MESH(v, &v_iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_TAG)) { + if (bp->vertex_only) { + vbeveled = true; + } + else { + vbeveled = false; + BM_ITER_ELEM(e, &e_iter, v, BM_EDGES_OF_VERT) { + if (BM_elem_flag_test(BM_edge_other_vert(e, v), BM_ELEM_TAG)) { + vbeveled = true; + break; + } + } + } + if (vbeveled) { + BM_ITER_ELEM(e, &e_iter, v, BM_EDGES_OF_VERT) { + half_elen = 0.5f * BM_edge_calc_length(e); + if (half_elen < limited_offset) + limited_offset = half_elen; + } + } + } + } + return limited_offset; +} + /** * - Currently only bevels BM_ELEM_TAG'd verts and edges. * @@ -2063,10 +2104,13 @@ static void bevel_build_edge_polygons(BMesh *bm, BevelParams *bp, BMEdge *bme) * the caller needs to ensure this is cleared before calling * if its going to use this face tag. * + * - If limit_offset is set, adjusts offset down if necessary + * to avoid geometry collisions. + * * \warning all tagged edges _must_ be manifold. */ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, - const bool vertex_only, const bool use_weights, + const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group) { BMIter iter; @@ -2087,6 +2131,9 @@ void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, bp.mem_arena = BLI_memarena_new((1 << 16), __func__); BLI_memarena_use_calloc(bp.mem_arena); + if (limit_offset) + bp.offset = bevel_limit_offset(bm, &bp); + /* The analysis of the input vertices and execution additional constructions */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) { diff --git a/source/blender/bmesh/tools/bmesh_bevel.h b/source/blender/bmesh/tools/bmesh_bevel.h index f214125fa1c..bee26357aca 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.h +++ b/source/blender/bmesh/tools/bmesh_bevel.h @@ -30,7 +30,7 @@ struct MDeformVert; void BM_mesh_bevel(BMesh *bm, const float offset, const float segments, - const bool vertex_only, const bool use_weights, + const bool vertex_only, const bool use_weights, const bool limit_offset, const struct MDeformVert *dvert, const int vertex_group); #endif /* __BMESH_BEVEL_H__ */ diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c index 3a724769f2a..a5122b242be 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c +++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c @@ -114,14 +114,14 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool /* check twice because cumulative effect could dissolve over angle limit */ (BM_edge_calc_face_angle(e) < angle_limit)) { - BMFace *nf = BM_faces_join_pair(bm, e->l->f, - e->l->radial_next->f, - e, - false); /* join faces */ + BMFace *f_new = BM_faces_join_pair(bm, e->l->f, + e->l->radial_next->f, + e, + false); /* join faces */ /* there may be some errors, we don't mind, just move on */ - if (nf) { - BM_face_normal_update(nf); + if (f_new) { + BM_face_normal_update(f_new); } else { BMO_error_clear(bm); @@ -210,10 +210,10 @@ void BM_mesh_decimate_dissolve_ex(BMesh *bm, const float angle_limit, const bool /* check twice because cumulative effect could dissolve over angle limit */ bm_vert_edge_face_angle(v) < angle_limit) { - BMEdge *ne = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */ + BMEdge *e_new = BM_vert_collapse_edge(bm, v->e, v, true); /* join edges */ - if (ne && ne->l) { - BM_edge_normals_update(ne); + if (e_new && e_new->l) { + BM_edge_normals_update(e_new); } } } diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c index 7e9a5784552..c48e83686b5 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c +++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c @@ -181,7 +181,6 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool unsigned vert_seek_b_tot = 0; #endif - BMVert *v; BMIter iter; const unsigned int offset = 0; @@ -192,12 +191,14 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool /* if tag_only is set, we assume the caller knows what verts to tag * needed for the operator */ if (tag_only == false) { + BMVert *v; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { BM_elem_flag_enable(v, BM_ELEM_TAG); } } for (iter_step = 0; iter_step < iterations; iter_step++) { + BMVert *v; bool iter_done; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { @@ -223,7 +224,6 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool unsigned int i; #endif BMVert *v_first = NULL; - BMVert *v; /* we could avoid iterating from the start each time */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c index 1d3f973dbc0..3ae5c712f0a 100644 --- a/source/blender/bmesh/tools/bmesh_edgesplit.c +++ b/source/blender/bmesh/tools/bmesh_edgesplit.c @@ -48,7 +48,6 @@ static void bm_edgesplit_validate_seams(BMesh *bm) BMEdge *e; unsigned char *vtouch; - unsigned char *vt; BM_mesh_elem_index_ensure(bm, BM_VERT); @@ -65,6 +64,7 @@ static void bm_edgesplit_validate_seams(BMesh *bm) BM_elem_flag_disable(e, BM_ELEM_TAG); } else if (BM_edge_is_boundary(e)) { + unsigned char *vt; vt = &vtouch[BM_elem_index_get(e->v1)]; if (*vt < 2) (*vt)++; vt = &vtouch[BM_elem_index_get(e->v2)]; if (*vt < 2) (*vt)++; |