diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-09-15 04:15:24 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-09-15 04:15:24 +0400 |
commit | 41729976753523ee08a0afaf6a26b6caf3dee1d6 (patch) | |
tree | ba264fba22084f44eb50b952f375715f501acff9 /source/blender/bmesh | |
parent | a5f8298ea5d13d7707bc0cbf0722013276bab9d6 (diff) | |
parent | a425790065fedb2ae49f1b79770945d8528790d9 (diff) |
Merged changes in the trunk up to revision 50607.
Conflicts resolved:
source/blender/blenloader/intern/readfile.c
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r-- | source/blender/bmesh/bmesh.h | 5 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_core.c | 33 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_iterators.c | 34 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_iterators.h | 17 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_marking.c | 9 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_marking.h | 2 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_operators.c | 12 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 55 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_private.h | 20 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_queries.c | 50 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_structure.c | 26 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_connect.c | 59 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_extrude.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_inset.c | 3 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_subdivide.c | 140 | ||||
-rw-r--r-- | source/blender/bmesh/tools/BME_bevel.c | 1 |
16 files changed, 284 insertions, 184 deletions
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index ac002070484..955b1a729c5 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -196,6 +196,11 @@ * * There may be a better place for this section, but adding here for now. * + * \subsection bm_todo_api API + * + * - make crease and bevel weight optional, they come for free in meshes but are allocated layers + * in the bmesh data structure. + * * * \subsection bm_todo_tools Tools * diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index 94d94cbec3e..f03ce9b8543 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -86,8 +86,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example) /* exception: don't copy the original shapekey index */ keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX); - if(keyi) + if (keyi) { *keyi = ORIGINDEX_NONE; + } } BM_CHECK_ELEMENT(v); @@ -339,6 +340,8 @@ BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, return f; } +#ifndef NDEBUG + /** * Check the element is valid. * @@ -357,14 +360,16 @@ int bmesh_elem_check(void *element, const char htype) return 2; switch (htype) { - case BM_VERT: { + case BM_VERT: + { BMVert *v = element; if (v->e && v->e->head.htype != BM_EDGE) { err |= 4; } break; } - case BM_EDGE: { + case BM_EDGE: + { BMEdge *e = element; if (e->l && e->l->head.htype != BM_LOOP) err |= 8; @@ -383,7 +388,8 @@ int bmesh_elem_check(void *element, const char htype) err |= 128; break; } - case BM_LOOP: { + case BM_LOOP: + { BMLoop *l = element, *l2; int i; @@ -423,7 +429,8 @@ int bmesh_elem_check(void *element, const char htype) break; } - case BM_FACE: { + case BM_FACE: + { BMFace *f = element; BMLoop *l_iter; BMLoop *l_first; @@ -471,6 +478,8 @@ int bmesh_elem_check(void *element, const char htype) return err; } +#endif /* NDEBUG */ + /** * low level function, only frees the vert, * doesn't change or adjust surrounding geometry @@ -1483,6 +1492,7 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e) * and collapses the edge on that vertex. * * \par Examples: + * * <pre> * Before: OE KE * ------- ------- @@ -1792,18 +1802,21 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) { BMEdge *e; - BMLoop *l; - BMIter liter; + + BMLoop **loops; + int i, loops_tot; /* verts already spliced */ if (v == vtarget) { return FALSE; } - /* retarget all the loops of v to vtarget */ - BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { - l->v = vtarget; + /* we can't modify the vert while iterating so first allocate an array of loops */ + loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot); + for (i = 0; i < loops_tot; i++) { + loops[i]->v = vtarget; } + MEM_freeN(loops); /* move all the edges from v's disk to vtarget's disk */ while ((e = v->e)) { diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index 8103ae1ee11..726127fdcad 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -28,6 +28,8 @@ * See: bmesh_iterators_inlin.c too, some functions are here for speed reasons. */ +#include "MEM_guardedalloc.h" + #include "BLI_utildefines.h" #include "bmesh.h" @@ -105,6 +107,38 @@ int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, cons } /** + * \brief Iterator as Array + * + * Allocates a new array, has the advantage that you dont need to know the size ahead of time. + * + * Takes advantage of less common iterator usage to avoid counting twice, + * which you might end up doing when #BM_iter_as_array is used. + * + * Caller needs to free the array. + */ +void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len) +{ + BMIter iter; + + if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) { + BMElem *ele; + BMElem **array = MEM_mallocN(sizeof(ele) * iter.count, __func__); + int i = 0; + + *r_len = iter.count; /* set before iterating */ + + while ((ele = BM_iter_step(&iter))) { + array[i++] = ele; + } + return array; + } + else { + *r_len = 0; + return NULL; + } +} + +/** * \brief Elem Iter Flag Count * * Counts how many flagged / unflagged items are found in this element. diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index 1361a91a692..8d0eeca31ed 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -115,10 +115,19 @@ typedef struct BMIter { char itype; } BMIter; -void *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index); -int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len); -int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const short value); -int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const short value); +void *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +#endif +; +int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len); +void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len) +#ifdef __GNUC__ +__attribute__((warn_unused_result)) +#endif +; +int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const short value); +int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const short value); /* private for bmesh_iterators_inline.c */ void bmiter__vert_of_mesh_begin(struct BMIter *iter); diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 58ccfa79a02..c0439311104 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -527,9 +527,9 @@ void BM_active_face_set(BMesh *bm, BMFace *efa) bm->act_face = efa; } -BMFace *BM_active_face_get(BMesh *bm, int sloppy) +BMFace *BM_active_face_get(BMesh *bm, int sloppy, int selected) { - if (bm->act_face) { + if (bm->act_face && (!selected || BM_elem_flag_test(bm->act_face, BM_ELEM_SELECT))) { return bm->act_face; } else if (sloppy) { @@ -546,6 +546,9 @@ BMFace *BM_active_face_get(BMesh *bm, int sloppy) if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { f = NULL; } + else if (selected && !BM_elem_flag_test(f, BM_ELEM_SELECT)) { + f = NULL; + } else { break; } @@ -768,7 +771,7 @@ void BM_select_history_validate(BMesh *bm) int BM_select_history_active_get(BMesh *bm, BMEditSelection *ese) { BMEditSelection *ese_last = bm->selected.last; - BMFace *efa = BM_active_face_get(bm, FALSE); + BMFace *efa = BM_active_face_get(bm, FALSE, FALSE); ese->next = ese->prev = NULL; diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h index 9b73ed2c390..8d4397794d5 100644 --- a/source/blender/bmesh/intern/bmesh_marking.h +++ b/source/blender/bmesh/intern/bmesh_marking.h @@ -71,7 +71,7 @@ int BM_mesh_elem_hflag_count_disabled(BMesh *bm, const char htype, const char hf /* edit selection stuff */ void BM_active_face_set(BMesh *bm, BMFace *f); -BMFace *BM_active_face_get(BMesh *bm, int sloppy); +BMFace *BM_active_face_get(BMesh *bm, int sloppy, int selected); void BM_editselection_center(BMEditSelection *ese, float r_center[3]); void BM_editselection_normal(BMEditSelection *ese, float r_normal[3]); diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index 0f2dc7041fa..53b95c97c8b 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -1417,7 +1417,8 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v case '=': case '%': break; - case 'm': { + case 'm': + { int size, c; c = NEXT_CHAR(fmt); @@ -1431,12 +1432,14 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v state = 1; break; } - case 'v': { + case 'v': + { BMO_slot_vec_set(op, slot_name, va_arg(vlist, float *)); state = 1; break; } - case 'e': { + case 'e': + { BMHeader *ele = va_arg(vlist, void *); BMOpSlot *slot = BMO_slot_get(op, slot_name); @@ -1447,7 +1450,8 @@ int BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, v state = 1; break; } - case 's': { + case 's': + { BMOperator *op2 = va_arg(vlist, void *); const char *slot_name2 = va_arg(vlist, char *); diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 807570f0d86..eb2b7721bdc 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -285,7 +285,7 @@ void calc_poly_plane(float (*verts)[3], const int nverts) * the list that bridges a concave region of the face or intersects * any of the faces's edges. */ -static void shrink_edgef(float v1[3], float v2[3], const float fac) +static void scale_edge_v3f(float v1[3], float v2[3], const float fac) { float mid[3]; @@ -502,7 +502,7 @@ void BM_face_normal_flip(BMesh *bm, BMFace *f) /* detects if two line segments cross each other (intersects). * note, there could be more winding cases then there needs to be. */ -static int linecrossesf(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) +static int line_crosses_v2f(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) { #define GETMIN2_AXIS(a, b, ma, mb, axis) \ @@ -606,13 +606,13 @@ int BM_face_point_inside_test(BMFace *f, const float co[3]) do { float v1[2], v2[2]; - v1[0] = (l_iter->prev->v->co[ax] - cent[ax]) * onepluseps + cent[ax]; - v1[1] = (l_iter->prev->v->co[ay] - cent[ay]) * onepluseps + cent[ay]; + v1[0] = (l_iter->prev->v->co[ax] - cent[0]) * onepluseps + cent[0]; + v1[1] = (l_iter->prev->v->co[ay] - cent[1]) * onepluseps + cent[1]; - v2[0] = (l_iter->v->co[ax] - cent[ax]) * onepluseps + cent[ax]; - v2[1] = (l_iter->v->co[ay] - cent[ay]) * onepluseps + cent[ay]; + v2[0] = (l_iter->v->co[ax] - cent[0]) * onepluseps + cent[0]; + v2[1] = (l_iter->v->co[ay] - cent[1]) * onepluseps + cent[1]; - crosses += linecrossesf(v1, v2, co2, out) != 0; + crosses += line_crosses_v2f(v1, v2, co2, out) != 0; } while ((l_iter = l_iter->next) != l_first); return crosses % 2 != 0; @@ -959,7 +959,7 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) BMIter iter; BMLoop *l; float v1[3], v2[3], v3[3] /*, v4[3 */, no[3], mid[3], *p1, *p2, *p3, *p4; - float out[3] = {-234324.0f, -234324.0f, 0.0f}; + float out[3] = {-FLT_MAX, -FLT_MAX, 0.0f}; float (*projverts)[3]; float (*edgeverts)[3]; float fac1 = 1.0000001f, fac2 = 0.9f; //9999f; //0.999f; @@ -980,7 +980,7 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) copy_v3_v3(v1, loops[i][0]->v->co); copy_v3_v3(v2, loops[i][1]->v->co); - shrink_edgef(v1, v2, fac2); + scale_edge_v3f(v1, v2, fac2); copy_v3_v3(edgeverts[a], v1); a++; @@ -994,14 +994,16 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) { p1 = projverts[i]; - out[0] = maxf(out[0], p1[0]) + 0.01f; - out[1] = maxf(out[1], p1[1]) + 0.01f; - out[2] = 0.0f; - p1[2] = 0.0f; + out[0] = maxf(out[0], p1[0]); + out[1] = maxf(out[1], p1[1]); + /* out[2] = 0.0f; */ /* keep at zero */ - //copy_v3_v3(l->v->co, p1); + p1[2] = 0.0f; } + /* ensure we are well outside the face bounds (value is arbitrary) */ + add_v2_fl(out, 1.0f); + for (i = 0; i < len; i++) { edgeverts[i * 2][2] = 0.0f; edgeverts[i * 2 + 1][2] = 0.0f; @@ -1019,19 +1021,26 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) p1 = projverts[j]; p2 = projverts[(j + 1) % f->len]; +#if 0 copy_v3_v3(v1, p1); copy_v3_v3(v2, p2); - shrink_edgef(v1, v2, fac1); - - if (linecrossesf(p1, p2, mid, out)) clen++; + scale_edge_v3f(v1, v2, fac1); + if (line_crosses_v2f(v1, v2, mid, out)) { + clen++; + } +#else + if (line_crosses_v2f(p1, p2, mid, out)) { + clen++; + } +#endif } - + if (clen % 2 == 0) { loops[i][0] = NULL; } } - + /* do line crossing test */ for (i = 0; i < f->len; i++) { p1 = projverts[i]; @@ -1040,7 +1049,7 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) copy_v3_v3(v1, p1); copy_v3_v3(v2, p2); - shrink_edgef(v1, v2, fac1); + scale_edge_v3f(v1, v2, fac1); for (j = 0; j < len; j++) { if (!loops[j][0]) { @@ -1050,7 +1059,7 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) p3 = edgeverts[j * 2]; p4 = edgeverts[j * 2 + 1]; - if (linecrossesf(v1, v2, p3, p4)) { + if (line_crosses_v2f(v1, v2, p3, p4)) { loops[j][0] = NULL; } } @@ -1067,9 +1076,9 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) copy_v3_v3(v1, p1); copy_v3_v3(v2, p2); - shrink_edgef(v1, v2, fac1); + scale_edge_v3f(v1, v2, fac1); - if (linecrossesf(v1, v2, p3, p4)) { + if (line_crosses_v2f(v1, v2, p3, p4)) { loops[i][0] = NULL; } } diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h index 0827901f5c2..b3fe3676ab8 100644 --- a/source/blender/bmesh/intern/bmesh_private.h +++ b/source/blender/bmesh/intern/bmesh_private.h @@ -37,21 +37,21 @@ */ /* returns positive nonzero on error */ -int bmesh_elem_check(void *element, const char htype); -#define BM_CHECK_ELEMENT(el) \ +#ifdef NDEBUG + /* no error checking for release, + * it can take most of the CPU time when running some tools */ +# define BM_CHECK_ELEMENT(el) (void)(el) +#else +int bmesh_elem_check(void *element, const char htype); +# define BM_CHECK_ELEMENT(el) \ if (bmesh_elem_check(el, ((BMHeader *)el)->htype)) { \ printf("check_element failure, with code %i on line %i in file\n" \ " \"%s\"\n\n", \ - bmesh_elem_check(el, ((BMHeader *)el)->htype), \ + bmesh_elem_check(el, ((BMHeader *)el)->htype), \ __LINE__, __FILE__); \ - } - -#define BM_DISK_EDGE_LINK_GET(e, v) ( \ - ((v) == ((BMEdge *)(e))->v1) ? \ - &((e)->v1_disk_link) : \ - &((e)->v2_disk_link) \ - ) + } (void)0 +#endif int bmesh_radial_length(BMLoop *l); int bmesh_disk_count(BMVert *v); diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index a9f146e4962..d850eb34477 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -470,31 +470,12 @@ int BM_edge_face_count(BMEdge *e) } /** - * Returns the number of faces around this vert + * Returns the number of faces around this vert + * length matches #BM_LOOPS_OF_VERT iterator */ int BM_vert_face_count(BMVert *v) { - int count = 0; - BMLoop *l; - BMIter iter; - - BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) { - count++; - } - - return count; -#if 0 //this code isn't working - BMEdge *curedge = NULL; - - if (v->e) { - curedge = v->e; - do { - if (curedge->l) count += BM_edge_face_count(curedge); - curedge = bmesh_disk_edge_next(curedge, v); - } while (curedge != v->e); - } - return count; -#endif + return bmesh_disk_facevert_count(v); } /** @@ -503,22 +484,21 @@ int BM_vert_face_count(BMVert *v) */ int BM_vert_is_wire(BMVert *v) { - BMEdge *curedge; + if (v->e) { + BMEdge *e_first, *e_iter; - if (v->e == NULL) { + e_first = e_iter = v->e; + do { + if (e_iter->l) { + return FALSE; + } + } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first); + + return TRUE; + } + else { return FALSE; } - - curedge = v->e; - do { - if (curedge->l) { - return FALSE; - } - - curedge = bmesh_disk_edge_next(curedge, v); - } while (curedge != v->e); - - return TRUE; } /** diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c index 2ff9e707b59..b58e61a3066 100644 --- a/source/blender/bmesh/intern/bmesh_structure.c +++ b/source/blender/bmesh/intern/bmesh_structure.c @@ -153,10 +153,22 @@ int bmesh_edge_swapverts(BMEdge *e, BMVert *orig, BMVert *newv) * advantage is that no intrinsic properties of the data structures are dependent upon the * cycle order and all non-manifold conditions are represented trivially. */ + +BLI_INLINE BMDiskLink *bmesh_disk_edge_link_from_vert(BMEdge *e, BMVert *v) +{ + if (v == e->v1) { + return &e->v1_disk_link; + } + else { + BLI_assert(v == e->v2); + return &e->v2_disk_link; + } +} + int bmesh_disk_edge_append(BMEdge *e, BMVert *v) { if (!v->e) { - BMDiskLink *dl1 = BM_DISK_EDGE_LINK_GET(e, v); + BMDiskLink *dl1 = bmesh_disk_edge_link_from_vert(e, v); v->e = e; dl1->next = dl1->prev = e; @@ -164,9 +176,9 @@ int bmesh_disk_edge_append(BMEdge *e, BMVert *v) else { BMDiskLink *dl1, *dl2, *dl3; - dl1 = BM_DISK_EDGE_LINK_GET(e, v); - dl2 = BM_DISK_EDGE_LINK_GET(v->e, v); - dl3 = dl2->prev ? BM_DISK_EDGE_LINK_GET(dl2->prev, v) : NULL; + dl1 = bmesh_disk_edge_link_from_vert(e, v); + dl2 = bmesh_disk_edge_link_from_vert(v->e, v); + dl3 = dl2->prev ? bmesh_disk_edge_link_from_vert(dl2->prev, v) : NULL; dl1->next = v->e; dl1->prev = dl2->prev; @@ -183,14 +195,14 @@ void bmesh_disk_edge_remove(BMEdge *e, BMVert *v) { BMDiskLink *dl1, *dl2; - dl1 = BM_DISK_EDGE_LINK_GET(e, v); + dl1 = bmesh_disk_edge_link_from_vert(e, v); if (dl1->prev) { - dl2 = BM_DISK_EDGE_LINK_GET(dl1->prev, v); + dl2 = bmesh_disk_edge_link_from_vert(dl1->prev, v); dl2->next = dl1->next; } if (dl1->next) { - dl2 = BM_DISK_EDGE_LINK_GET(dl1->next, v); + dl2 = bmesh_disk_edge_link_from_vert(dl1->next, v); dl2->prev = dl1->prev; } diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index 6943dcb3e5d..1987294fc42 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -45,18 +45,18 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op) { BMIter iter, liter; BMFace *f, *nf; - BMLoop **loops = NULL, *lastl = NULL; - BLI_array_declare(loops); - BMLoop *l, *nl; - BMVert **verts = NULL; - BLI_array_declare(verts); + BMLoop *(*loops_split)[2] = NULL; + BLI_array_declare(loops_split); + BMLoop *l, *nl, *lastl = NULL; + BMVert *(*verts_pair)[2] = NULL; + BLI_array_declare(verts_pair); int i; BMO_slot_buffer_flag_enable(bm, op, "verts", BM_VERT, VERT_INPUT); for (f = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL); f; f = BM_iter_step(&iter)) { - BLI_array_empty(loops); - BLI_array_empty(verts); + BLI_array_empty(loops_split); + BLI_array_empty(verts_pair); if (BMO_elem_flag_test(bm, f, FACE_NEW)) { continue; @@ -72,50 +72,44 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op) } if (lastl != l->prev && lastl != l->next) { - BLI_array_grow_one(loops); - loops[BLI_array_count(loops) - 1] = lastl; - - BLI_array_grow_one(loops); - loops[BLI_array_count(loops) - 1] = l; + BLI_array_grow_one(loops_split); + loops_split[BLI_array_count(loops_split) - 1][0] = lastl; + loops_split[BLI_array_count(loops_split) - 1][1] = l; } lastl = l; } } - if (BLI_array_count(loops) == 0) { + if (BLI_array_count(loops_split) == 0) { continue; } - if (BLI_array_count(loops) > 2) { - BLI_array_grow_one(loops); - loops[BLI_array_count(loops) - 1] = loops[BLI_array_count(loops) - 2]; - - BLI_array_grow_one(loops); - loops[BLI_array_count(loops) - 1] = loops[0]; + if (BLI_array_count(loops_split) > 1) { + BLI_array_grow_one(loops_split); + loops_split[BLI_array_count(loops_split) - 1][0] = loops_split[BLI_array_count(loops_split) - 2][1]; + loops_split[BLI_array_count(loops_split) - 1][1] = loops_split[0][0]; } - BM_face_legal_splits(bm, f, (BMLoop *(*)[2])loops, BLI_array_count(loops) / 2); + BM_face_legal_splits(bm, f, loops_split, BLI_array_count(loops_split)); - for (i = 0; i < BLI_array_count(loops) / 2; i++) { - if (loops[i * 2] == NULL) { + for (i = 0; i < BLI_array_count(loops_split); i++) { + if (loops_split[i][0] == NULL) { continue; } - BLI_array_grow_one(verts); - verts[BLI_array_count(verts) - 1] = loops[i * 2]->v; - - BLI_array_grow_one(verts); - verts[BLI_array_count(verts) - 1] = loops[i * 2 + 1]->v; + BLI_array_grow_one(verts_pair); + verts_pair[BLI_array_count(verts_pair) - 1][0] = loops_split[i][0]->v; + verts_pair[BLI_array_count(verts_pair) - 1][1] = loops_split[i][1]->v; } - for (i = 0; i < BLI_array_count(verts) / 2; i++) { - nf = BM_face_split(bm, f, verts[i * 2], verts[i * 2 + 1], &nl, NULL, FALSE); + 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; if (!nl || !nf) { BMO_error_raise(bm, op, BMERR_CONNECTVERT_FAILED, NULL); - BLI_array_free(loops); + BLI_array_free(loops_split); return; } BMO_elem_flag_enable(bm, nf, FACE_NEW); @@ -125,8 +119,8 @@ void bmo_connect_verts_exec(BMesh *bm, BMOperator *op) BMO_slot_buffer_from_enabled_flag(bm, op, "edgeout", BM_EDGE, EDGE_OUT); - BLI_array_free(loops); - BLI_array_free(verts); + BLI_array_free(loops_split); + BLI_array_free(verts_pair); } static BMVert *get_outer_vert(BMesh *bm, BMEdge *e) @@ -345,7 +339,6 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) goto cleanup; } - j = 0; if (vv1[0] == vv1[lenv1 - 1]) { lenv1--; } diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 9ea8e631435..c8be7c9ce34 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -390,7 +390,7 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) if (!v1->e) BM_vert_kill(bm, v1); if (!v2->e) - BM_vert_kill(bm, v1); + BM_vert_kill(bm, v2); continue; } diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index 3aa6e6dbe49..132d7050b31 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -283,7 +283,8 @@ void bmo_inset_exec(BMesh *bm, BMOperator *op) * cross product between both face normals */ add_v3_v3v3(tvec, e_info_a->no, e_info_b->no); - if ((f_a == f_b) || compare_v3v3(f_a->no, f_b->no, 0.00001f)) { + /* epsilon increased to fix [#32329] */ + if ((f_a == f_b) || compare_v3v3(f_a->no, f_b->no, 0.001f)) { normalize_v3(tvec); } else { diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 2af764060fb..b239be1c83b 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -308,7 +308,7 @@ static void quad_1edge_split(BMesh *bm, BMFace *UNUSED(face), } } -static SubDPattern quad_1edge = { +static const SubDPattern quad_1edge = { {1, 0, 0, 0}, quad_1edge_split, 4, @@ -337,7 +337,7 @@ static void quad_2edge_split_path(BMesh *bm, BMFace *UNUSED(face), BMVert **vert connect_smallest_face(bm, verts[numcuts * 2 + 3], verts[numcuts * 2 + 1], &nf); } -static SubDPattern quad_2edge_path = { +static const SubDPattern quad_2edge_path = { {1, 1, 0, 0}, quad_2edge_split_path, 4, @@ -379,7 +379,7 @@ static void quad_2edge_split_innervert(BMesh *bm, BMFace *UNUSED(face), BMVert * connect_smallest_face(bm, lastv, verts[numcuts * 2 + 2], &nf); } -static SubDPattern quad_2edge_innervert = { +static const SubDPattern quad_2edge_innervert = { {1, 1, 0, 0}, quad_2edge_split_innervert, 4, @@ -410,7 +410,7 @@ static void quad_2edge_split_fan(BMesh *bm, BMFace *UNUSED(face), BMVert **verts } } -static SubDPattern quad_2edge_fan = { +static const SubDPattern quad_2edge_fan = { {1, 1, 0, 0}, quad_2edge_split_fan, 4, @@ -449,7 +449,7 @@ static void quad_3edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, } } -static SubDPattern quad_3edge = { +static const SubDPattern quad_3edge = { {1, 1, 1, 0}, quad_3edge_split, 4, @@ -559,7 +559,7 @@ static void tri_1edge_split(BMesh *bm, BMFace *UNUSED(face), BMVert **verts, } } -static SubDPattern tri_1edge = { +static const SubDPattern tri_1edge = { {1, 0, 0}, tri_1edge_split, 3, @@ -660,51 +660,55 @@ cleanup: MEM_freeN(lines); } -static SubDPattern tri_3edge = { +static const SubDPattern tri_3edge = { {1, 1, 1}, tri_3edge_subdivide, 3, }; -static SubDPattern quad_4edge = { +static const SubDPattern quad_4edge = { {1, 1, 1, 1}, quad_4edge_subdivide, 4, }; -static SubDPattern *patterns[] = { - NULL, //quad single edge pattern is inserted here - NULL, //quad corner vert pattern is inserted here - NULL, //tri single edge pattern is inserted here +static const SubDPattern *patterns[] = { + NULL, /* quad single edge pattern is inserted here */ + NULL, /* quad corner vert pattern is inserted here */ + NULL, /* tri single edge pattern is inserted here */ NULL, &quad_3edge, NULL, }; -#define PLEN (sizeof(patterns) / sizeof(void *)) +#define PATTERNS_TOT (sizeof(patterns) / sizeof(void *)) typedef struct SubDFaceData { - BMVert *start; SubDPattern *pat; - int totedgesel; //only used if pat was NULL, e.g. no pattern was found + BMVert *start; + const SubDPattern *pat; + int totedgesel; /* only used if pat was NULL, e.g. no pattern was found */ BMFace *face; } SubDFaceData; void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) { BMOpSlot *einput; - SubDPattern *pat; + const SubDPattern *pat; SubDParams params; SubDFaceData *facedata = NULL; + BLI_array_declare(facedata); BMIter viter, fiter, liter; BMVert *v, **verts = NULL; - BMEdge *edge, **edges = NULL; - BMLoop *nl, *l, **splits = NULL, **loops = NULL; - BMFace *face; - BLI_array_declare(splits); - BLI_array_declare(loops); - BLI_array_declare(facedata); + BMEdge *edge; + BMEdge **edges = NULL; BLI_array_declare(edges); + BMLoop *(*loops_split)[2] = NULL; + BLI_array_declare(loops_split); + BMLoop **loops = NULL; + BLI_array_declare(loops); + BMLoop *nl, *l; + BMFace *face; BLI_array_declare(verts); float smooth, fractal, along_normal; int use_sphere, cornertype, use_singleedge, use_gridfill; @@ -726,7 +730,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) BLI_srandom(seed); patterns[1] = NULL; - //straight cut is patterns[1] == NULL + /* straight cut is patterns[1] == NULL */ switch (cornertype) { case SUBD_PATH: patterns[1] = &quad_2edge_path; @@ -861,7 +865,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) continue; } - for (i = 0; i < PLEN; i++) { + for (i = 0; i < PATTERNS_TOT; i++) { pat = patterns[i]; if (!pat) { continue; @@ -935,12 +939,12 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) /* ok, no pattern. we still may be able to do something */ BLI_array_empty(loops); - BLI_array_empty(splits); + BLI_array_empty(loops_split); /* for case of two edges, connecting them shouldn't be too hard */ - BM_ITER_ELEM (l, &liter, face, BM_LOOPS_OF_FACE) { - BLI_array_grow_one(loops); - loops[BLI_array_count(loops) - 1] = l; + BLI_array_grow_items(loops, face->len); + BM_ITER_ELEM_INDEX (l, &liter, face, BM_LOOPS_OF_FACE, a) { + loops[a] = l; } vlen = BLI_array_count(loops); @@ -971,23 +975,65 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) b += numcuts - 1; + BLI_array_grow_items(loops_split, numcuts); for (j = 0; j < numcuts; j++) { - BLI_array_grow_one(splits); - splits[BLI_array_count(splits) - 1] = loops[a]; - - BLI_array_grow_one(splits); - splits[BLI_array_count(splits) - 1] = loops[b]; + int ok = TRUE; + + /* Check for special case: [#32500] + * This edge pair could be used by more then one face, + * in this case it used to (2.63), split both faces along the same verts + * while it could be calculated which face should do the split, + * its ambigious, so in this case we're better off to skip them as exceptional cases + * and not try to be clever guessing which face to cut up. + * + * To avoid this case we need to check: + * Do the verts of each share a face besides the one we are subdividing, + * (but not connect to make an edge of that face). + */ + { + BMLoop *other_loop; + BMIter other_fiter; + BM_ITER_ELEM (other_loop, &other_fiter, loops[a]->v, BM_LOOPS_OF_VERT) { + if (other_loop->f != face) { + if (BM_vert_in_face(other_loop->f, loops[b]->v)) { + /* we assume that these verts are not making an edge in the face */ + BLI_assert(other_loop->prev->v != loops[a]->v); + BLI_assert(other_loop->next->v != loops[a]->v); + + ok = FALSE; + break; + } + } + } + } + + + if (ok == TRUE) { + loops_split[j][0] = loops[a]; + loops_split[j][1] = loops[b]; + } + else { + loops_split[j][0] = NULL; + loops_split[j][1] = NULL; + } b = (b - 1) % vlen; a = (a + 1) % vlen; } - //BM_face_legal_splits(bmesh, face, splits, BLI_array_count(splits) / 2); + /* Since these are newly created vertices, we don't need to worry about them being legal, + * ... though there are some cases we _should_ check for + * - concave corner of an ngon. + * - 2 edges being used in 2+ ngons. + */ +// BM_face_legal_splits(bm, face, loops_split, BLI_array_count(loops_split)); + + for (j = 0; j < BLI_array_count(loops_split); j++) { + if (loops_split[j][0]) { + BLI_assert(BM_edge_exists(loops_split[j][0]->v, loops_split[j][1]->v) == FALSE); - for (j = 0; j < BLI_array_count(splits) / 2; j++) { - if (splits[j * 2]) { /* BMFace *nf = */ /* UNUSED */ - BM_face_split(bm, face, splits[j * 2]->v, splits[j * 2 + 1]->v, &nl, NULL, FALSE); + BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &nl, NULL, FALSE); } } @@ -997,27 +1043,19 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) continue; } - j = a = 0; - for (nl = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, face); - nl; - nl = BM_iter_step(&liter)) - { + a = 0; + BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, j) { if (nl->v == facedata[i].start) { a = j + 1; break; } - j++; } - for (j = 0; j < face->len; j++) { - BLI_array_grow_one(verts); - } - - j = 0; - for (nl = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, face); nl; nl = BM_iter_step(&liter)) { + BLI_array_grow_items(verts, face->len); + + BM_ITER_ELEM_INDEX (nl, &liter, face, BM_LOOPS_OF_FACE, j) { b = (j - a + face->len) % face->len; verts[b] = nl->v; - j += 1; } BM_CHECK_ELEMENT(face); @@ -1035,7 +1073,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) if (facedata) BLI_array_free(facedata); if (edges) BLI_array_free(edges); if (verts) BLI_array_free(verts); - BLI_array_free(splits); + BLI_array_free(loops_split); BLI_array_free(loops); BMO_slot_buffer_from_enabled_flag(bm, op, "outinner", BM_ALL, ELE_INNER); diff --git a/source/blender/bmesh/tools/BME_bevel.c b/source/blender/bmesh/tools/BME_bevel.c index 85beb6d092b..91527313972 100644 --- a/source/blender/bmesh/tools/BME_bevel.c +++ b/source/blender/bmesh/tools/BME_bevel.c @@ -38,7 +38,6 @@ #include "BLI_ghash.h" #include "BLI_memarena.h" -#include "BKE_utildefines.h" #include "BKE_tessmesh.h" #include "BKE_bmesh.h" |