Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-09-15 04:15:24 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2012-09-15 04:15:24 +0400
commit41729976753523ee08a0afaf6a26b6caf3dee1d6 (patch)
treeba264fba22084f44eb50b952f375715f501acff9 /source/blender/bmesh
parenta5f8298ea5d13d7707bc0cbf0722013276bab9d6 (diff)
parenta425790065fedb2ae49f1b79770945d8528790d9 (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.h5
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c33
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c34
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.h17
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c9
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c12
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c55
-rw-r--r--source/blender/bmesh/intern/bmesh_private.h20
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c50
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.c26
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c59
-rw-r--r--source/blender/bmesh/operators/bmo_extrude.c2
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c3
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c140
-rw-r--r--source/blender/bmesh/tools/BME_bevel.c1
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"