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:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/bmesh/intern
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/bmesh/intern')
-rw-r--r--source/blender/bmesh/intern/bmesh_callback_generic.c19
-rw-r--r--source/blender/bmesh/intern/bmesh_callback_generic.h10
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c1182
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.h60
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c4127
-rw-r--r--source/blender/bmesh/intern/bmesh_core.h159
-rw-r--r--source/blender/bmesh/intern/bmesh_delete.c535
-rw-r--r--source/blender/bmesh/intern/bmesh_delete.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.c1274
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.h83
-rw-r--r--source/blender/bmesh/intern/bmesh_error.h48
-rw-r--r--source/blender/bmesh/intern/bmesh_inline.h64
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c1823
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.h84
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c863
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.h246
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators_inline.h269
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c1331
-rw-r--r--source/blender/bmesh/intern/bmesh_log.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c2075
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.h101
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c4242
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h125
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.c1962
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.h46
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_validate.c339
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c1504
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.h88
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c2644
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api.h639
-rw-r--r--source/blender/bmesh/intern/bmesh_operator_api_inline.h230
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c2788
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h171
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c2349
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h120
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.c2699
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.h28
-rw-r--r--source/blender/bmesh/intern/bmesh_private.h58
-rw-r--r--source/blender/bmesh/intern/bmesh_query.c3274
-rw-r--r--source/blender/bmesh/intern/bmesh_query.h295
-rw-r--r--source/blender/bmesh/intern/bmesh_query_inline.h105
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.c744
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.h77
-rw-r--r--source/blender/bmesh/intern/bmesh_structure_inline.h50
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers.c204
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers.h126
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_impl.c2286
-rw-r--r--source/blender/bmesh/intern/bmesh_walkers_private.h66
48 files changed, 21007 insertions, 20613 deletions
diff --git a/source/blender/bmesh/intern/bmesh_callback_generic.c b/source/blender/bmesh/intern/bmesh_callback_generic.c
index 07a23cd0471..27e808895cd 100644
--- a/source/blender/bmesh/intern/bmesh_callback_generic.c
+++ b/source/blender/bmesh/intern/bmesh_callback_generic.c
@@ -28,29 +28,28 @@
bool BM_elem_cb_check_hflag_ex(BMElem *ele, void *user_data)
{
- const uint hflag_pair = POINTER_AS_INT(user_data);
- const char hflag_p = (hflag_pair & 0xff);
- const char hflag_n = (hflag_pair >> 8);
+ const uint hflag_pair = POINTER_AS_INT(user_data);
+ const char hflag_p = (hflag_pair & 0xff);
+ const char hflag_n = (hflag_pair >> 8);
- return ((BM_elem_flag_test(ele, hflag_p) != 0) &&
- (BM_elem_flag_test(ele, hflag_n) == 0));
+ return ((BM_elem_flag_test(ele, hflag_p) != 0) && (BM_elem_flag_test(ele, hflag_n) == 0));
}
bool BM_elem_cb_check_hflag_enabled(BMElem *ele, void *user_data)
{
- const char hflag = POINTER_AS_INT(user_data);
+ const char hflag = POINTER_AS_INT(user_data);
- return (BM_elem_flag_test(ele, hflag) != 0);
+ return (BM_elem_flag_test(ele, hflag) != 0);
}
bool BM_elem_cb_check_hflag_disabled(BMElem *ele, void *user_data)
{
- const char hflag = POINTER_AS_INT(user_data);
+ const char hflag = POINTER_AS_INT(user_data);
- return (BM_elem_flag_test(ele, hflag) == 0);
+ return (BM_elem_flag_test(ele, hflag) == 0);
}
bool BM_elem_cb_check_elem_not_equal(BMElem *ele, void *user_data)
{
- return (ele != user_data);
+ return (ele != user_data);
}
diff --git a/source/blender/bmesh/intern/bmesh_callback_generic.h b/source/blender/bmesh/intern/bmesh_callback_generic.h
index d17e7a68ac8..5191bd31873 100644
--- a/source/blender/bmesh/intern/bmesh_callback_generic.h
+++ b/source/blender/bmesh/intern/bmesh_callback_generic.h
@@ -27,15 +27,13 @@ bool BM_elem_cb_check_hflag_ex(BMElem *, void *user_data);
bool BM_elem_cb_check_elem_not_equal(BMElem *ele, void *user_data);
#define BM_elem_cb_check_hflag_ex_simple(type, hflag_p, hflag_n) \
- (bool (*)(type, void *))BM_elem_cb_check_hflag_ex, \
- POINTER_FROM_UINT(((hflag_p) | (hflag_n << 8)))
+ (bool (*)(type, void *)) BM_elem_cb_check_hflag_ex, \
+ POINTER_FROM_UINT(((hflag_p) | (hflag_n << 8)))
#define BM_elem_cb_check_hflag_enabled_simple(type, hflag_p) \
- (bool (*)(type, void *))BM_elem_cb_check_hflag_enabled, \
- POINTER_FROM_UINT((hflag_p))
+ (bool (*)(type, void *)) BM_elem_cb_check_hflag_enabled, POINTER_FROM_UINT((hflag_p))
#define BM_elem_cb_check_hflag_disabled_simple(type, hflag_n) \
- (bool (*)(type, void *))BM_elem_cb_check_hflag_disabled, \
- POINTER_FROM_UINT(hflag_n)
+ (bool (*)(type, void *)) BM_elem_cb_check_hflag_disabled, POINTER_FROM_UINT(hflag_n)
#endif /* __BMESH_CALLBACK_GENERIC_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index c24a5b21b6c..0528a550be4 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -38,7 +38,6 @@
#define SELECT 1
-
/**
* Fill in a vertex array from an edge array.
*
@@ -46,15 +45,15 @@
*/
bool BM_verts_from_edges(BMVert **vert_arr, BMEdge **edge_arr, const int len)
{
- int i, i_prev = len - 1;
- for (i = 0; i < len; i++) {
- vert_arr[i] = BM_edge_share_vert(edge_arr[i_prev], edge_arr[i]);
- if (vert_arr[i] == NULL) {
- return false;
- }
- i_prev = i;
- }
- return true;
+ int i, i_prev = len - 1;
+ for (i = 0; i < len; i++) {
+ vert_arr[i] = BM_edge_share_vert(edge_arr[i_prev], edge_arr[i]);
+ if (vert_arr[i] == NULL) {
+ return false;
+ }
+ i_prev = i;
+ }
+ return true;
}
/**
@@ -64,15 +63,15 @@ bool BM_verts_from_edges(BMVert **vert_arr, BMEdge **edge_arr, const int len)
*/
bool BM_edges_from_verts(BMEdge **edge_arr, BMVert **vert_arr, const int len)
{
- int i, i_prev = len - 1;
- for (i = 0; i < len; i++) {
- edge_arr[i_prev] = BM_edge_exists(vert_arr[i_prev], vert_arr[i]);
- if (edge_arr[i_prev] == NULL) {
- return false;
- }
- i_prev = i;
- }
- return true;
+ int i, i_prev = len - 1;
+ for (i = 0; i < len; i++) {
+ edge_arr[i_prev] = BM_edge_exists(vert_arr[i_prev], vert_arr[i]);
+ if (edge_arr[i_prev] == NULL) {
+ return false;
+ }
+ i_prev = i;
+ }
+ return true;
}
/**
@@ -81,17 +80,20 @@ bool BM_edges_from_verts(BMEdge **edge_arr, BMVert **vert_arr, const int len)
*/
void BM_edges_from_verts_ensure(BMesh *bm, BMEdge **edge_arr, BMVert **vert_arr, const int len)
{
- int i, i_prev = len - 1;
- for (i = 0; i < len; i++) {
- edge_arr[i_prev] = BM_edge_create(bm, vert_arr[i_prev], vert_arr[i], NULL, BM_CREATE_NO_DOUBLE);
- i_prev = i;
- }
+ int i, i_prev = len - 1;
+ for (i = 0; i < len; i++) {
+ edge_arr[i_prev] = BM_edge_create(
+ bm, vert_arr[i_prev], vert_arr[i], NULL, BM_CREATE_NO_DOUBLE);
+ i_prev = i;
+ }
}
/* prototypes */
-static void bm_loop_attrs_copy(
- BMesh *source_mesh, BMesh *target_mesh,
- const BMLoop *source_loop, BMLoop *target_loop, uint64_t cd_mask);
+static void bm_loop_attrs_copy(BMesh *source_mesh,
+ BMesh *target_mesh,
+ const BMLoop *source_loop,
+ BMLoop *target_loop,
+ uint64_t cd_mask);
/**
* \brief Make Quad/Triangle
@@ -107,13 +109,16 @@ static void bm_loop_attrs_copy(
* of the vertices in the vertex array.
*/
-BMFace *BM_face_create_quad_tri(
- BMesh *bm,
- BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
- const BMFace *f_example, const eBMCreateFlag create_flag)
+BMFace *BM_face_create_quad_tri(BMesh *bm,
+ BMVert *v1,
+ BMVert *v2,
+ BMVert *v3,
+ BMVert *v4,
+ const BMFace *f_example,
+ const eBMCreateFlag create_flag)
{
- BMVert *vtar[4] = {v1, v2, v3, v4};
- return BM_face_create_verts(bm, vtar, v4 ? 4 : 3, f_example, create_flag, true);
+ BMVert *vtar[4] = {v1, v2, v3, v4};
+ return BM_face_create_verts(bm, vtar, v4 ? 4 : 3, f_example, create_flag, true);
}
/**
@@ -125,55 +130,52 @@ BMFace *BM_face_create_quad_tri(
* this is done since the face may not be completely surrounded by faces,
* this way: a quad with 2 connected quads on either side will still get all 4 loops updated
*/
-void BM_face_copy_shared(
- BMesh *bm, BMFace *f,
- BMLoopFilterFunc filter_fn, void *user_data)
+void BM_face_copy_shared(BMesh *bm, BMFace *f, BMLoopFilterFunc filter_fn, void *user_data)
{
- BMLoop *l_first;
- BMLoop *l_iter;
+ BMLoop *l_first;
+ BMLoop *l_iter;
#ifdef DEBUG
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BLI_assert(BM_ELEM_API_FLAG_TEST(l_iter, _FLAG_OVERLAP) == 0);
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BLI_assert(BM_ELEM_API_FLAG_TEST(l_iter, _FLAG_OVERLAP) == 0);
+ } while ((l_iter = l_iter->next) != l_first);
#endif
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BMLoop *l_other = l_iter->radial_next;
-
- if (l_other && l_other != l_iter) {
- BMLoop *l_src[2];
- BMLoop *l_dst[2] = {l_iter, l_iter->next};
- uint j;
-
- if (l_other->v == l_iter->v) {
- l_src[0] = l_other;
- l_src[1] = l_other->next;
- }
- else {
- l_src[0] = l_other->next;
- l_src[1] = l_other;
- }
-
- for (j = 0; j < 2; j++) {
- BLI_assert(l_dst[j]->v == l_src[j]->v);
- if (BM_ELEM_API_FLAG_TEST(l_dst[j], _FLAG_OVERLAP) == 0) {
- if ((filter_fn == NULL) || filter_fn(l_src[j], user_data)) {
- bm_loop_attrs_copy(bm, bm, l_src[j], l_dst[j], 0x0);
- BM_ELEM_API_FLAG_ENABLE(l_dst[j], _FLAG_OVERLAP);
- }
- }
- }
- }
- } while ((l_iter = l_iter->next) != l_first);
-
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BM_ELEM_API_FLAG_DISABLE(l_iter, _FLAG_OVERLAP);
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BMLoop *l_other = l_iter->radial_next;
+
+ if (l_other && l_other != l_iter) {
+ BMLoop *l_src[2];
+ BMLoop *l_dst[2] = {l_iter, l_iter->next};
+ uint j;
+
+ if (l_other->v == l_iter->v) {
+ l_src[0] = l_other;
+ l_src[1] = l_other->next;
+ }
+ else {
+ l_src[0] = l_other->next;
+ l_src[1] = l_other;
+ }
+
+ for (j = 0; j < 2; j++) {
+ BLI_assert(l_dst[j]->v == l_src[j]->v);
+ if (BM_ELEM_API_FLAG_TEST(l_dst[j], _FLAG_OVERLAP) == 0) {
+ if ((filter_fn == NULL) || filter_fn(l_src[j], user_data)) {
+ bm_loop_attrs_copy(bm, bm, l_src[j], l_dst[j], 0x0);
+ BM_ELEM_API_FLAG_ENABLE(l_dst[j], _FLAG_OVERLAP);
+ }
+ }
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_ELEM_API_FLAG_DISABLE(l_iter, _FLAG_OVERLAP);
+ } while ((l_iter = l_iter->next) != l_first);
}
/**
@@ -183,80 +185,80 @@ void BM_face_copy_shared(
*
* All arrays must be \a len long.
*/
-static bool bm_edges_sort_winding(
- BMVert *v1, BMVert *v2,
- BMEdge **edges, const int len,
- BMEdge **edges_sort, BMVert **verts_sort)
+static bool bm_edges_sort_winding(BMVert *v1,
+ BMVert *v2,
+ BMEdge **edges,
+ const int len,
+ BMEdge **edges_sort,
+ BMVert **verts_sort)
{
- BMEdge *e_iter, *e_first;
- BMVert *v_iter;
- int i;
-
- /* all flags _must_ be cleared on exit! */
- for (i = 0; i < len; i++) {
- BM_ELEM_API_FLAG_ENABLE(edges[i], _FLAG_MF);
- BM_ELEM_API_FLAG_ENABLE(edges[i]->v1, _FLAG_MV);
- BM_ELEM_API_FLAG_ENABLE(edges[i]->v2, _FLAG_MV);
- }
-
- /* find first edge */
- i = 0;
- v_iter = v1;
- e_iter = e_first = v1->e;
- do {
- if (BM_ELEM_API_FLAG_TEST(e_iter, _FLAG_MF) &&
- (BM_edge_other_vert(e_iter, v_iter) == v2))
- {
- i = 1;
- break;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v_iter)) != e_first);
- if (i == 0) {
- goto error;
- }
-
- i = 0;
- do {
- /* entering loop will always succeed */
- if (BM_ELEM_API_FLAG_TEST(e_iter, _FLAG_MF)) {
- if (UNLIKELY(BM_ELEM_API_FLAG_TEST(v_iter, _FLAG_MV) == false)) {
- /* vert is in loop multiple times */
- goto error;
- }
-
- BM_ELEM_API_FLAG_DISABLE(e_iter, _FLAG_MF);
- edges_sort[i] = e_iter;
-
- BM_ELEM_API_FLAG_DISABLE(v_iter, _FLAG_MV);
- verts_sort[i] = v_iter;
-
- i += 1;
-
- /* walk onto the next vertex */
- v_iter = BM_edge_other_vert(e_iter, v_iter);
- if (i == len) {
- if (UNLIKELY(v_iter != verts_sort[0])) {
- goto error;
- }
- break;
- }
-
- e_first = e_iter;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v_iter)) != e_first);
-
- if (i == len) {
- return true;
- }
+ BMEdge *e_iter, *e_first;
+ BMVert *v_iter;
+ int i;
+
+ /* all flags _must_ be cleared on exit! */
+ for (i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_ENABLE(edges[i], _FLAG_MF);
+ BM_ELEM_API_FLAG_ENABLE(edges[i]->v1, _FLAG_MV);
+ BM_ELEM_API_FLAG_ENABLE(edges[i]->v2, _FLAG_MV);
+ }
+
+ /* find first edge */
+ i = 0;
+ v_iter = v1;
+ e_iter = e_first = v1->e;
+ do {
+ if (BM_ELEM_API_FLAG_TEST(e_iter, _FLAG_MF) && (BM_edge_other_vert(e_iter, v_iter) == v2)) {
+ i = 1;
+ break;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v_iter)) != e_first);
+ if (i == 0) {
+ goto error;
+ }
+
+ i = 0;
+ do {
+ /* entering loop will always succeed */
+ if (BM_ELEM_API_FLAG_TEST(e_iter, _FLAG_MF)) {
+ if (UNLIKELY(BM_ELEM_API_FLAG_TEST(v_iter, _FLAG_MV) == false)) {
+ /* vert is in loop multiple times */
+ goto error;
+ }
+
+ BM_ELEM_API_FLAG_DISABLE(e_iter, _FLAG_MF);
+ edges_sort[i] = e_iter;
+
+ BM_ELEM_API_FLAG_DISABLE(v_iter, _FLAG_MV);
+ verts_sort[i] = v_iter;
+
+ i += 1;
+
+ /* walk onto the next vertex */
+ v_iter = BM_edge_other_vert(e_iter, v_iter);
+ if (i == len) {
+ if (UNLIKELY(v_iter != verts_sort[0])) {
+ goto error;
+ }
+ break;
+ }
+
+ e_first = e_iter;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v_iter)) != e_first);
+
+ if (i == len) {
+ return true;
+ }
error:
- for (i = 0; i < len; i++) {
- BM_ELEM_API_FLAG_DISABLE(edges[i], _FLAG_MF);
- BM_ELEM_API_FLAG_DISABLE(edges[i]->v1, _FLAG_MV);
- BM_ELEM_API_FLAG_DISABLE(edges[i]->v2, _FLAG_MV);
- }
+ for (i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_DISABLE(edges[i], _FLAG_MF);
+ BM_ELEM_API_FLAG_DISABLE(edges[i]->v1, _FLAG_MV);
+ BM_ELEM_API_FLAG_DISABLE(edges[i]->v2, _FLAG_MV);
+ }
- return false;
+ return false;
}
/**
@@ -273,20 +275,24 @@ error:
* #BM_face_create should be considered over this function as it
* avoids some unnecessary work.
*/
-BMFace *BM_face_create_ngon(
- BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, const int len,
- const BMFace *f_example, const eBMCreateFlag create_flag)
+BMFace *BM_face_create_ngon(BMesh *bm,
+ BMVert *v1,
+ BMVert *v2,
+ BMEdge **edges,
+ const int len,
+ const BMFace *f_example,
+ const eBMCreateFlag create_flag)
{
- BMEdge **edges_sort = BLI_array_alloca(edges_sort, len);
- BMVert **verts_sort = BLI_array_alloca(verts_sort, len);
+ BMEdge **edges_sort = BLI_array_alloca(edges_sort, len);
+ BMVert **verts_sort = BLI_array_alloca(verts_sort, len);
- BLI_assert(len && v1 && v2 && edges && bm);
+ BLI_assert(len && v1 && v2 && edges && bm);
- if (bm_edges_sort_winding(v1, v2, edges, len, edges_sort, verts_sort)) {
- return BM_face_create(bm, verts_sort, edges_sort, len, f_example, create_flag);
- }
+ if (bm_edges_sort_winding(v1, v2, edges, len, edges_sort, verts_sort)) {
+ return BM_face_create(bm, verts_sort, edges_sort, len, f_example, create_flag);
+ }
- return NULL;
+ return NULL;
}
/**
@@ -297,70 +303,69 @@ BMFace *BM_face_create_ngon(
* - Optionally create edges between vertices.
* - Uses verts so no need to find edges (handy when you only have verts)
*/
-BMFace *BM_face_create_ngon_verts(
- BMesh *bm, BMVert **vert_arr, const int len,
- const BMFace *f_example, const eBMCreateFlag create_flag,
- const bool calc_winding, const bool create_edges)
+BMFace *BM_face_create_ngon_verts(BMesh *bm,
+ BMVert **vert_arr,
+ const int len,
+ const BMFace *f_example,
+ const eBMCreateFlag create_flag,
+ const bool calc_winding,
+ const bool create_edges)
{
- BMEdge **edge_arr = BLI_array_alloca(edge_arr, len);
- uint winding[2] = {0, 0};
- int i, i_prev = len - 1;
- BMVert *v_winding[2] = {vert_arr[i_prev], vert_arr[0]};
-
- BLI_assert(len > 2);
-
- for (i = 0; i < len; i++) {
- if (create_edges) {
- edge_arr[i] = BM_edge_create(bm, vert_arr[i_prev], vert_arr[i], NULL, BM_CREATE_NO_DOUBLE);
- }
- else {
- edge_arr[i] = BM_edge_exists(vert_arr[i_prev], vert_arr[i]);
- if (edge_arr[i] == NULL) {
- return NULL;
- }
- }
-
- if (calc_winding) {
- /* the edge may exist already and be attached to a face
- * in this case we can find the best winding to use for the new face */
- if (edge_arr[i]->l) {
- BMVert *test_v1, *test_v2;
- /* we want to use the reverse winding to the existing order */
- BM_edge_ordered_verts(edge_arr[i], &test_v2, &test_v1);
- winding[(vert_arr[i_prev] == test_v2)]++;
- BLI_assert(vert_arr[i_prev] == test_v2 || vert_arr[i_prev] == test_v1);
- }
- }
-
- i_prev = i;
- }
-
- /* --- */
-
- if (calc_winding) {
- if (winding[0] < winding[1]) {
- winding[0] = 1;
- winding[1] = 0;
- }
- else {
- winding[0] = 0;
- winding[1] = 1;
- }
- }
- else {
- winding[0] = 0;
- winding[1] = 1;
- }
-
- /* --- */
-
- /* create the face */
- return BM_face_create_ngon(
- bm,
- v_winding[winding[0]],
- v_winding[winding[1]],
- edge_arr, len,
- f_example, create_flag);
+ BMEdge **edge_arr = BLI_array_alloca(edge_arr, len);
+ uint winding[2] = {0, 0};
+ int i, i_prev = len - 1;
+ BMVert *v_winding[2] = {vert_arr[i_prev], vert_arr[0]};
+
+ BLI_assert(len > 2);
+
+ for (i = 0; i < len; i++) {
+ if (create_edges) {
+ edge_arr[i] = BM_edge_create(bm, vert_arr[i_prev], vert_arr[i], NULL, BM_CREATE_NO_DOUBLE);
+ }
+ else {
+ edge_arr[i] = BM_edge_exists(vert_arr[i_prev], vert_arr[i]);
+ if (edge_arr[i] == NULL) {
+ return NULL;
+ }
+ }
+
+ if (calc_winding) {
+ /* the edge may exist already and be attached to a face
+ * in this case we can find the best winding to use for the new face */
+ if (edge_arr[i]->l) {
+ BMVert *test_v1, *test_v2;
+ /* we want to use the reverse winding to the existing order */
+ BM_edge_ordered_verts(edge_arr[i], &test_v2, &test_v1);
+ winding[(vert_arr[i_prev] == test_v2)]++;
+ BLI_assert(vert_arr[i_prev] == test_v2 || vert_arr[i_prev] == test_v1);
+ }
+ }
+
+ i_prev = i;
+ }
+
+ /* --- */
+
+ if (calc_winding) {
+ if (winding[0] < winding[1]) {
+ winding[0] = 1;
+ winding[1] = 0;
+ }
+ else {
+ winding[0] = 0;
+ winding[1] = 1;
+ }
+ }
+ else {
+ winding[0] = 0;
+ winding[1] = 1;
+ }
+
+ /* --- */
+
+ /* create the face */
+ return BM_face_create_ngon(
+ bm, v_winding[winding[0]], v_winding[winding[1]], edge_arr, len, f_example, create_flag);
}
/**
@@ -381,158 +386,166 @@ BMFace *BM_face_create_ngon_verts(
*/
void BM_verts_sort_radial_plane(BMVert **vert_arr, int len)
{
- struct SortIntByFloat *vang = BLI_array_alloca(vang, len);
- BMVert **vert_arr_map = BLI_array_alloca(vert_arr_map, len);
-
- float totv_inv = 1.0f / (float)len;
- int i = 0;
+ struct SortIntByFloat *vang = BLI_array_alloca(vang, len);
+ BMVert **vert_arr_map = BLI_array_alloca(vert_arr_map, len);
- float cent[3], nor[3];
+ float totv_inv = 1.0f / (float)len;
+ int i = 0;
- const float *far = NULL, *far_cross = NULL;
+ float cent[3], nor[3];
- float far_vec[3];
- float far_cross_vec[3];
- float sign_vec[3]; /* work out if we are pos/neg angle */
+ const float *far = NULL, *far_cross = NULL;
- float far_dist_sq, far_dist_max_sq;
- float far_cross_dist, far_cross_best = 0.0f;
+ float far_vec[3];
+ float far_cross_vec[3];
+ float sign_vec[3]; /* work out if we are pos/neg angle */
- /* get the center point and collect vector array since we loop over these a lot */
- zero_v3(cent);
- for (i = 0; i < len; i++) {
- madd_v3_v3fl(cent, vert_arr[i]->co, totv_inv);
- }
+ float far_dist_sq, far_dist_max_sq;
+ float far_cross_dist, far_cross_best = 0.0f;
+ /* get the center point and collect vector array since we loop over these a lot */
+ zero_v3(cent);
+ for (i = 0; i < len; i++) {
+ madd_v3_v3fl(cent, vert_arr[i]->co, totv_inv);
+ }
- /* find the far point from cent */
- far_dist_max_sq = 0.0f;
- for (i = 0; i < len; i++) {
- far_dist_sq = len_squared_v3v3(vert_arr[i]->co, cent);
- if (far_dist_sq > far_dist_max_sq || far == NULL) {
- far = vert_arr[i]->co;
- far_dist_max_sq = far_dist_sq;
- }
- }
+ /* find the far point from cent */
+ far_dist_max_sq = 0.0f;
+ for (i = 0; i < len; i++) {
+ far_dist_sq = len_squared_v3v3(vert_arr[i]->co, cent);
+ if (far_dist_sq > far_dist_max_sq || far == NULL) {
+ far = vert_arr[i]->co;
+ far_dist_max_sq = far_dist_sq;
+ }
+ }
- sub_v3_v3v3(far_vec, far, cent);
- // far_dist = len_v3(far_vec); /* real dist */ /* UNUSED */
+ sub_v3_v3v3(far_vec, far, cent);
+ // far_dist = len_v3(far_vec); /* real dist */ /* UNUSED */
- /* --- */
+ /* --- */
- /* find a point 90deg about to compare with */
- far_cross_best = 0.0f;
- for (i = 0; i < len; i++) {
+ /* find a point 90deg about to compare with */
+ far_cross_best = 0.0f;
+ for (i = 0; i < len; i++) {
- if (far == vert_arr[i]->co) {
- continue;
- }
+ if (far == vert_arr[i]->co) {
+ continue;
+ }
- sub_v3_v3v3(far_cross_vec, vert_arr[i]->co, cent);
- far_cross_dist = normalize_v3(far_cross_vec);
+ sub_v3_v3v3(far_cross_vec, vert_arr[i]->co, cent);
+ far_cross_dist = normalize_v3(far_cross_vec);
- /* more of a weight then a distance */
- far_cross_dist = (/* first we want to have a value close to zero mapped to 1 */
- 1.0f - fabsf(dot_v3v3(far_vec, far_cross_vec)) *
+ /* more of a weight then a distance */
+ far_cross_dist = (/* first we want to have a value close to zero mapped to 1 */
+ 1.0f - fabsf(dot_v3v3(far_vec, far_cross_vec)) *
- /* second we multiply by the distance
- * so points close to the center are not preferred */
- far_cross_dist);
+ /* second we multiply by the distance
+ * so points close to the center are not preferred */
+ far_cross_dist);
- if (far_cross_dist > far_cross_best || far_cross == NULL) {
- far_cross = vert_arr[i]->co;
- far_cross_best = far_cross_dist;
- }
- }
+ if (far_cross_dist > far_cross_best || far_cross == NULL) {
+ far_cross = vert_arr[i]->co;
+ far_cross_best = far_cross_dist;
+ }
+ }
- sub_v3_v3v3(far_cross_vec, far_cross, cent);
+ sub_v3_v3v3(far_cross_vec, far_cross, cent);
- /* --- */
+ /* --- */
- /* now we have 2 vectors we can have a cross product */
- cross_v3_v3v3(nor, far_vec, far_cross_vec);
- normalize_v3(nor);
- cross_v3_v3v3(sign_vec, far_vec, nor); /* this vector should match 'far_cross_vec' closely */
+ /* now we have 2 vectors we can have a cross product */
+ cross_v3_v3v3(nor, far_vec, far_cross_vec);
+ normalize_v3(nor);
+ cross_v3_v3v3(sign_vec, far_vec, nor); /* this vector should match 'far_cross_vec' closely */
- /* --- */
+ /* --- */
- /* now calculate every points angle around the normal (signed) */
- for (i = 0; i < len; i++) {
- vang[i].sort_value = angle_signed_on_axis_v3v3v3_v3(far, cent, vert_arr[i]->co, nor);
- vang[i].data = i;
- vert_arr_map[i] = vert_arr[i];
- }
+ /* now calculate every points angle around the normal (signed) */
+ for (i = 0; i < len; i++) {
+ vang[i].sort_value = angle_signed_on_axis_v3v3v3_v3(far, cent, vert_arr[i]->co, nor);
+ vang[i].data = i;
+ vert_arr_map[i] = vert_arr[i];
+ }
- /* sort by angle and magic! - we have our ngon */
- qsort(vang, len, sizeof(*vang), BLI_sortutil_cmp_float);
+ /* sort by angle and magic! - we have our ngon */
+ qsort(vang, len, sizeof(*vang), BLI_sortutil_cmp_float);
- /* --- */
+ /* --- */
- for (i = 0; i < len; i++) {
- vert_arr[i] = vert_arr_map[vang[i].data];
- }
+ for (i = 0; i < len; i++) {
+ vert_arr[i] = vert_arr_map[vang[i].data];
+ }
}
/*************************************************************/
-
-static void bm_vert_attrs_copy(
- BMesh *source_mesh, BMesh *target_mesh,
- const BMVert *source_vertex, BMVert *target_vertex, uint64_t cd_mask)
+static void bm_vert_attrs_copy(BMesh *source_mesh,
+ BMesh *target_mesh,
+ const BMVert *source_vertex,
+ BMVert *target_vertex,
+ uint64_t cd_mask)
{
- if ((source_mesh == target_mesh) && (source_vertex == target_vertex)) {
- BLI_assert(!"BMVert: source and targer match");
- return;
- }
- if ((cd_mask & CD_MASK_NORMAL) == 0) {
- copy_v3_v3(target_vertex->no, source_vertex->no);
- }
- CustomData_bmesh_free_block_data(&target_mesh->vdata, target_vertex->head.data);
- CustomData_bmesh_copy_data(&source_mesh->vdata, &target_mesh->vdata,
- source_vertex->head.data, &target_vertex->head.data);
+ if ((source_mesh == target_mesh) && (source_vertex == target_vertex)) {
+ BLI_assert(!"BMVert: source and targer match");
+ return;
+ }
+ if ((cd_mask & CD_MASK_NORMAL) == 0) {
+ copy_v3_v3(target_vertex->no, source_vertex->no);
+ }
+ CustomData_bmesh_free_block_data(&target_mesh->vdata, target_vertex->head.data);
+ CustomData_bmesh_copy_data(&source_mesh->vdata,
+ &target_mesh->vdata,
+ source_vertex->head.data,
+ &target_vertex->head.data);
}
-static void bm_edge_attrs_copy(
- BMesh *source_mesh, BMesh *target_mesh,
- const BMEdge *source_edge, BMEdge *target_edge, uint64_t UNUSED(cd_mask))
+static void bm_edge_attrs_copy(BMesh *source_mesh,
+ BMesh *target_mesh,
+ const BMEdge *source_edge,
+ BMEdge *target_edge,
+ uint64_t UNUSED(cd_mask))
{
- if ((source_mesh == target_mesh) && (source_edge == target_edge)) {
- BLI_assert(!"BMEdge: source and targer match");
- return;
- }
- CustomData_bmesh_free_block_data(&target_mesh->edata, target_edge->head.data);
- CustomData_bmesh_copy_data(&source_mesh->edata, &target_mesh->edata,
- source_edge->head.data, &target_edge->head.data);
+ if ((source_mesh == target_mesh) && (source_edge == target_edge)) {
+ BLI_assert(!"BMEdge: source and targer match");
+ return;
+ }
+ CustomData_bmesh_free_block_data(&target_mesh->edata, target_edge->head.data);
+ CustomData_bmesh_copy_data(
+ &source_mesh->edata, &target_mesh->edata, source_edge->head.data, &target_edge->head.data);
}
-static void bm_loop_attrs_copy(
- BMesh *source_mesh, BMesh *target_mesh,
- const BMLoop *source_loop, BMLoop *target_loop, uint64_t UNUSED(cd_mask))
+static void bm_loop_attrs_copy(BMesh *source_mesh,
+ BMesh *target_mesh,
+ const BMLoop *source_loop,
+ BMLoop *target_loop,
+ uint64_t UNUSED(cd_mask))
{
- if ((source_mesh == target_mesh) && (source_loop == target_loop)) {
- BLI_assert(!"BMLoop: source and targer match");
- return;
- }
- CustomData_bmesh_free_block_data(&target_mesh->ldata, target_loop->head.data);
- CustomData_bmesh_copy_data(&source_mesh->ldata, &target_mesh->ldata,
- source_loop->head.data, &target_loop->head.data);
+ if ((source_mesh == target_mesh) && (source_loop == target_loop)) {
+ BLI_assert(!"BMLoop: source and targer match");
+ return;
+ }
+ CustomData_bmesh_free_block_data(&target_mesh->ldata, target_loop->head.data);
+ CustomData_bmesh_copy_data(
+ &source_mesh->ldata, &target_mesh->ldata, source_loop->head.data, &target_loop->head.data);
}
-static void bm_face_attrs_copy(
- BMesh *source_mesh, BMesh *target_mesh,
- const BMFace *source_face, BMFace *target_face, uint64_t cd_mask)
+static void bm_face_attrs_copy(BMesh *source_mesh,
+ BMesh *target_mesh,
+ const BMFace *source_face,
+ BMFace *target_face,
+ uint64_t cd_mask)
{
- if ((source_mesh == target_mesh) && (source_face == target_face)) {
- BLI_assert(!"BMFace: source and targer match");
- return;
- }
- if ((cd_mask & CD_MASK_NORMAL) == 0) {
- copy_v3_v3(target_face->no, source_face->no);
- }
- CustomData_bmesh_free_block_data(&target_mesh->pdata, target_face->head.data);
- CustomData_bmesh_copy_data(&source_mesh->pdata, &target_mesh->pdata,
- source_face->head.data, &target_face->head.data);
- target_face->mat_nr = source_face->mat_nr;
+ if ((source_mesh == target_mesh) && (source_face == target_face)) {
+ BLI_assert(!"BMFace: source and targer match");
+ return;
+ }
+ if ((cd_mask & CD_MASK_NORMAL) == 0) {
+ copy_v3_v3(target_face->no, source_face->no);
+ }
+ CustomData_bmesh_free_block_data(&target_mesh->pdata, target_face->head.data);
+ CustomData_bmesh_copy_data(
+ &source_mesh->pdata, &target_mesh->pdata, source_face->head.data, &target_face->head.data);
+ target_face->mat_nr = source_face->mat_nr;
}
/* BMESH_TODO: Special handling for hide flags? */
@@ -542,304 +555,293 @@ static void bm_face_attrs_copy(
* Copies attributes, e.g. customdata, header flags, etc, from one element
* to another of the same type.
*/
-void BM_elem_attrs_copy_ex(
- BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v,
- const char hflag_mask, const uint64_t cd_mask)
+void BM_elem_attrs_copy_ex(BMesh *bm_src,
+ BMesh *bm_dst,
+ const void *ele_src_v,
+ void *ele_dst_v,
+ const char hflag_mask,
+ const uint64_t cd_mask)
{
- const BMHeader *ele_src = ele_src_v;
- BMHeader *ele_dst = ele_dst_v;
-
- BLI_assert(ele_src->htype == ele_dst->htype);
- BLI_assert(ele_src != ele_dst);
-
- /* Only support normal layer at the moment. */
- BLI_assert((cd_mask & ~CD_MASK_NORMAL) == 0);
-
- if ((hflag_mask & BM_ELEM_SELECT) == 0) {
- /* First we copy select */
- if (BM_elem_flag_test((BMElem *)ele_src, BM_ELEM_SELECT)) {
- BM_elem_select_set(bm_dst, (BMElem *)ele_dst, true);
- }
- }
-
- /* Now we copy flags */
- if (hflag_mask == 0) {
- ele_dst->hflag = ele_src->hflag;
- }
- else if (hflag_mask == 0xff) {
- /* pass */
- }
- else {
- ele_dst->hflag = ((ele_dst->hflag & hflag_mask) | (ele_src->hflag & ~hflag_mask));
- }
-
- /* Copy specific attributes */
- switch (ele_dst->htype) {
- case BM_VERT:
- bm_vert_attrs_copy(bm_src, bm_dst, (const BMVert *)ele_src, (BMVert *)ele_dst, cd_mask);
- break;
- case BM_EDGE:
- bm_edge_attrs_copy(bm_src, bm_dst, (const BMEdge *)ele_src, (BMEdge *)ele_dst, cd_mask);
- break;
- case BM_LOOP:
- bm_loop_attrs_copy(bm_src, bm_dst, (const BMLoop *)ele_src, (BMLoop *)ele_dst, cd_mask);
- break;
- case BM_FACE:
- bm_face_attrs_copy(bm_src, bm_dst, (const BMFace *)ele_src, (BMFace *)ele_dst, cd_mask);
- break;
- default:
- BLI_assert(0);
- break;
- }
+ const BMHeader *ele_src = ele_src_v;
+ BMHeader *ele_dst = ele_dst_v;
+
+ BLI_assert(ele_src->htype == ele_dst->htype);
+ BLI_assert(ele_src != ele_dst);
+
+ /* Only support normal layer at the moment. */
+ BLI_assert((cd_mask & ~CD_MASK_NORMAL) == 0);
+
+ if ((hflag_mask & BM_ELEM_SELECT) == 0) {
+ /* First we copy select */
+ if (BM_elem_flag_test((BMElem *)ele_src, BM_ELEM_SELECT)) {
+ BM_elem_select_set(bm_dst, (BMElem *)ele_dst, true);
+ }
+ }
+
+ /* Now we copy flags */
+ if (hflag_mask == 0) {
+ ele_dst->hflag = ele_src->hflag;
+ }
+ else if (hflag_mask == 0xff) {
+ /* pass */
+ }
+ else {
+ ele_dst->hflag = ((ele_dst->hflag & hflag_mask) | (ele_src->hflag & ~hflag_mask));
+ }
+
+ /* Copy specific attributes */
+ switch (ele_dst->htype) {
+ case BM_VERT:
+ bm_vert_attrs_copy(bm_src, bm_dst, (const BMVert *)ele_src, (BMVert *)ele_dst, cd_mask);
+ break;
+ case BM_EDGE:
+ bm_edge_attrs_copy(bm_src, bm_dst, (const BMEdge *)ele_src, (BMEdge *)ele_dst, cd_mask);
+ break;
+ case BM_LOOP:
+ bm_loop_attrs_copy(bm_src, bm_dst, (const BMLoop *)ele_src, (BMLoop *)ele_dst, cd_mask);
+ break;
+ case BM_FACE:
+ bm_face_attrs_copy(bm_src, bm_dst, (const BMFace *)ele_src, (BMFace *)ele_dst, cd_mask);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
}
void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src, void *ele_dst)
{
- /* BMESH_TODO, default 'use_flags' to false */
- BM_elem_attrs_copy_ex(bm_src, bm_dst, ele_src, ele_dst, BM_ELEM_SELECT, 0x0);
+ /* BMESH_TODO, default 'use_flags' to false */
+ BM_elem_attrs_copy_ex(bm_src, bm_dst, ele_src, ele_dst, BM_ELEM_SELECT, 0x0);
}
void BM_elem_select_copy(BMesh *bm_dst, void *ele_dst_v, const void *ele_src_v)
{
- BMHeader *ele_dst = ele_dst_v;
- const BMHeader *ele_src = ele_src_v;
+ BMHeader *ele_dst = ele_dst_v;
+ const BMHeader *ele_src = ele_src_v;
- BLI_assert(ele_src->htype == ele_dst->htype);
+ BLI_assert(ele_src->htype == ele_dst->htype);
- if ((ele_src->hflag & BM_ELEM_SELECT) != (ele_dst->hflag & BM_ELEM_SELECT)) {
- BM_elem_select_set(bm_dst, (BMElem *)ele_dst, (ele_src->hflag & BM_ELEM_SELECT) != 0);
- }
+ if ((ele_src->hflag & BM_ELEM_SELECT) != (ele_dst->hflag & BM_ELEM_SELECT)) {
+ BM_elem_select_set(bm_dst, (BMElem *)ele_dst, (ele_src->hflag & BM_ELEM_SELECT) != 0);
+ }
}
/* helper function for 'BM_mesh_copy' */
static BMFace *bm_mesh_copy_new_face(
- BMesh *bm_new, BMesh *bm_old,
- BMVert **vtable, BMEdge **etable,
- BMFace *f)
+ BMesh *bm_new, BMesh *bm_old, BMVert **vtable, BMEdge **etable, BMFace *f)
{
- BMLoop **loops = BLI_array_alloca(loops, f->len);
- BMVert **verts = BLI_array_alloca(verts, f->len);
- BMEdge **edges = BLI_array_alloca(edges, f->len);
-
- BMFace *f_new;
- BMLoop *l_iter, *l_first;
- int j;
-
- j = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- loops[j] = l_iter;
- verts[j] = vtable[BM_elem_index_get(l_iter->v)];
- edges[j] = etable[BM_elem_index_get(l_iter->e)];
- j++;
- } while ((l_iter = l_iter->next) != l_first);
-
- f_new = BM_face_create(bm_new, verts, edges, f->len, NULL, BM_CREATE_SKIP_CD);
-
- if (UNLIKELY(f_new == NULL)) {
- return NULL;
- }
-
- /* use totface in case adding some faces fails */
- BM_elem_index_set(f_new, (bm_new->totface - 1)); /* set_inline */
-
- BM_elem_attrs_copy_ex(bm_old, bm_new, f, f_new, 0xff, 0x0);
- f_new->head.hflag = f->head.hflag; /* low level! don't do this for normal api use */
-
- j = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
- do {
- BM_elem_attrs_copy(bm_old, bm_new, loops[j], l_iter);
- j++;
- } while ((l_iter = l_iter->next) != l_first);
-
- return f_new;
+ BMLoop **loops = BLI_array_alloca(loops, f->len);
+ BMVert **verts = BLI_array_alloca(verts, f->len);
+ BMEdge **edges = BLI_array_alloca(edges, f->len);
+
+ BMFace *f_new;
+ BMLoop *l_iter, *l_first;
+ int j;
+
+ j = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ loops[j] = l_iter;
+ verts[j] = vtable[BM_elem_index_get(l_iter->v)];
+ edges[j] = etable[BM_elem_index_get(l_iter->e)];
+ j++;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ f_new = BM_face_create(bm_new, verts, edges, f->len, NULL, BM_CREATE_SKIP_CD);
+
+ if (UNLIKELY(f_new == NULL)) {
+ return NULL;
+ }
+
+ /* use totface in case adding some faces fails */
+ BM_elem_index_set(f_new, (bm_new->totface - 1)); /* set_inline */
+
+ BM_elem_attrs_copy_ex(bm_old, bm_new, f, f_new, 0xff, 0x0);
+ f_new->head.hflag = f->head.hflag; /* low level! don't do this for normal api use */
+
+ j = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
+ do {
+ BM_elem_attrs_copy(bm_old, bm_new, loops[j], l_iter);
+ j++;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ return f_new;
}
void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const BMAllocTemplate *allocsize)
{
- if (allocsize == NULL) {
- allocsize = &bm_mesh_allocsize_default;
- }
-
- CustomData_copy(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0);
- CustomData_copy(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0);
- CustomData_copy(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0);
- CustomData_copy(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0);
-
- CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT);
- CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE);
- CustomData_bmesh_init_pool(&bm_dst->ldata, allocsize->totloop, BM_LOOP);
- CustomData_bmesh_init_pool(&bm_dst->pdata, allocsize->totface, BM_FACE);
+ if (allocsize == NULL) {
+ allocsize = &bm_mesh_allocsize_default;
+ }
+
+ CustomData_copy(&bm_src->vdata, &bm_dst->vdata, CD_MASK_BMESH.vmask, CD_CALLOC, 0);
+ CustomData_copy(&bm_src->edata, &bm_dst->edata, CD_MASK_BMESH.emask, CD_CALLOC, 0);
+ CustomData_copy(&bm_src->ldata, &bm_dst->ldata, CD_MASK_BMESH.lmask, CD_CALLOC, 0);
+ CustomData_copy(&bm_src->pdata, &bm_dst->pdata, CD_MASK_BMESH.pmask, CD_CALLOC, 0);
+
+ CustomData_bmesh_init_pool(&bm_dst->vdata, allocsize->totvert, BM_VERT);
+ CustomData_bmesh_init_pool(&bm_dst->edata, allocsize->totedge, BM_EDGE);
+ CustomData_bmesh_init_pool(&bm_dst->ldata, allocsize->totloop, BM_LOOP);
+ CustomData_bmesh_init_pool(&bm_dst->pdata, allocsize->totface, BM_FACE);
}
-
BMesh *BM_mesh_copy(BMesh *bm_old)
{
- BMesh *bm_new;
- BMVert *v, *v_new, **vtable = NULL;
- BMEdge *e, *e_new, **etable = NULL;
- BMFace *f, *f_new, **ftable = NULL;
- BMElem **eletable;
- BMEditSelection *ese;
- BMIter iter;
- int i;
- const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_BM(bm_old);
-
- /* allocate a bmesh */
- bm_new = BM_mesh_create(
- &allocsize,
- &((struct BMeshCreateParams){.use_toolflags = bm_old->use_toolflags,}));
-
- BM_mesh_copy_init_customdata(bm_new, bm_old, &allocsize);
-
- vtable = MEM_mallocN(sizeof(BMVert *) * bm_old->totvert, "BM_mesh_copy vtable");
- etable = MEM_mallocN(sizeof(BMEdge *) * bm_old->totedge, "BM_mesh_copy etable");
- ftable = MEM_mallocN(sizeof(BMFace *) * bm_old->totface, "BM_mesh_copy ftable");
-
- BM_ITER_MESH_INDEX (v, &iter, bm_old, BM_VERTS_OF_MESH, i) {
- /* copy between meshes so cant use 'example' argument */
- v_new = BM_vert_create(bm_new, v->co, NULL, BM_CREATE_SKIP_CD);
- BM_elem_attrs_copy_ex(bm_old, bm_new, v, v_new, 0xff, 0x0);
- v_new->head.hflag = v->head.hflag; /* low level! don't do this for normal api use */
- vtable[i] = v_new;
- BM_elem_index_set(v, i); /* set_inline */
- BM_elem_index_set(v_new, i); /* set_inline */
- }
- bm_old->elem_index_dirty &= ~BM_VERT;
- bm_new->elem_index_dirty &= ~BM_VERT;
-
- /* safety check */
- BLI_assert(i == bm_old->totvert);
-
- BM_ITER_MESH_INDEX (e, &iter, bm_old, BM_EDGES_OF_MESH, i) {
- e_new = BM_edge_create(bm_new,
- vtable[BM_elem_index_get(e->v1)],
- vtable[BM_elem_index_get(e->v2)],
- e, BM_CREATE_SKIP_CD);
-
- BM_elem_attrs_copy_ex(bm_old, bm_new, e, e_new, 0xff, 0x0);
- e_new->head.hflag = e->head.hflag; /* low level! don't do this for normal api use */
- etable[i] = e_new;
- BM_elem_index_set(e, i); /* set_inline */
- BM_elem_index_set(e_new, i); /* set_inline */
- }
- bm_old->elem_index_dirty &= ~BM_EDGE;
- bm_new->elem_index_dirty &= ~BM_EDGE;
-
- /* safety check */
- BLI_assert(i == bm_old->totedge);
-
- BM_ITER_MESH_INDEX (f, &iter, bm_old, BM_FACES_OF_MESH, i) {
- BM_elem_index_set(f, i); /* set_inline */
-
- f_new = bm_mesh_copy_new_face(bm_new, bm_old, vtable, etable, f);
-
- ftable[i] = f_new;
-
- if (f == bm_old->act_face) {
- bm_new->act_face = f_new;
- }
- }
- bm_old->elem_index_dirty &= ~BM_FACE;
- bm_new->elem_index_dirty &= ~BM_FACE;
-
-
- /* low level! don't do this for normal api use */
- bm_new->totvertsel = bm_old->totvertsel;
- bm_new->totedgesel = bm_old->totedgesel;
- bm_new->totfacesel = bm_old->totfacesel;
-
- /* safety check */
- BLI_assert(i == bm_old->totface);
-
- /* copy over edit selection history */
- for (ese = bm_old->selected.first; ese; ese = ese->next) {
- BMElem *ele = NULL;
-
- switch (ese->htype) {
- case BM_VERT:
- eletable = (BMElem **)vtable;
- break;
- case BM_EDGE:
- eletable = (BMElem **)etable;
- break;
- case BM_FACE:
- eletable = (BMElem **)ftable;
- break;
- default:
- eletable = NULL;
- break;
- }
-
- if (eletable) {
- ele = eletable[BM_elem_index_get(ese->ele)];
- if (ele) {
- BM_select_history_store(bm_new, ele);
- }
- }
- }
-
- MEM_freeN(etable);
- MEM_freeN(vtable);
- MEM_freeN(ftable);
-
- return bm_new;
+ BMesh *bm_new;
+ BMVert *v, *v_new, **vtable = NULL;
+ BMEdge *e, *e_new, **etable = NULL;
+ BMFace *f, *f_new, **ftable = NULL;
+ BMElem **eletable;
+ BMEditSelection *ese;
+ BMIter iter;
+ int i;
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_BM(bm_old);
+
+ /* allocate a bmesh */
+ bm_new = BM_mesh_create(&allocsize,
+ &((struct BMeshCreateParams){
+ .use_toolflags = bm_old->use_toolflags,
+ }));
+
+ BM_mesh_copy_init_customdata(bm_new, bm_old, &allocsize);
+
+ vtable = MEM_mallocN(sizeof(BMVert *) * bm_old->totvert, "BM_mesh_copy vtable");
+ etable = MEM_mallocN(sizeof(BMEdge *) * bm_old->totedge, "BM_mesh_copy etable");
+ ftable = MEM_mallocN(sizeof(BMFace *) * bm_old->totface, "BM_mesh_copy ftable");
+
+ BM_ITER_MESH_INDEX (v, &iter, bm_old, BM_VERTS_OF_MESH, i) {
+ /* copy between meshes so cant use 'example' argument */
+ v_new = BM_vert_create(bm_new, v->co, NULL, BM_CREATE_SKIP_CD);
+ BM_elem_attrs_copy_ex(bm_old, bm_new, v, v_new, 0xff, 0x0);
+ v_new->head.hflag = v->head.hflag; /* low level! don't do this for normal api use */
+ vtable[i] = v_new;
+ BM_elem_index_set(v, i); /* set_inline */
+ BM_elem_index_set(v_new, i); /* set_inline */
+ }
+ bm_old->elem_index_dirty &= ~BM_VERT;
+ bm_new->elem_index_dirty &= ~BM_VERT;
+
+ /* safety check */
+ BLI_assert(i == bm_old->totvert);
+
+ BM_ITER_MESH_INDEX (e, &iter, bm_old, BM_EDGES_OF_MESH, i) {
+ e_new = BM_edge_create(bm_new,
+ vtable[BM_elem_index_get(e->v1)],
+ vtable[BM_elem_index_get(e->v2)],
+ e,
+ BM_CREATE_SKIP_CD);
+
+ BM_elem_attrs_copy_ex(bm_old, bm_new, e, e_new, 0xff, 0x0);
+ e_new->head.hflag = e->head.hflag; /* low level! don't do this for normal api use */
+ etable[i] = e_new;
+ BM_elem_index_set(e, i); /* set_inline */
+ BM_elem_index_set(e_new, i); /* set_inline */
+ }
+ bm_old->elem_index_dirty &= ~BM_EDGE;
+ bm_new->elem_index_dirty &= ~BM_EDGE;
+
+ /* safety check */
+ BLI_assert(i == bm_old->totedge);
+
+ BM_ITER_MESH_INDEX (f, &iter, bm_old, BM_FACES_OF_MESH, i) {
+ BM_elem_index_set(f, i); /* set_inline */
+
+ f_new = bm_mesh_copy_new_face(bm_new, bm_old, vtable, etable, f);
+
+ ftable[i] = f_new;
+
+ if (f == bm_old->act_face) {
+ bm_new->act_face = f_new;
+ }
+ }
+ bm_old->elem_index_dirty &= ~BM_FACE;
+ bm_new->elem_index_dirty &= ~BM_FACE;
+
+ /* low level! don't do this for normal api use */
+ bm_new->totvertsel = bm_old->totvertsel;
+ bm_new->totedgesel = bm_old->totedgesel;
+ bm_new->totfacesel = bm_old->totfacesel;
+
+ /* safety check */
+ BLI_assert(i == bm_old->totface);
+
+ /* copy over edit selection history */
+ for (ese = bm_old->selected.first; ese; ese = ese->next) {
+ BMElem *ele = NULL;
+
+ switch (ese->htype) {
+ case BM_VERT:
+ eletable = (BMElem **)vtable;
+ break;
+ case BM_EDGE:
+ eletable = (BMElem **)etable;
+ break;
+ case BM_FACE:
+ eletable = (BMElem **)ftable;
+ break;
+ default:
+ eletable = NULL;
+ break;
+ }
+
+ if (eletable) {
+ ele = eletable[BM_elem_index_get(ese->ele)];
+ if (ele) {
+ BM_select_history_store(bm_new, ele);
+ }
+ }
+ }
+
+ MEM_freeN(etable);
+ MEM_freeN(vtable);
+ MEM_freeN(ftable);
+
+ return bm_new;
}
/* ME -> BM */
-char BM_vert_flag_from_mflag(const char meflag)
+char BM_vert_flag_from_mflag(const char meflag)
{
- return ( ((meflag & SELECT) ? BM_ELEM_SELECT : 0) |
- ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0)
- );
+ return (((meflag & SELECT) ? BM_ELEM_SELECT : 0) | ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0));
}
char BM_edge_flag_from_mflag(const short meflag)
{
- return ( ((meflag & SELECT) ? BM_ELEM_SELECT : 0) |
- ((meflag & ME_SEAM) ? BM_ELEM_SEAM : 0) |
- ((meflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) |
- ((meflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0) | /* invert */
- ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0)
- );
+ return (((meflag & SELECT) ? BM_ELEM_SELECT : 0) | ((meflag & ME_SEAM) ? BM_ELEM_SEAM : 0) |
+ ((meflag & ME_EDGEDRAW) ? BM_ELEM_DRAW : 0) |
+ ((meflag & ME_SHARP) == 0 ? BM_ELEM_SMOOTH : 0) | /* invert */
+ ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0));
}
-char BM_face_flag_from_mflag(const char meflag)
+char BM_face_flag_from_mflag(const char meflag)
{
- return ( ((meflag & ME_FACE_SEL) ? BM_ELEM_SELECT : 0) |
- ((meflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0) |
- ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0)
- );
+ return (((meflag & ME_FACE_SEL) ? BM_ELEM_SELECT : 0) |
+ ((meflag & ME_SMOOTH) ? BM_ELEM_SMOOTH : 0) | ((meflag & ME_HIDE) ? BM_ELEM_HIDDEN : 0));
}
/* BM -> ME */
-char BM_vert_flag_to_mflag(BMVert *eve)
+char BM_vert_flag_to_mflag(BMVert *eve)
{
- const char hflag = eve->head.hflag;
+ const char hflag = eve->head.hflag;
- return ( ((hflag & BM_ELEM_SELECT) ? SELECT : 0) |
- ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0)
- );
+ return (((hflag & BM_ELEM_SELECT) ? SELECT : 0) | ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0));
}
short BM_edge_flag_to_mflag(BMEdge *eed)
{
- const char hflag = eed->head.hflag;
-
- return ( ((hflag & BM_ELEM_SELECT) ? SELECT : 0) |
- ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) |
- ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) |
- ((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) |
- ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) |
- ((BM_edge_is_wire(eed)) ? ME_LOOSEEDGE : 0) | /* not typical */
- ME_EDGERENDER
- );
+ const char hflag = eed->head.hflag;
+
+ return (((hflag & BM_ELEM_SELECT) ? SELECT : 0) | ((hflag & BM_ELEM_SEAM) ? ME_SEAM : 0) |
+ ((hflag & BM_ELEM_DRAW) ? ME_EDGEDRAW : 0) |
+ ((hflag & BM_ELEM_SMOOTH) == 0 ? ME_SHARP : 0) |
+ ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0) |
+ ((BM_edge_is_wire(eed)) ? ME_LOOSEEDGE : 0) | /* not typical */
+ ME_EDGERENDER);
}
-char BM_face_flag_to_mflag(BMFace *efa)
+char BM_face_flag_to_mflag(BMFace *efa)
{
- const char hflag = efa->head.hflag;
+ const char hflag = efa->head.hflag;
- return ( ((hflag & BM_ELEM_SELECT) ? ME_FACE_SEL : 0) |
- ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0) |
- ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0)
- );
+ return (((hflag & BM_ELEM_SELECT) ? ME_FACE_SEL : 0) |
+ ((hflag & BM_ELEM_SMOOTH) ? ME_SMOOTH : 0) | ((hflag & BM_ELEM_HIDDEN) ? ME_HIDE : 0));
}
diff --git a/source/blender/bmesh/intern/bmesh_construct.h b/source/blender/bmesh/intern/bmesh_construct.h
index 0dfa0a81b91..0b285979369 100644
--- a/source/blender/bmesh/intern/bmesh_construct.h
+++ b/source/blender/bmesh/intern/bmesh_construct.h
@@ -29,38 +29,52 @@ bool BM_edges_from_verts(BMEdge **edge_arr, BMVert **vert_arr, const int len);
void BM_edges_from_verts_ensure(BMesh *bm, BMEdge **edge_arr, BMVert **vert_arr, const int len);
/* sort before creation */
-void BM_verts_sort_radial_plane(BMVert **vert_arr, int len);
+void BM_verts_sort_radial_plane(BMVert **vert_arr, int len);
-BMFace *BM_face_create_quad_tri(
- BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4,
- const BMFace *f_example, const eBMCreateFlag create_flag);
+BMFace *BM_face_create_quad_tri(BMesh *bm,
+ BMVert *v1,
+ BMVert *v2,
+ BMVert *v3,
+ BMVert *v4,
+ const BMFace *f_example,
+ const eBMCreateFlag create_flag);
-void BM_face_copy_shared(
- BMesh *bm, BMFace *f,
- BMLoopFilterFunc filter_fn, void *user_data);
+void BM_face_copy_shared(BMesh *bm, BMFace *f, BMLoopFilterFunc filter_fn, void *user_data);
-BMFace *BM_face_create_ngon(
- BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, const int len,
- const BMFace *f_example, const eBMCreateFlag create_flag);
-BMFace *BM_face_create_ngon_verts(
- BMesh *bm, BMVert **vert_arr, const int len,
- const BMFace *f_example, const eBMCreateFlag create_flag,
- const bool calc_winding, const bool create_edges);
+BMFace *BM_face_create_ngon(BMesh *bm,
+ BMVert *v1,
+ BMVert *v2,
+ BMEdge **edges,
+ const int len,
+ const BMFace *f_example,
+ const eBMCreateFlag create_flag);
+BMFace *BM_face_create_ngon_verts(BMesh *bm,
+ BMVert **vert_arr,
+ const int len,
+ const BMFace *f_example,
+ const eBMCreateFlag create_flag,
+ const bool calc_winding,
+ const bool create_edges);
-void BM_elem_attrs_copy_ex(
- BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v,
- const char hflag_mask, const uint64_t cd_mask);
+void BM_elem_attrs_copy_ex(BMesh *bm_src,
+ BMesh *bm_dst,
+ const void *ele_src_v,
+ void *ele_dst_v,
+ const char hflag_mask,
+ const uint64_t cd_mask);
void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src_v, void *ele_dst_v);
void BM_elem_select_copy(BMesh *bm_dst, void *ele_dst_v, const void *ele_src_v);
-void BM_mesh_copy_init_customdata(BMesh *bm_dst, BMesh *bm_src, const struct BMAllocTemplate *allocsize);
+void BM_mesh_copy_init_customdata(BMesh *bm_dst,
+ BMesh *bm_src,
+ const struct BMAllocTemplate *allocsize);
BMesh *BM_mesh_copy(BMesh *bm_old);
-char BM_face_flag_from_mflag(const char mflag);
-char BM_edge_flag_from_mflag(const short mflag);
-char BM_vert_flag_from_mflag(const char mflag);
-char BM_face_flag_to_mflag(BMFace *f);
+char BM_face_flag_from_mflag(const char mflag);
+char BM_edge_flag_from_mflag(const short mflag);
+char BM_vert_flag_from_mflag(const char mflag);
+char BM_face_flag_to_mflag(BMFace *f);
short BM_edge_flag_to_mflag(BMEdge *e);
-char BM_vert_flag_to_mflag(BMVert *v);
+char BM_vert_flag_to_mflag(BMVert *v);
#endif /* __BMESH_CONSTRUCT_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 58b83cd0586..5dcf6acad57 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -43,96 +43,97 @@
// #define USE_DEBUG_INDEX_MEMCHECK
#ifdef USE_DEBUG_INDEX_MEMCHECK
-#define DEBUG_MEMCHECK_INDEX_INVALIDATE(ele) \
- { \
- int undef_idx; \
- BM_elem_index_set(ele, undef_idx); /* set_ok_invalid */ \
- } (void)0
+# define DEBUG_MEMCHECK_INDEX_INVALIDATE(ele) \
+ { \
+ int undef_idx; \
+ BM_elem_index_set(ele, undef_idx); /* set_ok_invalid */ \
+ } \
+ (void)0
#endif
/**
* \brief Main function for creating a new vertex.
*/
-BMVert *BM_vert_create(
- BMesh *bm, const float co[3],
- const BMVert *v_example, const eBMCreateFlag create_flag)
+BMVert *BM_vert_create(BMesh *bm,
+ const float co[3],
+ const BMVert *v_example,
+ const eBMCreateFlag create_flag)
{
- BMVert *v = BLI_mempool_alloc(bm->vpool);
+ BMVert *v = BLI_mempool_alloc(bm->vpool);
- BLI_assert((v_example == NULL) || (v_example->head.htype == BM_VERT));
- BLI_assert(!(create_flag & 1));
+ BLI_assert((v_example == NULL) || (v_example->head.htype == BM_VERT));
+ BLI_assert(!(create_flag & 1));
- /* --- assign all members --- */
- v->head.data = NULL;
+ /* --- assign all members --- */
+ v->head.data = NULL;
#ifdef USE_DEBUG_INDEX_MEMCHECK
- DEBUG_MEMCHECK_INDEX_INVALIDATE(v)
+ DEBUG_MEMCHECK_INDEX_INVALIDATE(v)
#else
- BM_elem_index_set(v, -1); /* set_ok_invalid */
+ BM_elem_index_set(v, -1); /* set_ok_invalid */
#endif
- v->head.htype = BM_VERT;
- v->head.hflag = 0;
- v->head.api_flag = 0;
-
- /* allocate flags */
- if (bm->use_toolflags) {
- ((BMVert_OFlag *)v)->oflags = bm->vtoolflagpool ? BLI_mempool_calloc(bm->vtoolflagpool) : NULL;
- }
-
- /* 'v->no' is handled by BM_elem_attrs_copy */
- if (co) {
- copy_v3_v3(v->co, co);
- }
- else {
- zero_v3(v->co);
- }
- /* 'v->no' set below */
-
- v->e = NULL;
- /* --- done --- */
-
-
- /* disallow this flag for verts - its meaningless */
- BLI_assert((create_flag & BM_CREATE_NO_DOUBLE) == 0);
-
- /* may add to middle of the pool */
- bm->elem_index_dirty |= BM_VERT;
- bm->elem_table_dirty |= BM_VERT;
-
- bm->totvert++;
-
- if (!(create_flag & BM_CREATE_SKIP_CD)) {
- if (v_example) {
- int *keyi;
-
- /* handles 'v->no' too */
- BM_elem_attrs_copy(bm, bm, v_example, v);
-
- /* exception: don't copy the original shapekey index */
- keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
- if (keyi) {
- *keyi = ORIGINDEX_NONE;
- }
- }
- else {
- CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
- zero_v3(v->no);
- }
- }
- else {
- if (v_example) {
- copy_v3_v3(v->no, v_example->no);
- }
- else {
- zero_v3(v->no);
- }
- }
-
- BM_CHECK_ELEMENT(v);
-
- return v;
+ v->head.htype = BM_VERT;
+ v->head.hflag = 0;
+ v->head.api_flag = 0;
+
+ /* allocate flags */
+ if (bm->use_toolflags) {
+ ((BMVert_OFlag *)v)->oflags = bm->vtoolflagpool ? BLI_mempool_calloc(bm->vtoolflagpool) : NULL;
+ }
+
+ /* 'v->no' is handled by BM_elem_attrs_copy */
+ if (co) {
+ copy_v3_v3(v->co, co);
+ }
+ else {
+ zero_v3(v->co);
+ }
+ /* 'v->no' set below */
+
+ v->e = NULL;
+ /* --- done --- */
+
+ /* disallow this flag for verts - its meaningless */
+ BLI_assert((create_flag & BM_CREATE_NO_DOUBLE) == 0);
+
+ /* may add to middle of the pool */
+ bm->elem_index_dirty |= BM_VERT;
+ bm->elem_table_dirty |= BM_VERT;
+
+ bm->totvert++;
+
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ if (v_example) {
+ int *keyi;
+
+ /* handles 'v->no' too */
+ BM_elem_attrs_copy(bm, bm, v_example, v);
+
+ /* exception: don't copy the original shapekey index */
+ keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
+ if (keyi) {
+ *keyi = ORIGINDEX_NONE;
+ }
+ }
+ else {
+ CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
+ zero_v3(v->no);
+ }
+ }
+ else {
+ if (v_example) {
+ copy_v3_v3(v->no, v_example->no);
+ }
+ else {
+ zero_v3(v->no);
+ }
+ }
+
+ BM_CHECK_ELEMENT(v);
+
+ return v;
}
/**
@@ -142,70 +143,67 @@ BMVert *BM_vert_create(
* so unless you need a unique edge or know the edge won't exist, you should call with \a no_double = true
*/
BMEdge *BM_edge_create(
- BMesh *bm, BMVert *v1, BMVert *v2,
- const BMEdge *e_example, const eBMCreateFlag create_flag)
+ BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag)
{
- BMEdge *e;
+ BMEdge *e;
- BLI_assert(v1 != v2);
- BLI_assert(v1->head.htype == BM_VERT && v2->head.htype == BM_VERT);
- BLI_assert((e_example == NULL) || (e_example->head.htype == BM_EDGE));
- BLI_assert(!(create_flag & 1));
+ BLI_assert(v1 != v2);
+ BLI_assert(v1->head.htype == BM_VERT && v2->head.htype == BM_VERT);
+ BLI_assert((e_example == NULL) || (e_example->head.htype == BM_EDGE));
+ BLI_assert(!(create_flag & 1));
- if ((create_flag & BM_CREATE_NO_DOUBLE) && (e = BM_edge_exists(v1, v2))) {
- return e;
- }
+ if ((create_flag & BM_CREATE_NO_DOUBLE) && (e = BM_edge_exists(v1, v2))) {
+ return e;
+ }
- e = BLI_mempool_alloc(bm->epool);
+ e = BLI_mempool_alloc(bm->epool);
-
- /* --- assign all members --- */
- e->head.data = NULL;
+ /* --- assign all members --- */
+ e->head.data = NULL;
#ifdef USE_DEBUG_INDEX_MEMCHECK
- DEBUG_MEMCHECK_INDEX_INVALIDATE(e)
+ DEBUG_MEMCHECK_INDEX_INVALIDATE(e)
#else
- BM_elem_index_set(e, -1); /* set_ok_invalid */
+ BM_elem_index_set(e, -1); /* set_ok_invalid */
#endif
- e->head.htype = BM_EDGE;
- e->head.hflag = BM_ELEM_SMOOTH | BM_ELEM_DRAW;
- e->head.api_flag = 0;
-
- /* allocate flags */
- if (bm->use_toolflags) {
- ((BMEdge_OFlag *)e)->oflags = bm->etoolflagpool ? BLI_mempool_calloc(bm->etoolflagpool) : NULL;
- }
+ e->head.htype = BM_EDGE;
+ e->head.hflag = BM_ELEM_SMOOTH | BM_ELEM_DRAW;
+ e->head.api_flag = 0;
- e->v1 = v1;
- e->v2 = v2;
- e->l = NULL;
+ /* allocate flags */
+ if (bm->use_toolflags) {
+ ((BMEdge_OFlag *)e)->oflags = bm->etoolflagpool ? BLI_mempool_calloc(bm->etoolflagpool) : NULL;
+ }
- memset(&e->v1_disk_link, 0, sizeof(BMDiskLink) * 2);
- /* --- done --- */
+ e->v1 = v1;
+ e->v2 = v2;
+ e->l = NULL;
+ memset(&e->v1_disk_link, 0, sizeof(BMDiskLink) * 2);
+ /* --- done --- */
- bmesh_disk_edge_append(e, e->v1);
- bmesh_disk_edge_append(e, e->v2);
+ bmesh_disk_edge_append(e, e->v1);
+ bmesh_disk_edge_append(e, e->v2);
- /* may add to middle of the pool */
- bm->elem_index_dirty |= BM_EDGE;
- bm->elem_table_dirty |= BM_EDGE;
+ /* may add to middle of the pool */
+ bm->elem_index_dirty |= BM_EDGE;
+ bm->elem_table_dirty |= BM_EDGE;
- bm->totedge++;
+ bm->totedge++;
- if (!(create_flag & BM_CREATE_SKIP_CD)) {
- if (e_example) {
- BM_elem_attrs_copy(bm, bm, e_example, e);
- }
- else {
- CustomData_bmesh_set_default(&bm->edata, &e->head.data);
- }
- }
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ if (e_example) {
+ BM_elem_attrs_copy(bm, bm, e_example, e);
+ }
+ else {
+ CustomData_bmesh_set_default(&bm->edata, &e->head.data);
+ }
+ }
- BM_CHECK_ELEMENT(e);
+ BM_CHECK_ELEMENT(e);
- return e;
+ return e;
}
/**
@@ -213,150 +211,151 @@ BMEdge *BM_edge_create(
* since this is a low level API and we shouldn't attempt to be clever and guess whats intended.
* In cases where copying adjacent loop-data is useful, see #BM_face_copy_shared.
*/
-static BMLoop *bm_loop_create(
- BMesh *bm, BMVert *v, BMEdge *e, BMFace *f,
- const BMLoop *l_example, const eBMCreateFlag create_flag)
+static BMLoop *bm_loop_create(BMesh *bm,
+ BMVert *v,
+ BMEdge *e,
+ BMFace *f,
+ const BMLoop *l_example,
+ const eBMCreateFlag create_flag)
{
- BMLoop *l = NULL;
+ BMLoop *l = NULL;
- l = BLI_mempool_alloc(bm->lpool);
+ l = BLI_mempool_alloc(bm->lpool);
- BLI_assert((l_example == NULL) || (l_example->head.htype == BM_LOOP));
- BLI_assert(!(create_flag & 1));
+ BLI_assert((l_example == NULL) || (l_example->head.htype == BM_LOOP));
+ BLI_assert(!(create_flag & 1));
#ifndef NDEBUG
- if (l_example) {
- /* ensure passing a loop is either sharing the same vertex, or entirely disconnected
- * use to catch mistake passing in loop offset-by-one. */
- BLI_assert((v == l_example->v) || !ELEM(v, l_example->prev->v, l_example->next->v));
- }
+ if (l_example) {
+ /* ensure passing a loop is either sharing the same vertex, or entirely disconnected
+ * use to catch mistake passing in loop offset-by-one. */
+ BLI_assert((v == l_example->v) || !ELEM(v, l_example->prev->v, l_example->next->v));
+ }
#endif
- /* --- assign all members --- */
- l->head.data = NULL;
+ /* --- assign all members --- */
+ l->head.data = NULL;
#ifdef USE_DEBUG_INDEX_MEMCHECK
- DEBUG_MEMCHECK_INDEX_INVALIDATE(l)
+ DEBUG_MEMCHECK_INDEX_INVALIDATE(l)
#else
- BM_elem_index_set(l, -1); /* set_ok_invalid */
+ BM_elem_index_set(l, -1); /* set_ok_invalid */
#endif
- l->head.htype = BM_LOOP;
- l->head.hflag = 0;
- l->head.api_flag = 0;
-
- l->v = v;
- l->e = e;
- l->f = f;
-
- l->radial_next = NULL;
- l->radial_prev = NULL;
- l->next = NULL;
- l->prev = NULL;
- /* --- done --- */
-
- /* may add to middle of the pool */
- bm->elem_index_dirty |= BM_LOOP;
-
- bm->totloop++;
-
- if (!(create_flag & BM_CREATE_SKIP_CD)) {
- if (l_example) {
- /* no need to copy attrs, just handle customdata */
- // BM_elem_attrs_copy(bm, bm, l_example, l);
- CustomData_bmesh_free_block_data(&bm->ldata, l->head.data);
- CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, l_example->head.data, &l->head.data);
- }
- else {
- CustomData_bmesh_set_default(&bm->ldata, &l->head.data);
- }
- }
-
- return l;
+ l->head.htype = BM_LOOP;
+ l->head.hflag = 0;
+ l->head.api_flag = 0;
+
+ l->v = v;
+ l->e = e;
+ l->f = f;
+
+ l->radial_next = NULL;
+ l->radial_prev = NULL;
+ l->next = NULL;
+ l->prev = NULL;
+ /* --- done --- */
+
+ /* may add to middle of the pool */
+ bm->elem_index_dirty |= BM_LOOP;
+
+ bm->totloop++;
+
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ if (l_example) {
+ /* no need to copy attrs, just handle customdata */
+ // BM_elem_attrs_copy(bm, bm, l_example, l);
+ CustomData_bmesh_free_block_data(&bm->ldata, l->head.data);
+ CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata, l_example->head.data, &l->head.data);
+ }
+ else {
+ CustomData_bmesh_set_default(&bm->ldata, &l->head.data);
+ }
+ }
+
+ return l;
}
static BMLoop *bm_face_boundary_add(
- BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte,
- const eBMCreateFlag create_flag)
+ BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte, const eBMCreateFlag create_flag)
{
#ifdef USE_BMESH_HOLES
- BMLoopList *lst = BLI_mempool_calloc(bm->looplistpool);
+ BMLoopList *lst = BLI_mempool_calloc(bm->looplistpool);
#endif
- BMLoop *l = bm_loop_create(bm, startv, starte, f, NULL /* starte->l */, create_flag);
+ BMLoop *l = bm_loop_create(bm, startv, starte, f, NULL /* starte->l */, create_flag);
- bmesh_radial_loop_append(starte, l);
+ bmesh_radial_loop_append(starte, l);
#ifdef USE_BMESH_HOLES
- lst->first = lst->last = l;
- BLI_addtail(&f->loops, lst);
+ lst->first = lst->last = l;
+ BLI_addtail(&f->loops, lst);
#else
- f->l_first = l;
+ f->l_first = l;
#endif
- return l;
+ return l;
}
BMFace *BM_face_copy(
- BMesh *bm_dst, BMesh *bm_src, BMFace *f,
- const bool copy_verts, const bool copy_edges)
+ BMesh *bm_dst, BMesh *bm_src, BMFace *f, const bool copy_verts, const bool copy_edges)
{
- BMVert **verts = BLI_array_alloca(verts, f->len);
- BMEdge **edges = BLI_array_alloca(edges, f->len);
- BMLoop *l_iter;
- BMLoop *l_first;
- BMLoop *l_copy;
- BMFace *f_copy;
- int i;
-
- BLI_assert((bm_dst == bm_src) || (copy_verts && copy_edges));
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- i = 0;
- do {
- if (copy_verts) {
- verts[i] = BM_vert_create(bm_dst, l_iter->v->co, l_iter->v, BM_CREATE_NOP);
- }
- else {
- verts[i] = l_iter->v;
- }
- i++;
- } while ((l_iter = l_iter->next) != l_first);
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- i = 0;
- do {
- if (copy_edges) {
- BMVert *v1, *v2;
-
- if (l_iter->e->v1 == verts[i]) {
- v1 = verts[i];
- v2 = verts[(i + 1) % f->len];
- }
- else {
- v2 = verts[i];
- v1 = verts[(i + 1) % f->len];
- }
-
- edges[i] = BM_edge_create(bm_dst, v1, v2, l_iter->e, BM_CREATE_NOP);
- }
- else {
- edges[i] = l_iter->e;
- }
- i++;
- } while ((l_iter = l_iter->next) != l_first);
-
- f_copy = BM_face_create(bm_dst, verts, edges, f->len, NULL, BM_CREATE_SKIP_CD);
-
- BM_elem_attrs_copy(bm_src, bm_dst, f, f_copy);
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- l_copy = BM_FACE_FIRST_LOOP(f_copy);
- do {
- BM_elem_attrs_copy(bm_src, bm_dst, l_iter, l_copy);
- l_copy = l_copy->next;
- } while ((l_iter = l_iter->next) != l_first);
-
- return f_copy;
+ BMVert **verts = BLI_array_alloca(verts, f->len);
+ BMEdge **edges = BLI_array_alloca(edges, f->len);
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ BMLoop *l_copy;
+ BMFace *f_copy;
+ int i;
+
+ BLI_assert((bm_dst == bm_src) || (copy_verts && copy_edges));
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ i = 0;
+ do {
+ if (copy_verts) {
+ verts[i] = BM_vert_create(bm_dst, l_iter->v->co, l_iter->v, BM_CREATE_NOP);
+ }
+ else {
+ verts[i] = l_iter->v;
+ }
+ i++;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ i = 0;
+ do {
+ if (copy_edges) {
+ BMVert *v1, *v2;
+
+ if (l_iter->e->v1 == verts[i]) {
+ v1 = verts[i];
+ v2 = verts[(i + 1) % f->len];
+ }
+ else {
+ v2 = verts[i];
+ v1 = verts[(i + 1) % f->len];
+ }
+
+ edges[i] = BM_edge_create(bm_dst, v1, v2, l_iter->e, BM_CREATE_NOP);
+ }
+ else {
+ edges[i] = l_iter->e;
+ }
+ i++;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ f_copy = BM_face_create(bm_dst, verts, edges, f->len, NULL, BM_CREATE_SKIP_CD);
+
+ BM_elem_attrs_copy(bm_src, bm_dst, f, f_copy);
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ l_copy = BM_FACE_FIRST_LOOP(f_copy);
+ do {
+ BM_elem_attrs_copy(bm_src, bm_dst, l_iter, l_copy);
+ l_copy = l_copy->next;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ return f_copy;
}
/**
@@ -367,51 +366,49 @@ BMFace *BM_face_copy(
*/
BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
{
- BMFace *f;
+ BMFace *f;
- f = BLI_mempool_alloc(bm->fpool);
+ f = BLI_mempool_alloc(bm->fpool);
-
- /* --- assign all members --- */
- f->head.data = NULL;
+ /* --- assign all members --- */
+ f->head.data = NULL;
#ifdef USE_DEBUG_INDEX_MEMCHECK
- DEBUG_MEMCHECK_INDEX_INVALIDATE(f)
+ DEBUG_MEMCHECK_INDEX_INVALIDATE(f)
#else
- BM_elem_index_set(f, -1); /* set_ok_invalid */
+ BM_elem_index_set(f, -1); /* set_ok_invalid */
#endif
- f->head.htype = BM_FACE;
- f->head.hflag = 0;
- f->head.api_flag = 0;
+ f->head.htype = BM_FACE;
+ f->head.hflag = 0;
+ f->head.api_flag = 0;
- /* allocate flags */
- if (bm->use_toolflags) {
- ((BMFace_OFlag *)f)->oflags = bm->ftoolflagpool ? BLI_mempool_calloc(bm->ftoolflagpool) : NULL;
- }
+ /* allocate flags */
+ if (bm->use_toolflags) {
+ ((BMFace_OFlag *)f)->oflags = bm->ftoolflagpool ? BLI_mempool_calloc(bm->ftoolflagpool) : NULL;
+ }
#ifdef USE_BMESH_HOLES
- BLI_listbase_clear(&f->loops);
+ BLI_listbase_clear(&f->loops);
#else
- f->l_first = NULL;
+ f->l_first = NULL;
#endif
- f->len = 0;
- /* caller must initialize */
- // zero_v3(f->no);
- f->mat_nr = 0;
- /* --- done --- */
-
+ f->len = 0;
+ /* caller must initialize */
+ // zero_v3(f->no);
+ f->mat_nr = 0;
+ /* --- done --- */
- /* may add to middle of the pool */
- bm->elem_index_dirty |= BM_FACE;
- bm->elem_table_dirty |= BM_FACE;
+ /* may add to middle of the pool */
+ bm->elem_index_dirty |= BM_FACE;
+ bm->elem_table_dirty |= BM_FACE;
- bm->totface++;
+ bm->totface++;
#ifdef USE_BMESH_HOLES
- f->totbounds = 0;
+ f->totbounds = 0;
#endif
- return f;
+ return f;
}
/**
@@ -423,91 +420,97 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
* \param len: Length of the face
* \param create_flag: Options for creating the face
*/
-BMFace *BM_face_create(
- BMesh *bm, BMVert **verts, BMEdge **edges, const int len,
- const BMFace *f_example, const eBMCreateFlag create_flag)
+BMFace *BM_face_create(BMesh *bm,
+ BMVert **verts,
+ BMEdge **edges,
+ const int len,
+ const BMFace *f_example,
+ const eBMCreateFlag create_flag)
{
- BMFace *f = NULL;
- BMLoop *l, *startl, *lastl;
- int i;
-
- BLI_assert((f_example == NULL) || (f_example->head.htype == BM_FACE));
- BLI_assert(!(create_flag & 1));
-
- if (len == 0) {
- /* just return NULL for now */
- return NULL;
- }
-
- if (create_flag & BM_CREATE_NO_DOUBLE) {
- /* Check if face already exists */
- f = BM_face_exists(verts, len);
- if (f != NULL) {
- return f;
- }
- }
-
- f = bm_face_create__internal(bm);
-
- startl = lastl = bm_face_boundary_add(bm, f, verts[0], edges[0], create_flag);
-
- for (i = 1; i < len; i++) {
- l = bm_loop_create(bm, verts[i], edges[i], f, NULL /* edges[i]->l */, create_flag);
-
- bmesh_radial_loop_append(edges[i], l);
-
- l->prev = lastl;
- lastl->next = l;
- lastl = l;
- }
-
- startl->prev = lastl;
- lastl->next = startl;
-
- f->len = len;
-
- if (!(create_flag & BM_CREATE_SKIP_CD)) {
- if (f_example) {
- BM_elem_attrs_copy(bm, bm, f_example, f);
- }
- else {
- CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
- zero_v3(f->no);
- }
- }
- else {
- if (f_example) {
- copy_v3_v3(f->no, f_example->no);
- }
- else {
- zero_v3(f->no);
- }
- }
-
- BM_CHECK_ELEMENT(f);
-
- return f;
+ BMFace *f = NULL;
+ BMLoop *l, *startl, *lastl;
+ int i;
+
+ BLI_assert((f_example == NULL) || (f_example->head.htype == BM_FACE));
+ BLI_assert(!(create_flag & 1));
+
+ if (len == 0) {
+ /* just return NULL for now */
+ return NULL;
+ }
+
+ if (create_flag & BM_CREATE_NO_DOUBLE) {
+ /* Check if face already exists */
+ f = BM_face_exists(verts, len);
+ if (f != NULL) {
+ return f;
+ }
+ }
+
+ f = bm_face_create__internal(bm);
+
+ startl = lastl = bm_face_boundary_add(bm, f, verts[0], edges[0], create_flag);
+
+ for (i = 1; i < len; i++) {
+ l = bm_loop_create(bm, verts[i], edges[i], f, NULL /* edges[i]->l */, create_flag);
+
+ bmesh_radial_loop_append(edges[i], l);
+
+ l->prev = lastl;
+ lastl->next = l;
+ lastl = l;
+ }
+
+ startl->prev = lastl;
+ lastl->next = startl;
+
+ f->len = len;
+
+ if (!(create_flag & BM_CREATE_SKIP_CD)) {
+ if (f_example) {
+ BM_elem_attrs_copy(bm, bm, f_example, f);
+ }
+ else {
+ CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
+ zero_v3(f->no);
+ }
+ }
+ else {
+ if (f_example) {
+ copy_v3_v3(f->no, f_example->no);
+ }
+ else {
+ zero_v3(f->no);
+ }
+ }
+
+ BM_CHECK_ELEMENT(f);
+
+ return f;
}
/**
* Wrapper for #BM_face_create when you don't have an edge array
*/
-BMFace *BM_face_create_verts(
- BMesh *bm, BMVert **vert_arr, const int len,
- const BMFace *f_example, const eBMCreateFlag create_flag, const bool create_edges)
+BMFace *BM_face_create_verts(BMesh *bm,
+ BMVert **vert_arr,
+ const int len,
+ const BMFace *f_example,
+ const eBMCreateFlag create_flag,
+ const bool create_edges)
{
- BMEdge **edge_arr = BLI_array_alloca(edge_arr, len);
-
- if (create_edges) {
- BM_edges_from_verts_ensure(bm, edge_arr, vert_arr, len);
- }
- else {
- if (BM_edges_from_verts(edge_arr, vert_arr, len) == false) {
- return NULL;
- }
- }
-
- return BM_face_create(bm, vert_arr, edge_arr, len, f_example, create_flag);
+ BMEdge **edge_arr = BLI_array_alloca(edge_arr, len);
+
+ if (create_edges) {
+ BM_edges_from_verts_ensure(bm, edge_arr, vert_arr, len);
+ }
+ else {
+ if (BM_edges_from_verts(edge_arr, vert_arr, len) == false) {
+ return NULL;
+ }
+ }
+
+ return BM_face_create(bm, vert_arr, edge_arr, len, f_example, create_flag);
}
#ifndef NDEBUG
@@ -520,221 +523,217 @@ BMFace *BM_face_create_verts(
*/
int bmesh_elem_check(void *element, const char htype)
{
- BMHeader *head = element;
- enum {
- IS_NULL = (1 << 0),
- IS_WRONG_TYPE = (1 << 1),
-
- IS_VERT_WRONG_EDGE_TYPE = (1 << 2),
-
- IS_EDGE_NULL_DISK_LINK = (1 << 3),
- IS_EDGE_WRONG_LOOP_TYPE = (1 << 4),
- IS_EDGE_WRONG_FACE_TYPE = (1 << 5),
- IS_EDGE_NULL_RADIAL_LINK = (1 << 6),
- IS_EDGE_ZERO_FACE_LENGTH = (1 << 7),
-
- IS_LOOP_WRONG_FACE_TYPE = (1 << 8),
- IS_LOOP_WRONG_EDGE_TYPE = (1 << 9),
- IS_LOOP_WRONG_VERT_TYPE = (1 << 10),
- IS_LOOP_VERT_NOT_IN_EDGE = (1 << 11),
- IS_LOOP_NULL_CYCLE_LINK = (1 << 12),
- IS_LOOP_ZERO_FACE_LENGTH = (1 << 13),
- IS_LOOP_WRONG_FACE_LENGTH = (1 << 14),
- IS_LOOP_WRONG_RADIAL_LENGTH = (1 << 15),
-
- IS_FACE_NULL_LOOP = (1 << 16),
- IS_FACE_WRONG_LOOP_FACE = (1 << 17),
- IS_FACE_NULL_EDGE = (1 << 18),
- IS_FACE_NULL_VERT = (1 << 19),
- IS_FACE_LOOP_VERT_NOT_IN_EDGE = (1 << 20),
- IS_FACE_LOOP_WRONG_RADIAL_LENGTH = (1 << 21),
- IS_FACE_LOOP_WRONG_DISK_LENGTH = (1 << 22),
- IS_FACE_LOOP_DUPE_LOOP = (1 << 23),
- IS_FACE_LOOP_DUPE_VERT = (1 << 24),
- IS_FACE_LOOP_DUPE_EDGE = (1 << 25),
- IS_FACE_WRONG_LENGTH = (1 << 26),
- } err = 0;
-
- if (!element) {
- return IS_NULL;
- }
-
- if (head->htype != htype) {
- return IS_WRONG_TYPE;
- }
-
- switch (htype) {
- case BM_VERT:
- {
- BMVert *v = element;
- if (v->e && v->e->head.htype != BM_EDGE) {
- err |= IS_VERT_WRONG_EDGE_TYPE;
- }
- break;
- }
- case BM_EDGE:
- {
- BMEdge *e = element;
- if (e->v1_disk_link.prev == NULL ||
- e->v2_disk_link.prev == NULL ||
- e->v1_disk_link.next == NULL ||
- e->v2_disk_link.next == NULL)
- {
- err |= IS_EDGE_NULL_DISK_LINK;
- }
-
- if (e->l && e->l->head.htype != BM_LOOP) {
- err |= IS_EDGE_WRONG_LOOP_TYPE;
- }
- if (e->l && e->l->f->head.htype != BM_FACE) {
- err |= IS_EDGE_WRONG_FACE_TYPE;
- }
- if (e->l && (e->l->radial_next == NULL || e->l->radial_prev == NULL)) {
- err |= IS_EDGE_NULL_RADIAL_LINK;
- }
- if (e->l && e->l->f->len <= 0) {
- err |= IS_EDGE_ZERO_FACE_LENGTH;
- }
- break;
- }
- case BM_LOOP:
- {
- BMLoop *l = element, *l2;
- int i;
-
- if (l->f->head.htype != BM_FACE) {
- err |= IS_LOOP_WRONG_FACE_TYPE;
- }
- if (l->e->head.htype != BM_EDGE) {
- err |= IS_LOOP_WRONG_EDGE_TYPE;
- }
- if (l->v->head.htype != BM_VERT) {
- err |= IS_LOOP_WRONG_VERT_TYPE;
- }
- if (!BM_vert_in_edge(l->e, l->v)) {
- fprintf(stderr, "%s: fatal bmesh error (vert not in edge)! (bmesh internal error)\n", __func__);
- err |= IS_LOOP_VERT_NOT_IN_EDGE;
- }
-
- if (l->radial_next == NULL || l->radial_prev == NULL) {
- err |= IS_LOOP_NULL_CYCLE_LINK;
- }
- if (l->f->len <= 0) {
- err |= IS_LOOP_ZERO_FACE_LENGTH;
- }
-
- /* validate boundary loop -- invalid for hole loops, of course,
- * but we won't be allowing those for a while yet */
- l2 = l;
- i = 0;
- do {
- if (i >= BM_NGON_MAX) {
- break;
- }
-
- i++;
- } while ((l2 = l2->next) != l);
-
- if (i != l->f->len || l2 != l) {
- err |= IS_LOOP_WRONG_FACE_LENGTH;
- }
-
- if (!bmesh_radial_validate(bmesh_radial_length(l), l)) {
- err |= IS_LOOP_WRONG_RADIAL_LENGTH;
- }
-
- break;
- }
- case BM_FACE:
- {
- BMFace *f = element;
- BMLoop *l_iter;
- BMLoop *l_first;
- int len = 0;
-
-#ifdef USE_BMESH_HOLES
- if (!f->loops.first)
-#else
- if (!f->l_first)
-#endif
- {
- err |= IS_FACE_NULL_LOOP;
- }
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (l_iter->f != f) {
- fprintf(stderr, "%s: loop inside one face points to another! (bmesh internal error)\n", __func__);
- err |= IS_FACE_WRONG_LOOP_FACE;
- }
-
- if (!l_iter->e) {
- err |= IS_FACE_NULL_EDGE;
- }
- if (!l_iter->v) {
- err |= IS_FACE_NULL_VERT;
- }
- if (l_iter->e && l_iter->v) {
- if (!BM_vert_in_edge(l_iter->e, l_iter->v) ||
- !BM_vert_in_edge(l_iter->e, l_iter->next->v))
- {
- err |= IS_FACE_LOOP_VERT_NOT_IN_EDGE;
- }
-
- if (!bmesh_radial_validate(bmesh_radial_length(l_iter), l_iter)) {
- err |= IS_FACE_LOOP_WRONG_RADIAL_LENGTH;
- }
-
- if (bmesh_disk_count_at_most(l_iter->v, 2) < 2) {
- err |= IS_FACE_LOOP_WRONG_DISK_LENGTH;
- }
- }
-
- /* check for duplicates */
- if (BM_ELEM_API_FLAG_TEST(l_iter, _FLAG_ELEM_CHECK)) {
- err |= IS_FACE_LOOP_DUPE_LOOP;
- }
- BM_ELEM_API_FLAG_ENABLE(l_iter, _FLAG_ELEM_CHECK);
- if (l_iter->v) {
- if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_ELEM_CHECK)) {
- err |= IS_FACE_LOOP_DUPE_VERT;
- }
- BM_ELEM_API_FLAG_ENABLE(l_iter->v, _FLAG_ELEM_CHECK);
- }
- if (l_iter->e) {
- if (BM_ELEM_API_FLAG_TEST(l_iter->e, _FLAG_ELEM_CHECK)) {
- err |= IS_FACE_LOOP_DUPE_EDGE;
- }
- BM_ELEM_API_FLAG_ENABLE(l_iter->e, _FLAG_ELEM_CHECK);
- }
-
- len++;
- } while ((l_iter = l_iter->next) != l_first);
-
- /* cleanup duplicates flag */
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BM_ELEM_API_FLAG_DISABLE(l_iter, _FLAG_ELEM_CHECK);
- if (l_iter->v) {
- BM_ELEM_API_FLAG_DISABLE(l_iter->v, _FLAG_ELEM_CHECK);
- }
- if (l_iter->e) {
- BM_ELEM_API_FLAG_DISABLE(l_iter->e, _FLAG_ELEM_CHECK);
- }
- } while ((l_iter = l_iter->next) != l_first);
-
- if (len != f->len) {
- err |= IS_FACE_WRONG_LENGTH;
- }
- break;
- }
- default:
- BLI_assert(0);
- break;
- }
-
- BMESH_ASSERT(err == 0);
-
- return err;
+ BMHeader *head = element;
+ enum {
+ IS_NULL = (1 << 0),
+ IS_WRONG_TYPE = (1 << 1),
+
+ IS_VERT_WRONG_EDGE_TYPE = (1 << 2),
+
+ IS_EDGE_NULL_DISK_LINK = (1 << 3),
+ IS_EDGE_WRONG_LOOP_TYPE = (1 << 4),
+ IS_EDGE_WRONG_FACE_TYPE = (1 << 5),
+ IS_EDGE_NULL_RADIAL_LINK = (1 << 6),
+ IS_EDGE_ZERO_FACE_LENGTH = (1 << 7),
+
+ IS_LOOP_WRONG_FACE_TYPE = (1 << 8),
+ IS_LOOP_WRONG_EDGE_TYPE = (1 << 9),
+ IS_LOOP_WRONG_VERT_TYPE = (1 << 10),
+ IS_LOOP_VERT_NOT_IN_EDGE = (1 << 11),
+ IS_LOOP_NULL_CYCLE_LINK = (1 << 12),
+ IS_LOOP_ZERO_FACE_LENGTH = (1 << 13),
+ IS_LOOP_WRONG_FACE_LENGTH = (1 << 14),
+ IS_LOOP_WRONG_RADIAL_LENGTH = (1 << 15),
+
+ IS_FACE_NULL_LOOP = (1 << 16),
+ IS_FACE_WRONG_LOOP_FACE = (1 << 17),
+ IS_FACE_NULL_EDGE = (1 << 18),
+ IS_FACE_NULL_VERT = (1 << 19),
+ IS_FACE_LOOP_VERT_NOT_IN_EDGE = (1 << 20),
+ IS_FACE_LOOP_WRONG_RADIAL_LENGTH = (1 << 21),
+ IS_FACE_LOOP_WRONG_DISK_LENGTH = (1 << 22),
+ IS_FACE_LOOP_DUPE_LOOP = (1 << 23),
+ IS_FACE_LOOP_DUPE_VERT = (1 << 24),
+ IS_FACE_LOOP_DUPE_EDGE = (1 << 25),
+ IS_FACE_WRONG_LENGTH = (1 << 26),
+ } err = 0;
+
+ if (!element) {
+ return IS_NULL;
+ }
+
+ if (head->htype != htype) {
+ return IS_WRONG_TYPE;
+ }
+
+ switch (htype) {
+ case BM_VERT: {
+ BMVert *v = element;
+ if (v->e && v->e->head.htype != BM_EDGE) {
+ err |= IS_VERT_WRONG_EDGE_TYPE;
+ }
+ break;
+ }
+ case BM_EDGE: {
+ BMEdge *e = element;
+ if (e->v1_disk_link.prev == NULL || e->v2_disk_link.prev == NULL ||
+ e->v1_disk_link.next == NULL || e->v2_disk_link.next == NULL) {
+ err |= IS_EDGE_NULL_DISK_LINK;
+ }
+
+ if (e->l && e->l->head.htype != BM_LOOP) {
+ err |= IS_EDGE_WRONG_LOOP_TYPE;
+ }
+ if (e->l && e->l->f->head.htype != BM_FACE) {
+ err |= IS_EDGE_WRONG_FACE_TYPE;
+ }
+ if (e->l && (e->l->radial_next == NULL || e->l->radial_prev == NULL)) {
+ err |= IS_EDGE_NULL_RADIAL_LINK;
+ }
+ if (e->l && e->l->f->len <= 0) {
+ err |= IS_EDGE_ZERO_FACE_LENGTH;
+ }
+ break;
+ }
+ case BM_LOOP: {
+ BMLoop *l = element, *l2;
+ int i;
+
+ if (l->f->head.htype != BM_FACE) {
+ err |= IS_LOOP_WRONG_FACE_TYPE;
+ }
+ if (l->e->head.htype != BM_EDGE) {
+ err |= IS_LOOP_WRONG_EDGE_TYPE;
+ }
+ if (l->v->head.htype != BM_VERT) {
+ err |= IS_LOOP_WRONG_VERT_TYPE;
+ }
+ if (!BM_vert_in_edge(l->e, l->v)) {
+ fprintf(stderr,
+ "%s: fatal bmesh error (vert not in edge)! (bmesh internal error)\n",
+ __func__);
+ err |= IS_LOOP_VERT_NOT_IN_EDGE;
+ }
+
+ if (l->radial_next == NULL || l->radial_prev == NULL) {
+ err |= IS_LOOP_NULL_CYCLE_LINK;
+ }
+ if (l->f->len <= 0) {
+ err |= IS_LOOP_ZERO_FACE_LENGTH;
+ }
+
+ /* validate boundary loop -- invalid for hole loops, of course,
+ * but we won't be allowing those for a while yet */
+ l2 = l;
+ i = 0;
+ do {
+ if (i >= BM_NGON_MAX) {
+ break;
+ }
+
+ i++;
+ } while ((l2 = l2->next) != l);
+
+ if (i != l->f->len || l2 != l) {
+ err |= IS_LOOP_WRONG_FACE_LENGTH;
+ }
+
+ if (!bmesh_radial_validate(bmesh_radial_length(l), l)) {
+ err |= IS_LOOP_WRONG_RADIAL_LENGTH;
+ }
+
+ break;
+ }
+ case BM_FACE: {
+ BMFace *f = element;
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ int len = 0;
+
+# ifdef USE_BMESH_HOLES
+ if (!f->loops.first)
+# else
+ if (!f->l_first)
+# endif
+ {
+ err |= IS_FACE_NULL_LOOP;
+ }
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (l_iter->f != f) {
+ fprintf(stderr,
+ "%s: loop inside one face points to another! (bmesh internal error)\n",
+ __func__);
+ err |= IS_FACE_WRONG_LOOP_FACE;
+ }
+
+ if (!l_iter->e) {
+ err |= IS_FACE_NULL_EDGE;
+ }
+ if (!l_iter->v) {
+ err |= IS_FACE_NULL_VERT;
+ }
+ if (l_iter->e && l_iter->v) {
+ if (!BM_vert_in_edge(l_iter->e, l_iter->v) ||
+ !BM_vert_in_edge(l_iter->e, l_iter->next->v)) {
+ err |= IS_FACE_LOOP_VERT_NOT_IN_EDGE;
+ }
+
+ if (!bmesh_radial_validate(bmesh_radial_length(l_iter), l_iter)) {
+ err |= IS_FACE_LOOP_WRONG_RADIAL_LENGTH;
+ }
+
+ if (bmesh_disk_count_at_most(l_iter->v, 2) < 2) {
+ err |= IS_FACE_LOOP_WRONG_DISK_LENGTH;
+ }
+ }
+
+ /* check for duplicates */
+ if (BM_ELEM_API_FLAG_TEST(l_iter, _FLAG_ELEM_CHECK)) {
+ err |= IS_FACE_LOOP_DUPE_LOOP;
+ }
+ BM_ELEM_API_FLAG_ENABLE(l_iter, _FLAG_ELEM_CHECK);
+ if (l_iter->v) {
+ if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_ELEM_CHECK)) {
+ err |= IS_FACE_LOOP_DUPE_VERT;
+ }
+ BM_ELEM_API_FLAG_ENABLE(l_iter->v, _FLAG_ELEM_CHECK);
+ }
+ if (l_iter->e) {
+ if (BM_ELEM_API_FLAG_TEST(l_iter->e, _FLAG_ELEM_CHECK)) {
+ err |= IS_FACE_LOOP_DUPE_EDGE;
+ }
+ BM_ELEM_API_FLAG_ENABLE(l_iter->e, _FLAG_ELEM_CHECK);
+ }
+
+ len++;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ /* cleanup duplicates flag */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_ELEM_API_FLAG_DISABLE(l_iter, _FLAG_ELEM_CHECK);
+ if (l_iter->v) {
+ BM_ELEM_API_FLAG_DISABLE(l_iter->v, _FLAG_ELEM_CHECK);
+ }
+ if (l_iter->e) {
+ BM_ELEM_API_FLAG_DISABLE(l_iter->e, _FLAG_ELEM_CHECK);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (len != f->len) {
+ err |= IS_FACE_WRONG_LENGTH;
+ }
+ break;
+ }
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ BMESH_ASSERT(err == 0);
+
+ return err;
}
#endif /* NDEBUG */
@@ -745,20 +744,20 @@ int bmesh_elem_check(void *element, const char htype)
*/
static void bm_kill_only_vert(BMesh *bm, BMVert *v)
{
- bm->totvert--;
- bm->elem_index_dirty |= BM_VERT;
- bm->elem_table_dirty |= BM_VERT;
+ bm->totvert--;
+ bm->elem_index_dirty |= BM_VERT;
+ bm->elem_table_dirty |= BM_VERT;
- BM_select_history_remove(bm, v);
+ BM_select_history_remove(bm, v);
- if (v->head.data) {
- CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
- }
+ if (v->head.data) {
+ CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
+ }
- if (bm->vtoolflagpool) {
- BLI_mempool_free(bm->vtoolflagpool, ((BMVert_OFlag *)v)->oflags);
- }
- BLI_mempool_free(bm->vpool, v);
+ if (bm->vtoolflagpool) {
+ BLI_mempool_free(bm->vtoolflagpool, ((BMVert_OFlag *)v)->oflags);
+ }
+ BLI_mempool_free(bm->vpool, v);
}
/**
@@ -767,20 +766,20 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v)
*/
static void bm_kill_only_edge(BMesh *bm, BMEdge *e)
{
- bm->totedge--;
- bm->elem_index_dirty |= BM_EDGE;
- bm->elem_table_dirty |= BM_EDGE;
+ bm->totedge--;
+ bm->elem_index_dirty |= BM_EDGE;
+ bm->elem_table_dirty |= BM_EDGE;
- BM_select_history_remove(bm, (BMElem *)e);
+ BM_select_history_remove(bm, (BMElem *)e);
- if (e->head.data) {
- CustomData_bmesh_free_block(&bm->edata, &e->head.data);
- }
+ if (e->head.data) {
+ CustomData_bmesh_free_block(&bm->edata, &e->head.data);
+ }
- if (bm->etoolflagpool) {
- BLI_mempool_free(bm->etoolflagpool, ((BMEdge_OFlag *)e)->oflags);
- }
- BLI_mempool_free(bm->epool, e);
+ if (bm->etoolflagpool) {
+ BLI_mempool_free(bm->etoolflagpool, ((BMEdge_OFlag *)e)->oflags);
+ }
+ BLI_mempool_free(bm->epool, e);
}
/**
@@ -789,24 +788,24 @@ static void bm_kill_only_edge(BMesh *bm, BMEdge *e)
*/
static void bm_kill_only_face(BMesh *bm, BMFace *f)
{
- if (bm->act_face == f) {
- bm->act_face = NULL;
- }
+ if (bm->act_face == f) {
+ bm->act_face = NULL;
+ }
- bm->totface--;
- bm->elem_index_dirty |= BM_FACE;
- bm->elem_table_dirty |= BM_FACE;
+ bm->totface--;
+ bm->elem_index_dirty |= BM_FACE;
+ bm->elem_table_dirty |= BM_FACE;
- BM_select_history_remove(bm, (BMElem *)f);
+ BM_select_history_remove(bm, (BMElem *)f);
- if (f->head.data) {
- CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
- }
+ if (f->head.data) {
+ CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
+ }
- if (bm->ftoolflagpool) {
- BLI_mempool_free(bm->ftoolflagpool, ((BMFace_OFlag *)f)->oflags);
- }
- BLI_mempool_free(bm->fpool, f);
+ if (bm->ftoolflagpool) {
+ BLI_mempool_free(bm->ftoolflagpool, ((BMFace_OFlag *)f)->oflags);
+ }
+ BLI_mempool_free(bm->fpool, f);
}
/**
@@ -815,13 +814,13 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f)
*/
static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
{
- bm->totloop--;
- bm->elem_index_dirty |= BM_LOOP;
- if (l->head.data) {
- CustomData_bmesh_free_block(&bm->ldata, &l->head.data);
- }
+ bm->totloop--;
+ bm->elem_index_dirty |= BM_LOOP;
+ if (l->head.data) {
+ CustomData_bmesh_free_block(&bm->ldata, &l->head.data);
+ }
- BLI_mempool_free(bm->lpool, l);
+ BLI_mempool_free(bm->lpool, l);
}
/**
@@ -830,19 +829,19 @@ static void bm_kill_only_loop(BMesh *bm, BMLoop *l)
*/
void BM_face_edges_kill(BMesh *bm, BMFace *f)
{
- BMEdge **edges = BLI_array_alloca(edges, f->len);
- BMLoop *l_iter;
- BMLoop *l_first;
- int i = 0;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- edges[i++] = l_iter->e;
- } while ((l_iter = l_iter->next) != l_first);
-
- for (i = 0; i < f->len; i++) {
- BM_edge_kill(bm, edges[i]);
- }
+ BMEdge **edges = BLI_array_alloca(edges, f->len);
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ int i = 0;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ edges[i++] = l_iter->e;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ for (i = 0; i < f->len; i++) {
+ BM_edge_kill(bm, edges[i]);
+ }
}
/**
@@ -851,19 +850,19 @@ void BM_face_edges_kill(BMesh *bm, BMFace *f)
*/
void BM_face_verts_kill(BMesh *bm, BMFace *f)
{
- BMVert **verts = BLI_array_alloca(verts, f->len);
- BMLoop *l_iter;
- BMLoop *l_first;
- int i = 0;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- verts[i++] = l_iter->v;
- } while ((l_iter = l_iter->next) != l_first);
-
- for (i = 0; i < f->len; i++) {
- BM_vert_kill(bm, verts[i]);
- }
+ BMVert **verts = BLI_array_alloca(verts, f->len);
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ int i = 0;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ verts[i++] = l_iter->v;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ for (i = 0; i < f->len; i++) {
+ BM_vert_kill(bm, verts[i]);
+ }
}
/**
@@ -872,45 +871,45 @@ void BM_face_verts_kill(BMesh *bm, BMFace *f)
void BM_face_kill(BMesh *bm, BMFace *f)
{
#ifdef USE_BMESH_HOLES
- BMLoopList *ls, *ls_next;
+ BMLoopList *ls, *ls_next;
#endif
#ifdef NDEBUG
- /* check length since we may be removing degenerate faces */
- if (f->len >= 3) {
- BM_CHECK_ELEMENT(f);
- }
+ /* check length since we may be removing degenerate faces */
+ if (f->len >= 3) {
+ BM_CHECK_ELEMENT(f);
+ }
#endif
#ifdef USE_BMESH_HOLES
- for (ls = f->loops.first; ls; ls = ls_next)
+ for (ls = f->loops.first; ls; ls = ls_next)
#else
- if (f->l_first)
+ if (f->l_first)
#endif
- {
- BMLoop *l_iter, *l_next, *l_first;
+ {
+ BMLoop *l_iter, *l_next, *l_first;
#ifdef USE_BMESH_HOLES
- ls_next = ls->next;
- l_iter = l_first = ls->first;
+ ls_next = ls->next;
+ l_iter = l_first = ls->first;
#else
- l_iter = l_first = f->l_first;
+ l_iter = l_first = f->l_first;
#endif
- do {
- l_next = l_iter->next;
+ do {
+ l_next = l_iter->next;
- bmesh_radial_loop_remove(l_iter->e, l_iter);
- bm_kill_only_loop(bm, l_iter);
+ bmesh_radial_loop_remove(l_iter->e, l_iter);
+ bm_kill_only_loop(bm, l_iter);
- } while ((l_iter = l_next) != l_first);
+ } while ((l_iter = l_next) != l_first);
#ifdef USE_BMESH_HOLES
- BLI_mempool_free(bm->looplistpool, ls);
+ BLI_mempool_free(bm->looplistpool, ls);
#endif
- }
+ }
- bm_kill_only_face(bm, f);
+ bm_kill_only_face(bm, f);
}
/**
@@ -920,56 +919,56 @@ void BM_face_kill(BMesh *bm, BMFace *f)
void BM_face_kill_loose(BMesh *bm, BMFace *f)
{
#ifdef USE_BMESH_HOLES
- BMLoopList *ls, *ls_next;
+ BMLoopList *ls, *ls_next;
#endif
- BM_CHECK_ELEMENT(f);
+ BM_CHECK_ELEMENT(f);
#ifdef USE_BMESH_HOLES
- for (ls = f->loops.first; ls; ls = ls_next)
+ for (ls = f->loops.first; ls; ls = ls_next)
#else
- if (f->l_first)
+ if (f->l_first)
#endif
- {
- BMLoop *l_iter, *l_next, *l_first;
+ {
+ BMLoop *l_iter, *l_next, *l_first;
#ifdef USE_BMESH_HOLES
- ls_next = ls->next;
- l_iter = l_first = ls->first;
+ ls_next = ls->next;
+ l_iter = l_first = ls->first;
#else
- l_iter = l_first = f->l_first;
+ l_iter = l_first = f->l_first;
#endif
- do {
- BMEdge *e;
- l_next = l_iter->next;
+ do {
+ BMEdge *e;
+ l_next = l_iter->next;
- e = l_iter->e;
- bmesh_radial_loop_remove(e, l_iter);
- bm_kill_only_loop(bm, l_iter);
+ e = l_iter->e;
+ bmesh_radial_loop_remove(e, l_iter);
+ bm_kill_only_loop(bm, l_iter);
- if (e->l == NULL) {
- BMVert *v1 = e->v1, *v2 = e->v2;
+ if (e->l == NULL) {
+ BMVert *v1 = e->v1, *v2 = e->v2;
- bmesh_disk_edge_remove(e, e->v1);
- bmesh_disk_edge_remove(e, e->v2);
- bm_kill_only_edge(bm, e);
+ bmesh_disk_edge_remove(e, e->v1);
+ bmesh_disk_edge_remove(e, e->v2);
+ bm_kill_only_edge(bm, e);
- if (v1->e == NULL) {
- bm_kill_only_vert(bm, v1);
- }
- if (v2->e == NULL) {
- bm_kill_only_vert(bm, v2);
- }
- }
- } while ((l_iter = l_next) != l_first);
+ if (v1->e == NULL) {
+ bm_kill_only_vert(bm, v1);
+ }
+ if (v2->e == NULL) {
+ bm_kill_only_vert(bm, v2);
+ }
+ }
+ } while ((l_iter = l_next) != l_first);
#ifdef USE_BMESH_HOLES
- BLI_mempool_free(bm->looplistpool, ls);
+ BLI_mempool_free(bm->looplistpool, ls);
#endif
- }
+ }
- bm_kill_only_face(bm, f);
+ bm_kill_only_face(bm, f);
}
/**
@@ -977,14 +976,14 @@ void BM_face_kill_loose(BMesh *bm, BMFace *f)
*/
void BM_edge_kill(BMesh *bm, BMEdge *e)
{
- while (e->l) {
- BM_face_kill(bm, e->l->f);
- }
+ while (e->l) {
+ BM_face_kill(bm, e->l->f);
+ }
- bmesh_disk_edge_remove(e, e->v1);
- bmesh_disk_edge_remove(e, e->v2);
+ bmesh_disk_edge_remove(e, e->v1);
+ bmesh_disk_edge_remove(e, e->v2);
- bm_kill_only_edge(bm, e);
+ bm_kill_only_edge(bm, e);
}
/**
@@ -992,11 +991,11 @@ void BM_edge_kill(BMesh *bm, BMEdge *e)
*/
void BM_vert_kill(BMesh *bm, BMVert *v)
{
- while (v->e) {
- BM_edge_kill(bm, v->e);
- }
+ while (v->e) {
+ BM_edge_kill(bm, v->e);
+ }
- bm_kill_only_vert(bm, v);
+ bm_kill_only_vert(bm, v);
}
/********** private disk and radial cycle functions ********** */
@@ -1006,14 +1005,14 @@ void BM_vert_kill(BMesh *bm, BMVert *v)
*/
static int UNUSED_FUNCTION(bm_loop_length)(BMLoop *l)
{
- BMLoop *l_first = l;
- int i = 0;
+ BMLoop *l_first = l;
+ int i = 0;
- do {
- i++;
- } while ((l = l->next) != l_first);
+ do {
+ i++;
+ } while ((l = l->next) != l_first);
- return i;
+ return i;
}
/**
@@ -1025,126 +1024,127 @@ static int UNUSED_FUNCTION(bm_loop_length)(BMLoop *l)
* \param use_loop_mdisp_flip: When set, flip the Z-depth of the mdisp,
* (use when flipping normals, disable when mirroring, eg: symmetrize).
*/
-void bmesh_kernel_loop_reverse(
- BMesh *bm, BMFace *f,
- const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
+void bmesh_kernel_loop_reverse(BMesh *bm,
+ BMFace *f,
+ const int cd_loop_mdisp_offset,
+ const bool use_loop_mdisp_flip)
{
- BMLoop *l_first = f->l_first;
+ BMLoop *l_first = f->l_first;
- /* track previous cycles radial state */
- BMEdge *e_prev = l_first->prev->e;
- BMLoop *l_prev_radial_next = l_first->prev->radial_next;
- BMLoop *l_prev_radial_prev = l_first->prev->radial_prev;
- bool is_prev_boundary = l_prev_radial_next == l_prev_radial_next->radial_next;
+ /* track previous cycles radial state */
+ BMEdge *e_prev = l_first->prev->e;
+ BMLoop *l_prev_radial_next = l_first->prev->radial_next;
+ BMLoop *l_prev_radial_prev = l_first->prev->radial_prev;
+ bool is_prev_boundary = l_prev_radial_next == l_prev_radial_next->radial_next;
- BMLoop *l_iter = l_first;
- do {
- BMEdge *e_iter = l_iter->e;
- BMLoop *l_iter_radial_next = l_iter->radial_next;
- BMLoop *l_iter_radial_prev = l_iter->radial_prev;
- bool is_iter_boundary = l_iter_radial_next == l_iter_radial_next->radial_next;
+ BMLoop *l_iter = l_first;
+ do {
+ BMEdge *e_iter = l_iter->e;
+ BMLoop *l_iter_radial_next = l_iter->radial_next;
+ BMLoop *l_iter_radial_prev = l_iter->radial_prev;
+ bool is_iter_boundary = l_iter_radial_next == l_iter_radial_next->radial_next;
#if 0
- bmesh_radial_loop_remove(e_iter, l_iter);
- bmesh_radial_loop_append(e_prev, l_iter);
+ bmesh_radial_loop_remove(e_iter, l_iter);
+ bmesh_radial_loop_append(e_prev, l_iter);
#else
- /* inline loop reversal */
- if (is_prev_boundary) {
- /* boundary */
- l_iter->radial_next = l_iter;
- l_iter->radial_prev = l_iter;
- }
- else {
- /* non-boundary, replace radial links */
- l_iter->radial_next = l_prev_radial_next;
- l_iter->radial_prev = l_prev_radial_prev;
- l_prev_radial_next->radial_prev = l_iter;
- l_prev_radial_prev->radial_next = l_iter;
- }
-
- if (e_iter->l == l_iter) {
- e_iter->l = l_iter->next;
- }
- l_iter->e = e_prev;
+ /* inline loop reversal */
+ if (is_prev_boundary) {
+ /* boundary */
+ l_iter->radial_next = l_iter;
+ l_iter->radial_prev = l_iter;
+ }
+ else {
+ /* non-boundary, replace radial links */
+ l_iter->radial_next = l_prev_radial_next;
+ l_iter->radial_prev = l_prev_radial_prev;
+ l_prev_radial_next->radial_prev = l_iter;
+ l_prev_radial_prev->radial_next = l_iter;
+ }
+
+ if (e_iter->l == l_iter) {
+ e_iter->l = l_iter->next;
+ }
+ l_iter->e = e_prev;
#endif
- SWAP(BMLoop *, l_iter->next, l_iter->prev);
+ SWAP(BMLoop *, l_iter->next, l_iter->prev);
- if (cd_loop_mdisp_offset != -1) {
- MDisps *md = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset);
- BKE_mesh_mdisp_flip(md, use_loop_mdisp_flip);
- }
+ if (cd_loop_mdisp_offset != -1) {
+ MDisps *md = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset);
+ BKE_mesh_mdisp_flip(md, use_loop_mdisp_flip);
+ }
- e_prev = e_iter;
- l_prev_radial_next = l_iter_radial_next;
- l_prev_radial_prev = l_iter_radial_prev;
- is_prev_boundary = is_iter_boundary;
+ e_prev = e_iter;
+ l_prev_radial_next = l_iter_radial_next;
+ l_prev_radial_prev = l_iter_radial_prev;
+ is_prev_boundary = is_iter_boundary;
- /* step to next (now swapped) */
- } while ((l_iter = l_iter->prev) != l_first);
+ /* step to next (now swapped) */
+ } while ((l_iter = l_iter->prev) != l_first);
#ifndef NDEBUG
- /* validate radial */
- int i;
- for (i = 0, l_iter = l_first; i < f->len; i++, l_iter = l_iter->next) {
- BM_CHECK_ELEMENT(l_iter);
- BM_CHECK_ELEMENT(l_iter->e);
- BM_CHECK_ELEMENT(l_iter->v);
- BM_CHECK_ELEMENT(l_iter->f);
- }
-
- BM_CHECK_ELEMENT(f);
+ /* validate radial */
+ int i;
+ for (i = 0, l_iter = l_first; i < f->len; i++, l_iter = l_iter->next) {
+ BM_CHECK_ELEMENT(l_iter);
+ BM_CHECK_ELEMENT(l_iter->e);
+ BM_CHECK_ELEMENT(l_iter->v);
+ BM_CHECK_ELEMENT(l_iter->f);
+ }
+
+ BM_CHECK_ELEMENT(f);
#endif
- /* Loop indices are no more valid! */
- bm->elem_index_dirty |= BM_LOOP;
+ /* Loop indices are no more valid! */
+ bm->elem_index_dirty |= BM_LOOP;
}
static void bm_elements_systag_enable(void *veles, int tot, const char api_flag)
{
- BMHeader **eles = veles;
- int i;
+ BMHeader **eles = veles;
+ int i;
- for (i = 0; i < tot; i++) {
- BM_ELEM_API_FLAG_ENABLE((BMElemF *)eles[i], api_flag);
- }
+ for (i = 0; i < tot; i++) {
+ BM_ELEM_API_FLAG_ENABLE((BMElemF *)eles[i], api_flag);
+ }
}
static void bm_elements_systag_disable(void *veles, int tot, const char api_flag)
{
- BMHeader **eles = veles;
- int i;
+ BMHeader **eles = veles;
+ int i;
- for (i = 0; i < tot; i++) {
- BM_ELEM_API_FLAG_DISABLE((BMElemF *)eles[i], api_flag);
- }
+ for (i = 0; i < tot; i++) {
+ BM_ELEM_API_FLAG_DISABLE((BMElemF *)eles[i], api_flag);
+ }
}
static int bm_loop_systag_count_radial(BMLoop *l, const char api_flag)
{
- BMLoop *l_iter = l;
- int i = 0;
- do {
- i += BM_ELEM_API_FLAG_TEST(l_iter->f, api_flag) ? 1 : 0;
- } while ((l_iter = l_iter->radial_next) != l);
+ BMLoop *l_iter = l;
+ int i = 0;
+ do {
+ i += BM_ELEM_API_FLAG_TEST(l_iter->f, api_flag) ? 1 : 0;
+ } while ((l_iter = l_iter->radial_next) != l);
- return i;
+ return i;
}
static int UNUSED_FUNCTION(bm_vert_systag_count_disk)(BMVert *v, const char api_flag)
{
- BMEdge *e = v->e;
- int i = 0;
+ BMEdge *e = v->e;
+ int i = 0;
- if (!e) {
- return 0;
- }
+ if (!e) {
+ return 0;
+ }
- do {
- i += BM_ELEM_API_FLAG_TEST(e, api_flag) ? 1 : 0;
- } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
+ do {
+ i += BM_ELEM_API_FLAG_TEST(e, api_flag) ? 1 : 0;
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
- return i;
+ return i;
}
/**
@@ -1153,31 +1153,31 @@ static int UNUSED_FUNCTION(bm_vert_systag_count_disk)(BMVert *v, const char api_
*/
static bool bm_vert_is_manifold_flagged(BMVert *v, const char api_flag)
{
- BMEdge *e = v->e;
+ BMEdge *e = v->e;
- if (!e) {
- return false;
- }
+ if (!e) {
+ return false;
+ }
- do {
- BMLoop *l = e->l;
+ do {
+ BMLoop *l = e->l;
- if (!l) {
- return false;
- }
+ if (!l) {
+ return false;
+ }
- if (BM_edge_is_boundary(l->e)) {
- return false;
- }
+ if (BM_edge_is_boundary(l->e)) {
+ return false;
+ }
- do {
- if (!BM_ELEM_API_FLAG_TEST(l->f, api_flag)) {
- return false;
- }
- } while ((l = l->radial_next) != e->l);
- } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
+ do {
+ if (!BM_ELEM_API_FLAG_TEST(l->f, api_flag)) {
+ return false;
+ }
+ } while ((l = l->radial_next) != e->l);
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
- return true;
+ return true;
}
/* Mid-level Topology Manipulation Functions */
@@ -1198,216 +1198,218 @@ static bool bm_vert_is_manifold_flagged(BMVert *v, const char api_flag)
*/
BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del)
{
- BMFace *f, *f_new;
+ BMFace *f, *f_new;
#ifdef USE_BMESH_HOLES
- BMLoopList *lst;
- ListBase holes = {NULL, NULL};
+ BMLoopList *lst;
+ ListBase holes = {NULL, NULL};
#endif
- BMLoop *l_iter;
- BMLoop *l_first;
- BMEdge **edges = NULL;
- BMEdge **deledges = NULL;
- BMVert **delverts = NULL;
- BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
- BLI_array_staticdeclare(deledges, BM_DEFAULT_NGON_STACK_SIZE);
- BLI_array_staticdeclare(delverts, BM_DEFAULT_NGON_STACK_SIZE);
- BMVert *v1 = NULL, *v2 = NULL;
- int i;
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
-
- if (UNLIKELY(!totface)) {
- BMESH_ASSERT(0);
- return NULL;
- }
-
- if (totface == 1) {
- return faces[0];
- }
-
- bm_elements_systag_enable(faces, totface, _FLAG_JF);
-
- for (i = 0; i < totface; i++) {
- f = faces[i];
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- int rlen = bm_loop_systag_count_radial(l_iter, _FLAG_JF);
-
- if (rlen > 2) {
- /* Input faces do not form a contiguous manifold region */
- goto error;
- }
- else if (rlen == 1) {
- BLI_array_append(edges, l_iter->e);
-
- if (!v1) {
- v1 = l_iter->v;
- v2 = BM_edge_other_vert(l_iter->e, l_iter->v);
- }
- }
- else if (rlen == 2) {
- const bool d1 = bm_vert_is_manifold_flagged(l_iter->e->v1, _FLAG_JF);
- const bool d2 = bm_vert_is_manifold_flagged(l_iter->e->v2, _FLAG_JF);
-
- if (!d1 && !d2 && !BM_ELEM_API_FLAG_TEST(l_iter->e, _FLAG_JF)) {
- /* don't remove an edge it makes up the side of another face
- * else this will remove the face as well - campbell */
- if (!BM_edge_face_count_is_over(l_iter->e, 2)) {
- if (do_del) {
- BLI_array_append(deledges, l_iter->e);
- }
- BM_ELEM_API_FLAG_ENABLE(l_iter->e, _FLAG_JF);
- }
- }
- else {
- if (d1 && !BM_ELEM_API_FLAG_TEST(l_iter->e->v1, _FLAG_JF)) {
- if (do_del) {
- BLI_array_append(delverts, l_iter->e->v1);
- }
- BM_ELEM_API_FLAG_ENABLE(l_iter->e->v1, _FLAG_JF);
- }
-
- if (d2 && !BM_ELEM_API_FLAG_TEST(l_iter->e->v2, _FLAG_JF)) {
- if (do_del) {
- BLI_array_append(delverts, l_iter->e->v2);
- }
- BM_ELEM_API_FLAG_ENABLE(l_iter->e->v2, _FLAG_JF);
- }
- }
- }
- } while ((l_iter = l_iter->next) != l_first);
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ BMEdge **edges = NULL;
+ BMEdge **deledges = NULL;
+ BMVert **delverts = NULL;
+ BLI_array_staticdeclare(edges, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(deledges, BM_DEFAULT_NGON_STACK_SIZE);
+ BLI_array_staticdeclare(delverts, BM_DEFAULT_NGON_STACK_SIZE);
+ BMVert *v1 = NULL, *v2 = NULL;
+ int i;
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+
+ if (UNLIKELY(!totface)) {
+ BMESH_ASSERT(0);
+ return NULL;
+ }
+
+ if (totface == 1) {
+ return faces[0];
+ }
+
+ bm_elements_systag_enable(faces, totface, _FLAG_JF);
+
+ for (i = 0; i < totface; i++) {
+ f = faces[i];
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ int rlen = bm_loop_systag_count_radial(l_iter, _FLAG_JF);
+
+ if (rlen > 2) {
+ /* Input faces do not form a contiguous manifold region */
+ goto error;
+ }
+ else if (rlen == 1) {
+ BLI_array_append(edges, l_iter->e);
+
+ if (!v1) {
+ v1 = l_iter->v;
+ v2 = BM_edge_other_vert(l_iter->e, l_iter->v);
+ }
+ }
+ else if (rlen == 2) {
+ const bool d1 = bm_vert_is_manifold_flagged(l_iter->e->v1, _FLAG_JF);
+ const bool d2 = bm_vert_is_manifold_flagged(l_iter->e->v2, _FLAG_JF);
+
+ if (!d1 && !d2 && !BM_ELEM_API_FLAG_TEST(l_iter->e, _FLAG_JF)) {
+ /* don't remove an edge it makes up the side of another face
+ * else this will remove the face as well - campbell */
+ if (!BM_edge_face_count_is_over(l_iter->e, 2)) {
+ if (do_del) {
+ BLI_array_append(deledges, l_iter->e);
+ }
+ BM_ELEM_API_FLAG_ENABLE(l_iter->e, _FLAG_JF);
+ }
+ }
+ else {
+ if (d1 && !BM_ELEM_API_FLAG_TEST(l_iter->e->v1, _FLAG_JF)) {
+ if (do_del) {
+ BLI_array_append(delverts, l_iter->e->v1);
+ }
+ BM_ELEM_API_FLAG_ENABLE(l_iter->e->v1, _FLAG_JF);
+ }
+
+ if (d2 && !BM_ELEM_API_FLAG_TEST(l_iter->e->v2, _FLAG_JF)) {
+ if (do_del) {
+ BLI_array_append(delverts, l_iter->e->v2);
+ }
+ BM_ELEM_API_FLAG_ENABLE(l_iter->e->v2, _FLAG_JF);
+ }
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_first);
#ifdef USE_BMESH_HOLES
- for (lst = f->loops.first; lst; lst = lst->next) {
- if (lst == f->loops.first) {
- continue;
- }
-
- BLI_remlink(&f->loops, lst);
- BLI_addtail(&holes, lst);
- }
+ for (lst = f->loops.first; lst; lst = lst->next) {
+ if (lst == f->loops.first) {
+ continue;
+ }
+
+ BLI_remlink(&f->loops, lst);
+ BLI_addtail(&holes, lst);
+ }
#endif
-
- }
-
- /* create region face */
- f_new = BLI_array_len(edges) ?
- BM_face_create_ngon(bm, v1, v2, edges, BLI_array_len(edges), faces[0], BM_CREATE_NOP) : NULL;
- if (UNLIKELY(f_new == NULL)) {
- /* Invalid boundary region to join faces */
- goto error;
- }
-
- /* copy over loop data */
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
- do {
- BMLoop *l2 = l_iter->radial_next;
-
- do {
- if (BM_ELEM_API_FLAG_TEST(l2->f, _FLAG_JF)) {
- break;
- }
- l2 = l2->radial_next;
- } while (l2 != l_iter);
-
- if (l2 != l_iter) {
- /* loops share an edge, shared vert depends on winding */
- if (l2->v != l_iter->v) {
- l2 = l2->next;
- }
- BLI_assert(l_iter->v == l2->v);
-
- BM_elem_attrs_copy(bm, bm, l2, l_iter);
- }
- } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ /* create region face */
+ f_new = BLI_array_len(edges) ?
+ BM_face_create_ngon(
+ bm, v1, v2, edges, BLI_array_len(edges), faces[0], BM_CREATE_NOP) :
+ NULL;
+ if (UNLIKELY(f_new == NULL)) {
+ /* Invalid boundary region to join faces */
+ goto error;
+ }
+
+ /* copy over loop data */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
+ do {
+ BMLoop *l2 = l_iter->radial_next;
+
+ do {
+ if (BM_ELEM_API_FLAG_TEST(l2->f, _FLAG_JF)) {
+ break;
+ }
+ l2 = l2->radial_next;
+ } while (l2 != l_iter);
+
+ if (l2 != l_iter) {
+ /* loops share an edge, shared vert depends on winding */
+ if (l2->v != l_iter->v) {
+ l2 = l2->next;
+ }
+ BLI_assert(l_iter->v == l2->v);
+
+ BM_elem_attrs_copy(bm, bm, l2, l_iter);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
#ifdef USE_BMESH_HOLES
- /* add holes */
- BLI_movelisttolist(&f_new->loops, &holes);
-
- /* update loop face pointer */
- for (lst = f_new->loops.first; lst; lst = lst->next) {
- l_iter = l_first = lst->first;
- do {
- l_iter->f = f_new;
- } while ((l_iter = l_iter->next) != l_first);
- }
+ /* add holes */
+ BLI_movelisttolist(&f_new->loops, &holes);
+
+ /* update loop face pointer */
+ for (lst = f_new->loops.first; lst; lst = lst->next) {
+ l_iter = l_first = lst->first;
+ do {
+ l_iter->f = f_new;
+ } while ((l_iter = l_iter->next) != l_first);
+ }
#endif
- bm_elements_systag_disable(faces, totface, _FLAG_JF);
- BM_ELEM_API_FLAG_DISABLE(f_new, _FLAG_JF);
-
- /* handle multi-res data */
- if (cd_loop_mdisp_offset != -1) {
- float f_center[3];
- float (*faces_center)[3] = BLI_array_alloca(faces_center, totface);
-
- BM_face_calc_center_median(f_new, f_center);
- for (i = 0; i < totface; i++) {
- BM_face_calc_center_median(faces[i], faces_center[i]);
- }
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
- do {
- for (i = 0; i < totface; i++) {
- BM_loop_interp_multires_ex(bm, l_iter, faces[i], f_center, faces_center[i], cd_loop_mdisp_offset);
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
-
- /* delete old geometry */
- if (do_del) {
- for (i = 0; i < BLI_array_len(deledges); i++) {
- BM_edge_kill(bm, deledges[i]);
- }
-
- for (i = 0; i < BLI_array_len(delverts); i++) {
- BM_vert_kill(bm, delverts[i]);
- }
- }
- else {
- /* otherwise we get both old and new faces */
- for (i = 0; i < totface; i++) {
- BM_face_kill(bm, faces[i]);
- }
- }
-
- BLI_array_free(edges);
- BLI_array_free(deledges);
- BLI_array_free(delverts);
-
- BM_CHECK_ELEMENT(f_new);
- return f_new;
+ bm_elements_systag_disable(faces, totface, _FLAG_JF);
+ BM_ELEM_API_FLAG_DISABLE(f_new, _FLAG_JF);
+
+ /* handle multi-res data */
+ if (cd_loop_mdisp_offset != -1) {
+ float f_center[3];
+ float(*faces_center)[3] = BLI_array_alloca(faces_center, totface);
+
+ BM_face_calc_center_median(f_new, f_center);
+ for (i = 0; i < totface; i++) {
+ BM_face_calc_center_median(faces[i], faces_center[i]);
+ }
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
+ do {
+ for (i = 0; i < totface; i++) {
+ BM_loop_interp_multires_ex(
+ bm, l_iter, faces[i], f_center, faces_center[i], cd_loop_mdisp_offset);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ /* delete old geometry */
+ if (do_del) {
+ for (i = 0; i < BLI_array_len(deledges); i++) {
+ BM_edge_kill(bm, deledges[i]);
+ }
+
+ for (i = 0; i < BLI_array_len(delverts); i++) {
+ BM_vert_kill(bm, delverts[i]);
+ }
+ }
+ else {
+ /* otherwise we get both old and new faces */
+ for (i = 0; i < totface; i++) {
+ BM_face_kill(bm, faces[i]);
+ }
+ }
+
+ BLI_array_free(edges);
+ BLI_array_free(deledges);
+ BLI_array_free(delverts);
+
+ BM_CHECK_ELEMENT(f_new);
+ return f_new;
error:
- bm_elements_systag_disable(faces, totface, _FLAG_JF);
- BLI_array_free(edges);
- BLI_array_free(deledges);
- BLI_array_free(delverts);
+ bm_elements_systag_disable(faces, totface, _FLAG_JF);
+ BLI_array_free(edges);
+ BLI_array_free(deledges);
+ BLI_array_free(delverts);
- return NULL;
+ return NULL;
}
static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *f_example)
{
- BMFace *f;
+ BMFace *f;
#ifdef USE_BMESH_HOLES
- BMLoopList *lst;
+ BMLoopList *lst;
#endif
- f = bm_face_create__internal(bm);
+ f = bm_face_create__internal(bm);
#ifdef USE_BMESH_HOLES
- lst = BLI_mempool_calloc(bm->looplistpool);
- BLI_addtail(&f->loops, lst);
+ lst = BLI_mempool_calloc(bm->looplistpool);
+ BLI_addtail(&f->loops, lst);
#endif
#ifdef USE_BMESH_HOLES
- f->totbounds = 1;
+ f->totbounds = 1;
#endif
- BM_elem_attrs_copy(bm, bm, f_example, f);
+ BM_elem_attrs_copy(bm, bm, f_example, f);
- return f;
+ return f;
}
/**
@@ -1447,141 +1449,143 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *f_example)
*
* \return A BMFace pointer
*/
-BMFace *bmesh_kernel_split_face_make_edge(
- BMesh *bm, BMFace *f, BMLoop *l_v1, BMLoop *l_v2,
- BMLoop **r_l,
+BMFace *bmesh_kernel_split_face_make_edge(BMesh *bm,
+ BMFace *f,
+ BMLoop *l_v1,
+ BMLoop *l_v2,
+ BMLoop **r_l,
#ifdef USE_BMESH_HOLES
- ListBase *holes,
+ ListBase *holes,
#endif
- BMEdge *e_example,
- const bool no_double)
+ BMEdge *e_example,
+ const bool no_double)
{
#ifdef USE_BMESH_HOLES
- BMLoopList *lst, *lst2;
+ BMLoopList *lst, *lst2;
#else
- int first_loop_f1;
+ int first_loop_f1;
#endif
- BMFace *f2;
- BMLoop *l_iter, *l_first;
- BMLoop *l_f1 = NULL, *l_f2 = NULL;
- BMEdge *e;
- BMVert *v1 = l_v1->v, *v2 = l_v2->v;
- int f1len, f2len;
+ BMFace *f2;
+ BMLoop *l_iter, *l_first;
+ BMLoop *l_f1 = NULL, *l_f2 = NULL;
+ BMEdge *e;
+ BMVert *v1 = l_v1->v, *v2 = l_v2->v;
+ int f1len, f2len;
- BLI_assert(f == l_v1->f && f == l_v2->f);
+ BLI_assert(f == l_v1->f && f == l_v2->f);
- /* allocate new edge between v1 and v2 */
- e = BM_edge_create(bm, v1, v2, e_example, no_double ? BM_CREATE_NO_DOUBLE : BM_CREATE_NOP);
+ /* allocate new edge between v1 and v2 */
+ e = BM_edge_create(bm, v1, v2, e_example, no_double ? BM_CREATE_NO_DOUBLE : BM_CREATE_NOP);
- f2 = bm_face_create__sfme(bm, f);
- l_f1 = bm_loop_create(bm, v2, e, f, l_v2, 0);
- l_f2 = bm_loop_create(bm, v1, e, f2, l_v1, 0);
+ f2 = bm_face_create__sfme(bm, f);
+ l_f1 = bm_loop_create(bm, v2, e, f, l_v2, 0);
+ l_f2 = bm_loop_create(bm, v1, e, f2, l_v1, 0);
- l_f1->prev = l_v2->prev;
- l_f2->prev = l_v1->prev;
- l_v2->prev->next = l_f1;
- l_v1->prev->next = l_f2;
+ l_f1->prev = l_v2->prev;
+ l_f2->prev = l_v1->prev;
+ l_v2->prev->next = l_f1;
+ l_v1->prev->next = l_f2;
- l_f1->next = l_v1;
- l_f2->next = l_v2;
- l_v1->prev = l_f1;
- l_v2->prev = l_f2;
+ 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;
+ lst = f->loops.first;
+ lst2 = f2->loops.first;
- lst2->first = lst2->last = l_f2;
- lst->first = lst->last = l_f1;
+ 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 = l_f1;
- first_loop_f1 = 0;
- do {
- if (l_iter == f->l_first) {
- first_loop_f1 = 1;
- }
- } while ((l_iter = l_iter->next) != l_first);
-
- if (first_loop_f1) {
- /* 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 == 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 = 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 == 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 = l_f1;
- }
- }
+ /* find which of the faces the original first loop is in */
+ l_iter = l_first = l_f1;
+ first_loop_f1 = 0;
+ do {
+ if (l_iter == f->l_first) {
+ first_loop_f1 = 1;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (first_loop_f1) {
+ /* 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 == 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 = 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 == 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 = l_f1;
+ }
+ }
#endif
- /* validate both loop */
- /* I don't know how many loops are supposed to be in each face at this point! FIXME */
+ /* validate both loop */
+ /* I don't know how many loops are supposed to be in each face at this point! FIXME */
- /* go through all of f2's loops and make sure they point to it properly */
- l_iter = l_first = BM_FACE_FIRST_LOOP(f2);
- f2len = 0;
- do {
- l_iter->f = f2;
- f2len++;
- } while ((l_iter = l_iter->next) != l_first);
+ /* go through all of f2's loops and make sure they point to it properly */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f2);
+ f2len = 0;
+ do {
+ l_iter->f = f2;
+ f2len++;
+ } while ((l_iter = l_iter->next) != l_first);
- /* link up the new loops into the new edges radial */
- bmesh_radial_loop_append(e, l_f1);
- bmesh_radial_loop_append(e, l_f2);
+ /* link up the new loops into the new edges radial */
+ bmesh_radial_loop_append(e, l_f1);
+ bmesh_radial_loop_append(e, l_f2);
- f2->len = f2len;
+ f2->len = f2len;
- f1len = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- f1len++;
- } while ((l_iter = l_iter->next) != l_first);
+ f1len = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ f1len++;
+ } while ((l_iter = l_iter->next) != l_first);
- f->len = f1len;
+ f->len = f1len;
- if (r_l) {
- *r_l = l_f2;
- }
+ if (r_l) {
+ *r_l = l_f2;
+ }
#ifdef USE_BMESH_HOLES
- if (holes) {
- BLI_movelisttolist(&f2->loops, holes);
- }
- else {
- /* this code is not significant until holes actually work */
- //printf("warning: call to split face euler without holes argument; holes will be tossed.\n");
- for (lst = f->loops.last; lst != f->loops.first; lst = lst2) {
- lst2 = lst->prev;
- BLI_mempool_free(bm->looplistpool, lst);
- }
- }
+ if (holes) {
+ BLI_movelisttolist(&f2->loops, holes);
+ }
+ else {
+ /* this code is not significant until holes actually work */
+ //printf("warning: call to split face euler without holes argument; holes will be tossed.\n");
+ for (lst = f->loops.last; lst != f->loops.first; lst = lst2) {
+ lst2 = lst->prev;
+ BLI_mempool_free(bm->looplistpool, lst);
+ }
+ }
#endif
- BM_CHECK_ELEMENT(e);
- BM_CHECK_ELEMENT(f);
- BM_CHECK_ELEMENT(f2);
+ BM_CHECK_ELEMENT(e);
+ BM_CHECK_ELEMENT(f);
+ BM_CHECK_ELEMENT(f2);
- return f2;
+ return f2;
}
/**
@@ -1604,156 +1608,155 @@ BMFace *bmesh_kernel_split_face_make_edge(
*/
BMVert *bmesh_kernel_split_edge_make_vert(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
{
- BMLoop *l_next;
- BMEdge *e_new;
- BMVert *v_new, *v_old;
+ BMLoop *l_next;
+ BMEdge *e_new;
+ BMVert *v_new, *v_old;
#ifndef NDEBUG
- int valence1, valence2;
- bool edok;
- int i;
+ int valence1, valence2;
+ bool edok;
+ int i;
#endif
- BLI_assert(BM_vert_in_edge(e, tv) != false);
+ BLI_assert(BM_vert_in_edge(e, tv) != false);
- v_old = BM_edge_other_vert(e, tv);
+ v_old = BM_edge_other_vert(e, tv);
#ifndef NDEBUG
- valence1 = bmesh_disk_count(v_old);
- valence2 = bmesh_disk_count(tv);
+ valence1 = bmesh_disk_count(v_old);
+ valence2 = bmesh_disk_count(tv);
#endif
- /* order of 'e_new' verts should match 'e'
- * (so extruded faces don't flip) */
- v_new = BM_vert_create(bm, tv->co, tv, BM_CREATE_NOP);
- e_new = BM_edge_create(bm, tv, v_new, e, BM_CREATE_NOP);
+ /* order of 'e_new' verts should match 'e'
+ * (so extruded faces don't flip) */
+ v_new = BM_vert_create(bm, tv->co, tv, BM_CREATE_NOP);
+ e_new = BM_edge_create(bm, tv, v_new, e, BM_CREATE_NOP);
- bmesh_disk_edge_remove(e_new, tv);
- bmesh_disk_edge_remove(e_new, v_new);
+ bmesh_disk_edge_remove(e_new, tv);
+ bmesh_disk_edge_remove(e_new, v_new);
- bmesh_disk_vert_replace(e, v_new, tv);
+ bmesh_disk_vert_replace(e, v_new, tv);
- /* add e_new to v_new's disk cycle */
- bmesh_disk_edge_append(e_new, v_new);
+ /* add e_new to v_new's disk cycle */
+ bmesh_disk_edge_append(e_new, v_new);
- /* add e_new to tv's disk cycle */
- bmesh_disk_edge_append(e_new, tv);
+ /* add e_new to tv's disk cycle */
+ bmesh_disk_edge_append(e_new, tv);
#ifndef NDEBUG
- /* verify disk cycles */
- 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, v_new->e, v_new);
- BMESH_ASSERT(edok != false);
+ /* verify disk cycles */
+ 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, v_new->e, v_new);
+ BMESH_ASSERT(edok != false);
#endif
- /* Split the radial cycle if present */
- l_next = e->l;
- e->l = NULL;
- if (l_next) {
- BMLoop *l_new, *l;
+ /* Split the radial cycle if present */
+ l_next = e->l;
+ e->l = NULL;
+ if (l_next) {
+ BMLoop *l_new, *l;
#ifndef NDEBUG
- int radlen = bmesh_radial_length(l_next);
+ int radlen = bmesh_radial_length(l_next);
#endif
- bool is_first = true;
-
- /* Take the next loop. Remove it from radial. Split it. Append to appropriate radials */
- while (l_next) {
- l = l_next;
- l->f->len++;
- l_next = l_next != l_next->radial_next ? l_next->radial_next : NULL;
- bmesh_radial_loop_unlink(l);
-
- 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 (BM_verts_in_edge(l_new->v, l_new->next->v, e)) {
- l_new->e = e;
- l->e = e_new;
-
- /* append l into e_new's rad cycle */
- if (is_first) {
- is_first = false;
- l->radial_next = l->radial_prev = NULL;
- }
-
- bmesh_radial_loop_append(l_new->e, l_new);
- bmesh_radial_loop_append(l->e, l);
- }
- else if (BM_verts_in_edge(l_new->v, l_new->next->v, e_new)) {
- l_new->e = e_new;
- l->e = e;
-
- /* append l into e_new's rad cycle */
- if (is_first) {
- is_first = false;
- l->radial_next = l->radial_prev = NULL;
- }
-
- bmesh_radial_loop_append(l_new->e, l_new);
- bmesh_radial_loop_append(l->e, l);
- }
-
- }
+ bool is_first = true;
+
+ /* Take the next loop. Remove it from radial. Split it. Append to appropriate radials */
+ while (l_next) {
+ l = l_next;
+ l->f->len++;
+ l_next = l_next != l_next->radial_next ? l_next->radial_next : NULL;
+ bmesh_radial_loop_unlink(l);
+
+ 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 (BM_verts_in_edge(l_new->v, l_new->next->v, e)) {
+ l_new->e = e;
+ l->e = e_new;
+
+ /* append l into e_new's rad cycle */
+ if (is_first) {
+ is_first = false;
+ l->radial_next = l->radial_prev = NULL;
+ }
+
+ bmesh_radial_loop_append(l_new->e, l_new);
+ bmesh_radial_loop_append(l->e, l);
+ }
+ else if (BM_verts_in_edge(l_new->v, l_new->next->v, e_new)) {
+ l_new->e = e_new;
+ l->e = e;
+
+ /* append l into e_new's rad cycle */
+ if (is_first) {
+ is_first = false;
+ l->radial_next = l->radial_prev = NULL;
+ }
+
+ bmesh_radial_loop_append(l_new->e, l_new);
+ bmesh_radial_loop_append(l->e, l);
+ }
+ }
#ifndef NDEBUG
- /* verify length of radial cycle */
- edok = bmesh_radial_validate(radlen, e->l);
- BMESH_ASSERT(edok != false);
- 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 != e_new && l->next->e != e_new));
-
- edok = BM_verts_in_edge(l->v, l->next->v, e);
- BMESH_ASSERT(edok != false);
- BMESH_ASSERT(l->v != l->next->v);
- BMESH_ASSERT(l->e != l->next->e);
-
- /* verify loop cycle for kloop->f */
- BM_CHECK_ELEMENT(l);
- BM_CHECK_ELEMENT(l->v);
- BM_CHECK_ELEMENT(l->e);
- BM_CHECK_ELEMENT(l->f);
- }
- /* 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 = BM_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);
-
- BM_CHECK_ELEMENT(l);
- BM_CHECK_ELEMENT(l->v);
- BM_CHECK_ELEMENT(l->e);
- BM_CHECK_ELEMENT(l->f);
- }
+ /* verify length of radial cycle */
+ edok = bmesh_radial_validate(radlen, e->l);
+ BMESH_ASSERT(edok != false);
+ 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 != e_new && l->next->e != e_new));
+
+ edok = BM_verts_in_edge(l->v, l->next->v, e);
+ BMESH_ASSERT(edok != false);
+ BMESH_ASSERT(l->v != l->next->v);
+ BMESH_ASSERT(l->e != l->next->e);
+
+ /* verify loop cycle for kloop->f */
+ BM_CHECK_ELEMENT(l);
+ BM_CHECK_ELEMENT(l->v);
+ BM_CHECK_ELEMENT(l->e);
+ BM_CHECK_ELEMENT(l->f);
+ }
+ /* 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 = BM_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);
+
+ BM_CHECK_ELEMENT(l);
+ BM_CHECK_ELEMENT(l->v);
+ BM_CHECK_ELEMENT(l->e);
+ BM_CHECK_ELEMENT(l->f);
+ }
#endif
- }
-
- 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 = e_new;
- }
- return v_new;
+ }
+
+ 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 = e_new;
+ }
+ return v_new;
}
/**
@@ -1786,153 +1789,154 @@ BMVert *bmesh_kernel_split_edge_make_vert(BMesh *bm, BMVert *tv, BMEdge *e, BMEd
* faces with just 2 edges. It is up to the caller to decide what to do with
* these faces.
*/
-BMEdge *bmesh_kernel_join_edge_kill_vert(
- BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
- const bool do_del, const bool check_edge_double,
- const bool kill_degenerate_faces)
+BMEdge *bmesh_kernel_join_edge_kill_vert(BMesh *bm,
+ BMEdge *e_kill,
+ BMVert *v_kill,
+ const bool do_del,
+ const bool check_edge_double,
+ const bool kill_degenerate_faces)
{
- BMEdge *e_old;
- BMVert *v_old, *v_target;
- BMLoop *l_kill;
+ BMEdge *e_old;
+ BMVert *v_old, *v_target;
+ BMLoop *l_kill;
#ifndef NDEBUG
- int radlen, i;
- bool edok;
+ int radlen, i;
+ bool edok;
#endif
- BLI_assert(BM_vert_in_edge(e_kill, v_kill));
+ BLI_assert(BM_vert_in_edge(e_kill, v_kill));
- if (BM_vert_in_edge(e_kill, v_kill) == 0) {
- return NULL;
- }
+ if (BM_vert_in_edge(e_kill, v_kill) == 0) {
+ return NULL;
+ }
- if (bmesh_disk_count_at_most(v_kill, 3) == 2) {
+ if (bmesh_disk_count_at_most(v_kill, 3) == 2) {
#ifndef NDEBUG
- int valence1, valence2;
- BMLoop *l;
+ int valence1, valence2;
+ BMLoop *l;
#endif
- e_old = bmesh_disk_edge_next(e_kill, v_kill);
- v_target = BM_edge_other_vert(e_kill, v_kill);
- v_old = BM_edge_other_vert(e_old, v_kill);
+ e_old = bmesh_disk_edge_next(e_kill, v_kill);
+ v_target = BM_edge_other_vert(e_kill, v_kill);
+ v_old = BM_edge_other_vert(e_old, v_kill);
- /* check for double edges */
- if (BM_verts_in_edge(v_kill, v_target, e_old)) {
- return NULL;
- }
- else {
- BMEdge *e_splice;
- BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *);
- BMLoop *l_kill_next;
+ /* check for double edges */
+ if (BM_verts_in_edge(v_kill, v_target, e_old)) {
+ return NULL;
+ }
+ else {
+ BMEdge *e_splice;
+ BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *);
+ BMLoop *l_kill_next;
#ifndef NDEBUG
- /* For verification later, count valence of 'v_old' and 'v_target' */
- valence1 = bmesh_disk_count(v_old);
- valence2 = bmesh_disk_count(v_target);
+ /* For verification later, count valence of 'v_old' and 'v_target' */
+ valence1 = bmesh_disk_count(v_old);
+ valence2 = bmesh_disk_count(v_target);
#endif
- if (check_edge_double) {
- e_splice = BM_edge_exists(v_target, v_old);
- }
+ if (check_edge_double) {
+ e_splice = BM_edge_exists(v_target, v_old);
+ }
- bmesh_disk_vert_replace(e_old, v_target, v_kill);
+ bmesh_disk_vert_replace(e_old, v_target, v_kill);
- /* remove e_kill from 'v_target's disk cycle */
- bmesh_disk_edge_remove(e_kill, v_target);
+ /* remove e_kill from 'v_target's disk cycle */
+ bmesh_disk_edge_remove(e_kill, v_target);
#ifndef NDEBUG
- /* deal with radial cycle of e_kill */
- radlen = bmesh_radial_length(e_kill->l);
+ /* deal with radial cycle of e_kill */
+ radlen = bmesh_radial_length(e_kill->l);
#endif
- if (e_kill->l) {
-
-
- /* fix the neighboring loops of all loops in e_kill's radial cycle */
- l_kill = e_kill->l;
- do {
- /* relink loops and fix vertex pointer */
- if (l_kill->next->v == v_kill) {
- l_kill->next->v = v_target;
- }
-
- 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;
- }
-
- /* fix len attribute of face */
- l_kill->f->len--;
- if (kill_degenerate_faces) {
- if (l_kill->f->len < 3) {
- BLI_SMALLSTACK_PUSH(faces_degenerate, l_kill->f);
- }
- }
- l_kill_next = l_kill->radial_next;
-
- bm_kill_only_loop(bm, l_kill);
-
- } while ((l_kill = l_kill_next) != e_kill->l);
- /* `e_kill->l` is invalid but the edge is freed next. */
+ if (e_kill->l) {
+
+ /* fix the neighboring loops of all loops in e_kill's radial cycle */
+ l_kill = e_kill->l;
+ do {
+ /* relink loops and fix vertex pointer */
+ if (l_kill->next->v == v_kill) {
+ l_kill->next->v = v_target;
+ }
+
+ 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;
+ }
+
+ /* fix len attribute of face */
+ l_kill->f->len--;
+ if (kill_degenerate_faces) {
+ if (l_kill->f->len < 3) {
+ BLI_SMALLSTACK_PUSH(faces_degenerate, l_kill->f);
+ }
+ }
+ l_kill_next = l_kill->radial_next;
+
+ bm_kill_only_loop(bm, l_kill);
+
+ } while ((l_kill = l_kill_next) != e_kill->l);
+ /* `e_kill->l` is invalid but the edge is freed next. */
#ifndef NDEBUG
- /* Validate radial cycle of e_old */
- edok = bmesh_radial_validate(radlen, e_old->l);
- BMESH_ASSERT(edok != false);
+ /* Validate radial cycle of e_old */
+ edok = bmesh_radial_validate(radlen, e_old->l);
+ BMESH_ASSERT(edok != false);
#endif
- }
- /* deallocate edge */
- bm_kill_only_edge(bm, e_kill);
-
- /* deallocate vertex */
- if (do_del) {
- bm_kill_only_vert(bm, v_kill);
- }
- else {
- v_kill->e = NULL;
- }
+ }
+ /* deallocate edge */
+ bm_kill_only_edge(bm, e_kill);
+
+ /* deallocate vertex */
+ if (do_del) {
+ bm_kill_only_vert(bm, v_kill);
+ }
+ else {
+ v_kill->e = NULL;
+ }
#ifndef NDEBUG
- /* Validate disk cycle lengths of 'v_old', 'v_target' are unchanged */
- edok = bmesh_disk_validate(valence1, v_old->e, v_old);
- BMESH_ASSERT(edok != false);
- edok = bmesh_disk_validate(valence2, v_target->e, v_target);
- BMESH_ASSERT(edok != false);
-
- /* 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 = BM_verts_in_edge(l->v, l->next->v, e_old);
- BMESH_ASSERT(edok != false);
- edok = bmesh_loop_validate(l->f);
- BMESH_ASSERT(edok != false);
-
- BM_CHECK_ELEMENT(l);
- BM_CHECK_ELEMENT(l->v);
- BM_CHECK_ELEMENT(l->e);
- BM_CHECK_ELEMENT(l->f);
- }
+ /* Validate disk cycle lengths of 'v_old', 'v_target' are unchanged */
+ edok = bmesh_disk_validate(valence1, v_old->e, v_old);
+ BMESH_ASSERT(edok != false);
+ edok = bmesh_disk_validate(valence2, v_target->e, v_target);
+ BMESH_ASSERT(edok != false);
+
+ /* 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 = BM_verts_in_edge(l->v, l->next->v, e_old);
+ BMESH_ASSERT(edok != false);
+ edok = bmesh_loop_validate(l->f);
+ BMESH_ASSERT(edok != false);
+
+ BM_CHECK_ELEMENT(l);
+ BM_CHECK_ELEMENT(l->v);
+ BM_CHECK_ELEMENT(l->e);
+ BM_CHECK_ELEMENT(l->f);
+ }
#endif
- if (check_edge_double) {
- if (e_splice) {
- /* removes e_splice */
- BM_edge_splice(bm, e_old, e_splice);
- }
- }
-
- if (kill_degenerate_faces) {
- BMFace *f_kill;
- while ((f_kill = BLI_SMALLSTACK_POP(faces_degenerate))) {
- BM_face_kill(bm, f_kill);
- }
- }
-
- BM_CHECK_ELEMENT(v_old);
- BM_CHECK_ELEMENT(v_target);
- BM_CHECK_ELEMENT(e_old);
-
- return e_old;
- }
- }
- return NULL;
+ if (check_edge_double) {
+ if (e_splice) {
+ /* removes e_splice */
+ BM_edge_splice(bm, e_old, e_splice);
+ }
+ }
+
+ if (kill_degenerate_faces) {
+ BMFace *f_kill;
+ while ((f_kill = BLI_SMALLSTACK_POP(faces_degenerate))) {
+ BM_face_kill(bm, f_kill);
+ }
+ }
+
+ BM_CHECK_ELEMENT(v_old);
+ BM_CHECK_ELEMENT(v_target);
+ BM_CHECK_ELEMENT(e_old);
+
+ return e_old;
+ }
+ }
+ return NULL;
}
/**
@@ -1952,85 +1956,87 @@ BMEdge *bmesh_kernel_join_edge_kill_vert(
* +-+-+-+ +-+-+-+
* </pre>
*/
-BMVert *bmesh_kernel_join_vert_kill_edge(
- BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
- const bool do_del, const bool check_edge_double,
- const bool kill_degenerate_faces)
+BMVert *bmesh_kernel_join_vert_kill_edge(BMesh *bm,
+ BMEdge *e_kill,
+ BMVert *v_kill,
+ const bool do_del,
+ const bool check_edge_double,
+ const bool kill_degenerate_faces)
{
- BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *);
- BMVert *v_target = BM_edge_other_vert(e_kill, v_kill);
-
- BLI_assert(BM_vert_in_edge(e_kill, v_kill));
-
- if (e_kill->l) {
- BMLoop *l_kill, *l_first, *l_kill_next;
- l_kill = l_first = e_kill->l;
- do {
- /* relink loops and fix vertex pointer */
- if (l_kill->next->v == v_kill) {
- l_kill->next->v = v_target;
- }
-
- 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;
- }
-
- /* fix len attribute of face */
- l_kill->f->len--;
- if (kill_degenerate_faces) {
- if (l_kill->f->len < 3) {
- BLI_SMALLSTACK_PUSH(faces_degenerate, l_kill->f);
- }
- }
- l_kill_next = l_kill->radial_next;
-
- bm_kill_only_loop(bm, l_kill);
-
- } while ((l_kill = l_kill_next) != l_first);
-
- e_kill->l = NULL;
- }
-
- BM_edge_kill(bm, e_kill);
- BM_CHECK_ELEMENT(v_kill);
- BM_CHECK_ELEMENT(v_target);
-
- if (v_target->e && v_kill->e) {
- /* inline BM_vert_splice(bm, v_target, v_kill); */
- BMEdge *e;
- while ((e = v_kill->e)) {
- BMEdge *e_target;
-
- if (check_edge_double) {
- e_target = BM_edge_exists(v_target, BM_edge_other_vert(e, v_kill));
- }
-
- bmesh_edge_vert_swap(e, v_target, v_kill);
- BLI_assert(e->v1 != e->v2);
-
- if (check_edge_double) {
- if (e_target) {
- BM_edge_splice(bm, e_target, e);
- }
- }
- }
- }
-
- if (kill_degenerate_faces) {
- BMFace *f_kill;
- while ((f_kill = BLI_SMALLSTACK_POP(faces_degenerate))) {
- BM_face_kill(bm, f_kill);
- }
- }
-
- if (do_del) {
- BLI_assert(v_kill->e == NULL);
- bm_kill_only_vert(bm, v_kill);
- }
-
- return v_target;
+ BLI_SMALLSTACK_DECLARE(faces_degenerate, BMFace *);
+ BMVert *v_target = BM_edge_other_vert(e_kill, v_kill);
+
+ BLI_assert(BM_vert_in_edge(e_kill, v_kill));
+
+ if (e_kill->l) {
+ BMLoop *l_kill, *l_first, *l_kill_next;
+ l_kill = l_first = e_kill->l;
+ do {
+ /* relink loops and fix vertex pointer */
+ if (l_kill->next->v == v_kill) {
+ l_kill->next->v = v_target;
+ }
+
+ 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;
+ }
+
+ /* fix len attribute of face */
+ l_kill->f->len--;
+ if (kill_degenerate_faces) {
+ if (l_kill->f->len < 3) {
+ BLI_SMALLSTACK_PUSH(faces_degenerate, l_kill->f);
+ }
+ }
+ l_kill_next = l_kill->radial_next;
+
+ bm_kill_only_loop(bm, l_kill);
+
+ } while ((l_kill = l_kill_next) != l_first);
+
+ e_kill->l = NULL;
+ }
+
+ BM_edge_kill(bm, e_kill);
+ BM_CHECK_ELEMENT(v_kill);
+ BM_CHECK_ELEMENT(v_target);
+
+ if (v_target->e && v_kill->e) {
+ /* inline BM_vert_splice(bm, v_target, v_kill); */
+ BMEdge *e;
+ while ((e = v_kill->e)) {
+ BMEdge *e_target;
+
+ if (check_edge_double) {
+ e_target = BM_edge_exists(v_target, BM_edge_other_vert(e, v_kill));
+ }
+
+ bmesh_edge_vert_swap(e, v_target, v_kill);
+ BLI_assert(e->v1 != e->v2);
+
+ if (check_edge_double) {
+ if (e_target) {
+ BM_edge_splice(bm, e_target, e);
+ }
+ }
+ }
+ }
+
+ if (kill_degenerate_faces) {
+ BMFace *f_kill;
+ while ((f_kill = BLI_SMALLSTACK_POP(faces_degenerate))) {
+ BM_face_kill(bm, f_kill);
+ }
+ }
+
+ if (do_del) {
+ BLI_assert(v_kill->e == NULL);
+ bm_kill_only_vert(bm, v_kill);
+ }
+
+ return v_target;
}
/**
@@ -2066,129 +2072,124 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
*/
BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
{
- 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;
- }
-
- /* validate that edge is 2-manifold edge */
- if (!BM_edge_is_manifold(e)) {
- return NULL;
- }
-
- /* verify that e is in both f1 and f2 */
- f1len = f1->len;
- f2len = f2->len;
-
- 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 (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 (BM_edge_in_face(l_f1->next->e, f2) ||
- BM_edge_in_face(l_f1->prev->e, f2) ||
- BM_edge_in_face(l_f2->next->e, f1) ||
- BM_edge_in_face(l_f2->prev->e, f1) )
- {
- return NULL;
- }
-
- /* validate only one shared edge */
- if (BM_face_share_edge_count(f1, f2) > 1) {
- return NULL;
- }
-
- /* validate no internal join */
- {
- bool is_dupe = false;
-
- /* TODO: skip clearing once this is ensured. */
- for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
- BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
- }
-
- for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
- BM_elem_flag_set(l_iter->v, BM_ELEM_INTERNAL_TAG, l_iter != l_f1);
- }
- for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
- 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)) {
- is_dupe = true;
- break;
- }
- }
- }
- /* Cleanup tags. */
- for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
- BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
- }
- if (is_dupe) {
- return NULL;
- }
- }
-
- /* join the two loop */
- l_f1->prev->next = l_f2->next;
- l_f2->next->prev = l_f1->prev;
-
- l_f1->next->prev = l_f2->prev;
- l_f2->prev->next = l_f1->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);
-
- /* make sure each loop points to the proper face */
- newlen = f1->len;
- for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < newlen; i++, l_iter = l_iter->next) {
- l_iter->f = f1;
- }
-
- /* remove edge from the disk cycle of its two vertices */
- 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, ((BMEdge_OFlag *)l_f1->e)->oflags);
- }
- BLI_mempool_free(bm->epool, l_f1->e);
- bm->totedge--;
- BLI_mempool_free(bm->lpool, l_f1);
- bm->totloop--;
- BLI_mempool_free(bm->lpool, l_f2);
- bm->totloop--;
- if (bm->ftoolflagpool) {
- BLI_mempool_free(bm->ftoolflagpool, ((BMFace_OFlag *)f2)->oflags);
- }
- BLI_mempool_free(bm->fpool, f2);
- bm->totface--;
- /* account for both above */
- bm->elem_index_dirty |= BM_EDGE | BM_LOOP | BM_FACE;
-
- BM_CHECK_ELEMENT(f1);
-
- /* validate the new loop cycle */
- edok = bmesh_loop_validate(f1);
- BMESH_ASSERT(edok != false);
-
- return f1;
+ 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;
+ }
+
+ /* validate that edge is 2-manifold edge */
+ if (!BM_edge_is_manifold(e)) {
+ return NULL;
+ }
+
+ /* verify that e is in both f1 and f2 */
+ f1len = f1->len;
+ f2len = f2->len;
+
+ 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 (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 (BM_edge_in_face(l_f1->next->e, f2) || BM_edge_in_face(l_f1->prev->e, f2) ||
+ BM_edge_in_face(l_f2->next->e, f1) || BM_edge_in_face(l_f2->prev->e, f1)) {
+ return NULL;
+ }
+
+ /* validate only one shared edge */
+ if (BM_face_share_edge_count(f1, f2) > 1) {
+ return NULL;
+ }
+
+ /* validate no internal join */
+ {
+ bool is_dupe = false;
+
+ /* TODO: skip clearing once this is ensured. */
+ for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
+ BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
+ }
+
+ for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
+ BM_elem_flag_set(l_iter->v, BM_ELEM_INTERNAL_TAG, l_iter != l_f1);
+ }
+ for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f2); i < f2len; i++, l_iter = l_iter->next) {
+ 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)) {
+ is_dupe = true;
+ break;
+ }
+ }
+ }
+ /* Cleanup tags. */
+ for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < f1len; i++, l_iter = l_iter->next) {
+ BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
+ }
+ if (is_dupe) {
+ return NULL;
+ }
+ }
+
+ /* join the two loop */
+ l_f1->prev->next = l_f2->next;
+ l_f2->next->prev = l_f1->prev;
+
+ l_f1->next->prev = l_f2->prev;
+ l_f2->prev->next = l_f1->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);
+
+ /* make sure each loop points to the proper face */
+ newlen = f1->len;
+ for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f1); i < newlen; i++, l_iter = l_iter->next) {
+ l_iter->f = f1;
+ }
+
+ /* remove edge from the disk cycle of its two vertices */
+ 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, ((BMEdge_OFlag *)l_f1->e)->oflags);
+ }
+ BLI_mempool_free(bm->epool, l_f1->e);
+ bm->totedge--;
+ BLI_mempool_free(bm->lpool, l_f1);
+ bm->totloop--;
+ BLI_mempool_free(bm->lpool, l_f2);
+ bm->totloop--;
+ if (bm->ftoolflagpool) {
+ BLI_mempool_free(bm->ftoolflagpool, ((BMFace_OFlag *)f2)->oflags);
+ }
+ BLI_mempool_free(bm->fpool, f2);
+ bm->totface--;
+ /* account for both above */
+ bm->elem_index_dirty |= BM_EDGE | BM_LOOP | BM_FACE;
+
+ BM_CHECK_ELEMENT(f1);
+
+ /* validate the new loop cycle */
+ edok = bmesh_loop_validate(f1);
+ BMESH_ASSERT(edok != false);
+
+ return f1;
}
/**
@@ -2198,46 +2199,45 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd
*/
bool BM_vert_splice_check_double(BMVert *v_a, BMVert *v_b)
{
- bool is_double = false;
+ bool is_double = false;
- BLI_assert(BM_edge_exists(v_a, v_b) == false);
+ BLI_assert(BM_edge_exists(v_a, v_b) == false);
- if (v_a->e && v_b->e) {
- BMEdge *e, *e_first;
+ if (v_a->e && v_b->e) {
+ BMEdge *e, *e_first;
#define VERT_VISIT _FLAG_WALK
- /* tag 'v_a' */
- e = e_first = v_a->e;
- do {
- BMVert *v_other = BM_edge_other_vert(e, v_a);
- BLI_assert(!BM_ELEM_API_FLAG_TEST(v_other, VERT_VISIT));
- BM_ELEM_API_FLAG_ENABLE(v_other, VERT_VISIT);
- } while ((e = BM_DISK_EDGE_NEXT(e, v_a)) != e_first);
-
- /* check 'v_b' connects to 'v_a' edges */
- e = e_first = v_b->e;
- do {
- BMVert *v_other = BM_edge_other_vert(e, v_b);
- if (BM_ELEM_API_FLAG_TEST(v_other, VERT_VISIT)) {
- is_double = true;
- break;
- }
- } while ((e = BM_DISK_EDGE_NEXT(e, v_b)) != e_first);
-
- /* cleanup */
- e = e_first = v_a->e;
- do {
- BMVert *v_other = BM_edge_other_vert(e, v_a);
- BLI_assert(BM_ELEM_API_FLAG_TEST(v_other, VERT_VISIT));
- BM_ELEM_API_FLAG_DISABLE(v_other, VERT_VISIT);
- } while ((e = BM_DISK_EDGE_NEXT(e, v_a)) != e_first);
+ /* tag 'v_a' */
+ e = e_first = v_a->e;
+ do {
+ BMVert *v_other = BM_edge_other_vert(e, v_a);
+ BLI_assert(!BM_ELEM_API_FLAG_TEST(v_other, VERT_VISIT));
+ BM_ELEM_API_FLAG_ENABLE(v_other, VERT_VISIT);
+ } while ((e = BM_DISK_EDGE_NEXT(e, v_a)) != e_first);
+
+ /* check 'v_b' connects to 'v_a' edges */
+ e = e_first = v_b->e;
+ do {
+ BMVert *v_other = BM_edge_other_vert(e, v_b);
+ if (BM_ELEM_API_FLAG_TEST(v_other, VERT_VISIT)) {
+ is_double = true;
+ break;
+ }
+ } while ((e = BM_DISK_EDGE_NEXT(e, v_b)) != e_first);
+
+ /* cleanup */
+ e = e_first = v_a->e;
+ do {
+ BMVert *v_other = BM_edge_other_vert(e, v_a);
+ BLI_assert(BM_ELEM_API_FLAG_TEST(v_other, VERT_VISIT));
+ BM_ELEM_API_FLAG_DISABLE(v_other, VERT_VISIT);
+ } while ((e = BM_DISK_EDGE_NEXT(e, v_a)) != e_first);
#undef VERT_VISIT
+ }
- }
-
- return is_double;
+ return is_double;
}
/**
@@ -2254,38 +2254,37 @@ bool BM_vert_splice_check_double(BMVert *v_a, BMVert *v_b)
*/
bool BM_vert_splice(BMesh *bm, BMVert *v_dst, BMVert *v_src)
{
- BMEdge *e;
+ BMEdge *e;
- /* verts already spliced */
- if (v_src == v_dst) {
- return false;
- }
+ /* verts already spliced */
+ if (v_src == v_dst) {
+ return false;
+ }
- BLI_assert(BM_vert_pair_share_face_check(v_src, v_dst) == false);
+ BLI_assert(BM_vert_pair_share_face_check(v_src, v_dst) == false);
- /* move all the edges from 'v_src' disk to 'v_dst' */
- while ((e = v_src->e)) {
- bmesh_edge_vert_swap(e, v_dst, v_src);
- BLI_assert(e->v1 != e->v2);
- }
+ /* move all the edges from 'v_src' disk to 'v_dst' */
+ while ((e = v_src->e)) {
+ bmesh_edge_vert_swap(e, v_dst, v_src);
+ BLI_assert(e->v1 != e->v2);
+ }
- BM_CHECK_ELEMENT(v_src);
- BM_CHECK_ELEMENT(v_dst);
+ BM_CHECK_ELEMENT(v_src);
+ BM_CHECK_ELEMENT(v_dst);
- /* 'v_src' is unused now, and can be killed */
- BM_vert_kill(bm, v_src);
+ /* 'v_src' is unused now, and can be killed */
+ BM_vert_kill(bm, v_src);
- return true;
+ return true;
}
-
/** \name BM_vert_separate, bmesh_kernel_vert_separate and friends
* \{ */
/* BM_edge_face_count(e) >= 1 */
BLI_INLINE bool bm_edge_supports_separate(const BMEdge *e)
{
- return (e->l && e->l->radial_next != e->l);
+ return (e->l && e->l->radial_next != e->l);
}
/**
@@ -2300,114 +2299,113 @@ BLI_INLINE bool bm_edge_supports_separate(const BMEdge *e)
* \return Success
*/
void bmesh_kernel_vert_separate(
- BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
- const bool copy_select)
+ BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, const bool copy_select)
{
- int v_edges_num = 0;
+ int v_edges_num = 0;
- /* Detailed notes on array use since this is stack memory, we have to be careful */
+ /* Detailed notes on array use since this is stack memory, we have to be careful */
- /* newly created vertices, only use when 'r_vout' is set
- * (total size will be number of fans) */
- BLI_SMALLSTACK_DECLARE(verts_new, BMVert *);
- /* fill with edges from the face-fan, clearing on completion
- * (total size will be max fan edge count) */
- BLI_SMALLSTACK_DECLARE(edges, BMEdge *);
- /* temp store edges to walk over when filling 'edges',
- * (total size will be max radial edges of any edge) */
- BLI_SMALLSTACK_DECLARE(edges_search, BMEdge *);
+ /* newly created vertices, only use when 'r_vout' is set
+ * (total size will be number of fans) */
+ BLI_SMALLSTACK_DECLARE(verts_new, BMVert *);
+ /* fill with edges from the face-fan, clearing on completion
+ * (total size will be max fan edge count) */
+ BLI_SMALLSTACK_DECLARE(edges, BMEdge *);
+ /* temp store edges to walk over when filling 'edges',
+ * (total size will be max radial edges of any edge) */
+ BLI_SMALLSTACK_DECLARE(edges_search, BMEdge *);
- /* number of resulting verts, include self */
- int verts_num = 1;
- /* track the total number of edges handled, so we know when we've found the last fan */
- int edges_found = 0;
+ /* number of resulting verts, include self */
+ int verts_num = 1;
+ /* track the total number of edges handled, so we know when we've found the last fan */
+ int edges_found = 0;
#define EDGE_VISIT _FLAG_WALK
- /* count and flag at once */
- if (v->e) {
- BMEdge *e_first, *e_iter;
- e_iter = e_first = v->e;
- do {
- v_edges_num += 1;
-
- BLI_assert(!BM_ELEM_API_FLAG_TEST(e_iter, EDGE_VISIT));
- BM_ELEM_API_FLAG_ENABLE(e_iter, EDGE_VISIT);
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- }
-
- while (true) {
- /* Considering only edges and faces incident on vertex v, walk
- * the edges & collect in the 'edges' list for splitting */
-
- BMEdge *e = v->e;
- BM_ELEM_API_FLAG_DISABLE(e, EDGE_VISIT);
-
- do {
- BLI_assert(!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT));
- BLI_SMALLSTACK_PUSH(edges, e);
- edges_found += 1;
-
- if (e->l) {
- BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- BMLoop *l_adjacent = (l_iter->v == v) ? l_iter->prev : l_iter->next;
- BLI_assert(BM_vert_in_edge(l_adjacent->e, v));
- if (BM_ELEM_API_FLAG_TEST(l_adjacent->e, EDGE_VISIT)) {
- BM_ELEM_API_FLAG_DISABLE(l_adjacent->e, EDGE_VISIT);
- BLI_SMALLSTACK_PUSH(edges_search, l_adjacent->e);
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
- } while ((e = BLI_SMALLSTACK_POP(edges_search)));
-
- /* now we have all edges connected to 'v->e' */
-
- BLI_assert(edges_found <= v_edges_num);
-
- if (edges_found == v_edges_num) {
- /* We're done! The remaining edges in 'edges' form the last fan,
- * which can be left as is.
- * if 'edges' were alloc'd it'd be freed here. */
- break;
- }
- else {
- BMVert *v_new;
-
- v_new = BM_vert_create(bm, v->co, v, BM_CREATE_NOP);
- if (copy_select) {
- BM_elem_select_copy(bm, v_new, v);
- }
-
- while ((e = BLI_SMALLSTACK_POP(edges))) {
- bmesh_edge_vert_swap(e, v_new, v);
- }
-
- if (r_vout) {
- BLI_SMALLSTACK_PUSH(verts_new, v_new);
- }
- verts_num += 1;
- }
- }
+ /* count and flag at once */
+ if (v->e) {
+ BMEdge *e_first, *e_iter;
+ e_iter = e_first = v->e;
+ do {
+ v_edges_num += 1;
+
+ BLI_assert(!BM_ELEM_API_FLAG_TEST(e_iter, EDGE_VISIT));
+ BM_ELEM_API_FLAG_ENABLE(e_iter, EDGE_VISIT);
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+
+ while (true) {
+ /* Considering only edges and faces incident on vertex v, walk
+ * the edges & collect in the 'edges' list for splitting */
+
+ BMEdge *e = v->e;
+ BM_ELEM_API_FLAG_DISABLE(e, EDGE_VISIT);
+
+ do {
+ BLI_assert(!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT));
+ BLI_SMALLSTACK_PUSH(edges, e);
+ edges_found += 1;
+
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ BMLoop *l_adjacent = (l_iter->v == v) ? l_iter->prev : l_iter->next;
+ BLI_assert(BM_vert_in_edge(l_adjacent->e, v));
+ if (BM_ELEM_API_FLAG_TEST(l_adjacent->e, EDGE_VISIT)) {
+ BM_ELEM_API_FLAG_DISABLE(l_adjacent->e, EDGE_VISIT);
+ BLI_SMALLSTACK_PUSH(edges_search, l_adjacent->e);
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ } while ((e = BLI_SMALLSTACK_POP(edges_search)));
+
+ /* now we have all edges connected to 'v->e' */
+
+ BLI_assert(edges_found <= v_edges_num);
+
+ if (edges_found == v_edges_num) {
+ /* We're done! The remaining edges in 'edges' form the last fan,
+ * which can be left as is.
+ * if 'edges' were alloc'd it'd be freed here. */
+ break;
+ }
+ else {
+ BMVert *v_new;
+
+ v_new = BM_vert_create(bm, v->co, v, BM_CREATE_NOP);
+ if (copy_select) {
+ BM_elem_select_copy(bm, v_new, v);
+ }
+
+ while ((e = BLI_SMALLSTACK_POP(edges))) {
+ bmesh_edge_vert_swap(e, v_new, v);
+ }
+
+ if (r_vout) {
+ BLI_SMALLSTACK_PUSH(verts_new, v_new);
+ }
+ verts_num += 1;
+ }
+ }
#undef EDGE_VISIT
- /* flags are clean now, handle return values */
+ /* flags are clean now, handle return values */
- if (r_vout_len != NULL) {
- *r_vout_len = verts_num;
- }
+ if (r_vout_len != NULL) {
+ *r_vout_len = verts_num;
+ }
- if (r_vout != NULL) {
- BMVert **verts;
+ if (r_vout != NULL) {
+ BMVert **verts;
- verts = MEM_mallocN(sizeof(BMVert *) * verts_num, __func__);
- *r_vout = verts;
+ verts = MEM_mallocN(sizeof(BMVert *) * verts_num, __func__);
+ *r_vout = verts;
- verts[0] = v;
- BLI_SMALLSTACK_AS_TABLE(verts_new, &verts[1]);
- }
+ verts[0] = v;
+ BLI_SMALLSTACK_AS_TABLE(verts_new, &verts[1]);
+ }
}
/**
@@ -2430,131 +2428,132 @@ void bmesh_kernel_vert_separate(
*/
static void bmesh_kernel_vert_separate__cleanup(BMesh *bm, LinkNode *edges_separate)
{
- do {
- LinkNode *n_orig = edges_separate->link;
- do {
- LinkNode *n_prev = n_orig;
- LinkNode *n_step = n_orig->next;
- BMEdge *e_orig = n_orig->link;
- do {
- BMEdge *e = n_step->link;
- BLI_assert(e != e_orig);
- if ((e->v1 == e_orig->v1) && (e->v2 == e_orig->v2) &&
- BM_edge_splice(bm, e_orig, e))
- {
- /* don't visit again */
- n_prev->next = n_step->next;
- }
- else {
- n_prev = n_step;
- }
- } while ((n_step = n_step->next));
-
- } while ((n_orig = n_orig->next) && n_orig->next);
- } while ((edges_separate = edges_separate->next));
+ do {
+ LinkNode *n_orig = edges_separate->link;
+ do {
+ LinkNode *n_prev = n_orig;
+ LinkNode *n_step = n_orig->next;
+ BMEdge *e_orig = n_orig->link;
+ do {
+ BMEdge *e = n_step->link;
+ BLI_assert(e != e_orig);
+ if ((e->v1 == e_orig->v1) && (e->v2 == e_orig->v2) && BM_edge_splice(bm, e_orig, e)) {
+ /* don't visit again */
+ n_prev->next = n_step->next;
+ }
+ else {
+ n_prev = n_step;
+ }
+ } while ((n_step = n_step->next));
+
+ } while ((n_orig = n_orig->next) && n_orig->next);
+ } while ((edges_separate = edges_separate->next));
}
/**
* High level function which wraps both #bmesh_kernel_vert_separate and #bmesh_kernel_edge_separate
*/
-void BM_vert_separate(
- BMesh *bm, BMVert *v,
- BMEdge **e_in, int e_in_len,
- const bool copy_select,
- BMVert ***r_vout, int *r_vout_len)
+void BM_vert_separate(BMesh *bm,
+ BMVert *v,
+ BMEdge **e_in,
+ int e_in_len,
+ const bool copy_select,
+ BMVert ***r_vout,
+ int *r_vout_len)
{
- LinkNode *edges_separate = NULL;
- int i;
-
- for (i = 0; i < e_in_len; i++) {
- BMEdge *e = e_in[i];
- if (bm_edge_supports_separate(e)) {
- LinkNode *edges_orig = NULL;
- do {
- BMLoop *l_sep = e->l;
- bmesh_kernel_edge_separate(bm, e, l_sep, copy_select);
- BLI_linklist_prepend_alloca(&edges_orig, l_sep->e);
- BLI_assert(e != l_sep->e);
- } while (bm_edge_supports_separate(e));
- BLI_linklist_prepend_alloca(&edges_orig, e);
- BLI_linklist_prepend_alloca(&edges_separate, edges_orig);
- }
- }
-
- bmesh_kernel_vert_separate(bm, v, r_vout, r_vout_len, copy_select);
-
- if (edges_separate) {
- bmesh_kernel_vert_separate__cleanup(bm, edges_separate);
- }
+ LinkNode *edges_separate = NULL;
+ int i;
+
+ for (i = 0; i < e_in_len; i++) {
+ BMEdge *e = e_in[i];
+ if (bm_edge_supports_separate(e)) {
+ LinkNode *edges_orig = NULL;
+ do {
+ BMLoop *l_sep = e->l;
+ bmesh_kernel_edge_separate(bm, e, l_sep, copy_select);
+ BLI_linklist_prepend_alloca(&edges_orig, l_sep->e);
+ BLI_assert(e != l_sep->e);
+ } while (bm_edge_supports_separate(e));
+ BLI_linklist_prepend_alloca(&edges_orig, e);
+ BLI_linklist_prepend_alloca(&edges_separate, edges_orig);
+ }
+ }
+
+ bmesh_kernel_vert_separate(bm, v, r_vout, r_vout_len, copy_select);
+
+ if (edges_separate) {
+ bmesh_kernel_vert_separate__cleanup(bm, edges_separate);
+ }
}
-
/**
* A version of #BM_vert_separate which takes a flag.
*/
-void BM_vert_separate_hflag(
- BMesh *bm, BMVert *v,
- const char hflag,
- const bool copy_select,
- BMVert ***r_vout, int *r_vout_len)
+void BM_vert_separate_hflag(BMesh *bm,
+ BMVert *v,
+ const char hflag,
+ const bool copy_select,
+ BMVert ***r_vout,
+ int *r_vout_len)
{
- LinkNode *edges_separate = NULL;
- BMEdge *e_iter, *e_first;
-
- e_iter = e_first = v->e;
- do {
- if (BM_elem_flag_test(e_iter, hflag)) {
- BMEdge *e = e_iter;
- if (bm_edge_supports_separate(e)) {
- LinkNode *edges_orig = NULL;
- do {
- BMLoop *l_sep = e->l;
- bmesh_kernel_edge_separate(bm, e, l_sep, copy_select);
- /* trick to avoid looping over separated edges */
- if (edges_separate == NULL && edges_orig == NULL) {
- e_first = l_sep->e;
- }
- BLI_linklist_prepend_alloca(&edges_orig, l_sep->e);
- BLI_assert(e != l_sep->e);
- } while (bm_edge_supports_separate(e));
- BLI_linklist_prepend_alloca(&edges_orig, e);
- BLI_linklist_prepend_alloca(&edges_separate, edges_orig);
- }
- }
- } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
-
- bmesh_kernel_vert_separate(bm, v, r_vout, r_vout_len, copy_select);
-
- if (edges_separate) {
- bmesh_kernel_vert_separate__cleanup(bm, edges_separate);
- }
+ LinkNode *edges_separate = NULL;
+ BMEdge *e_iter, *e_first;
+
+ e_iter = e_first = v->e;
+ do {
+ if (BM_elem_flag_test(e_iter, hflag)) {
+ BMEdge *e = e_iter;
+ if (bm_edge_supports_separate(e)) {
+ LinkNode *edges_orig = NULL;
+ do {
+ BMLoop *l_sep = e->l;
+ bmesh_kernel_edge_separate(bm, e, l_sep, copy_select);
+ /* trick to avoid looping over separated edges */
+ if (edges_separate == NULL && edges_orig == NULL) {
+ e_first = l_sep->e;
+ }
+ BLI_linklist_prepend_alloca(&edges_orig, l_sep->e);
+ BLI_assert(e != l_sep->e);
+ } while (bm_edge_supports_separate(e));
+ BLI_linklist_prepend_alloca(&edges_orig, e);
+ BLI_linklist_prepend_alloca(&edges_separate, edges_orig);
+ }
+ }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
+
+ bmesh_kernel_vert_separate(bm, v, r_vout, r_vout_len, copy_select);
+
+ if (edges_separate) {
+ bmesh_kernel_vert_separate__cleanup(bm, edges_separate);
+ }
}
-void BM_vert_separate_tested_edges(
- BMesh *UNUSED(bm), BMVert *v_dst, BMVert *v_src,
- bool (*testfn)(BMEdge *, void *arg), void *arg)
+void BM_vert_separate_tested_edges(BMesh *UNUSED(bm),
+ BMVert *v_dst,
+ BMVert *v_src,
+ bool (*testfn)(BMEdge *, void *arg),
+ void *arg)
{
- LinkNode *edges_hflag = NULL;
- BMEdge *e_iter, *e_first;
-
- e_iter = e_first = v_src->e;
- do {
- if (testfn(e_iter, arg)) {
- BLI_linklist_prepend_alloca(&edges_hflag, e_iter);
- }
- } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_src)) != e_first);
-
- if (edges_hflag) {
- do {
- e_iter = edges_hflag->link;
- bmesh_disk_vert_replace(e_iter, v_dst, v_src);
- } while ((edges_hflag = edges_hflag->next));
- }
+ LinkNode *edges_hflag = NULL;
+ BMEdge *e_iter, *e_first;
+
+ e_iter = e_first = v_src->e;
+ do {
+ if (testfn(e_iter, arg)) {
+ BLI_linklist_prepend_alloca(&edges_hflag, e_iter);
+ }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_src)) != e_first);
+
+ if (edges_hflag) {
+ do {
+ e_iter = edges_hflag->link;
+ bmesh_disk_vert_replace(e_iter, v_dst, v_src);
+ } while ((edges_hflag = edges_hflag->next));
+ }
}
/** \} */
-
/**
* \brief Splice Edge
*
@@ -2567,35 +2566,35 @@ void BM_vert_separate_tested_edges(
*/
bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src)
{
- BMLoop *l;
+ BMLoop *l;
- if (!BM_vert_in_edge(e_src, e_dst->v1) || !BM_vert_in_edge(e_src, e_dst->v2)) {
- /* not the same vertices can't splice */
+ if (!BM_vert_in_edge(e_src, e_dst->v1) || !BM_vert_in_edge(e_src, e_dst->v2)) {
+ /* not the same vertices can't splice */
- /* the caller should really make sure this doesn't happen ever
- * so assert on release builds */
- BLI_assert(0);
+ /* the caller should really make sure this doesn't happen ever
+ * so assert on release builds */
+ BLI_assert(0);
- return false;
- }
+ return false;
+ }
- while (e_src->l) {
- l = e_src->l;
- BLI_assert(BM_vert_in_edge(e_dst, l->v));
- BLI_assert(BM_vert_in_edge(e_dst, l->next->v));
- bmesh_radial_loop_remove(e_src, l);
- bmesh_radial_loop_append(e_dst, l);
- }
+ while (e_src->l) {
+ l = e_src->l;
+ BLI_assert(BM_vert_in_edge(e_dst, l->v));
+ BLI_assert(BM_vert_in_edge(e_dst, l->next->v));
+ bmesh_radial_loop_remove(e_src, l);
+ bmesh_radial_loop_append(e_dst, l);
+ }
- BLI_assert(bmesh_radial_length(e_src->l) == 0);
+ BLI_assert(bmesh_radial_length(e_src->l) == 0);
- BM_CHECK_ELEMENT(e_src);
- BM_CHECK_ELEMENT(e_dst);
+ BM_CHECK_ELEMENT(e_src);
+ BM_CHECK_ELEMENT(e_dst);
- /* removes from disks too */
- BM_edge_kill(bm, e_src);
+ /* removes from disks too */
+ BM_edge_kill(bm, e_src);
- return true;
+ return true;
}
/**
@@ -2609,41 +2608,39 @@ bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src)
* \note Does nothing if \a l_sep is already the only loop in the
* edge radial.
*/
-void bmesh_kernel_edge_separate(
- BMesh *bm, BMEdge *e, BMLoop *l_sep,
- const bool copy_select)
+void bmesh_kernel_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep, const bool copy_select)
{
- BMEdge *e_new;
+ BMEdge *e_new;
#ifndef NDEBUG
- const int radlen = bmesh_radial_length(e->l);
+ const int radlen = bmesh_radial_length(e->l);
#endif
- BLI_assert(l_sep->e == e);
- BLI_assert(e->l);
+ BLI_assert(l_sep->e == e);
+ BLI_assert(e->l);
- if (BM_edge_is_boundary(e)) {
- BLI_assert(0); /* no cut required */
- return;
- }
+ if (BM_edge_is_boundary(e)) {
+ BLI_assert(0); /* no cut required */
+ return;
+ }
- if (l_sep == e->l) {
- e->l = l_sep->radial_next;
- }
+ if (l_sep == e->l) {
+ e->l = l_sep->radial_next;
+ }
- e_new = BM_edge_create(bm, e->v1, e->v2, e, BM_CREATE_NOP);
- bmesh_radial_loop_remove(e, l_sep);
- bmesh_radial_loop_append(e_new, l_sep);
- l_sep->e = e_new;
+ e_new = BM_edge_create(bm, e->v1, e->v2, e, BM_CREATE_NOP);
+ bmesh_radial_loop_remove(e, l_sep);
+ bmesh_radial_loop_append(e_new, l_sep);
+ l_sep->e = e_new;
- if (copy_select) {
- BM_elem_select_copy(bm, e_new, e);
- }
+ if (copy_select) {
+ BM_elem_select_copy(bm, e_new, e);
+ }
- BLI_assert(bmesh_radial_length(e->l) == radlen - 1);
- BLI_assert(bmesh_radial_length(e_new->l) == 1);
+ BLI_assert(bmesh_radial_length(e->l) == radlen - 1);
+ BLI_assert(bmesh_radial_length(e_new->l) == 1);
- BM_CHECK_ELEMENT(e_new);
- BM_CHECK_ELEMENT(e);
+ BM_CHECK_ELEMENT(e_new);
+ BM_CHECK_ELEMENT(e);
}
/**
@@ -2657,64 +2654,64 @@ void bmesh_kernel_edge_separate(
*/
BMVert *bmesh_kernel_unglue_region_make_vert(BMesh *bm, BMLoop *l_sep)
{
- BMVert *v_new = NULL;
- BMVert *v_sep = l_sep->v;
- BMEdge *e_iter;
- BMEdge *edges[2];
- int i;
-
- /* peel the face from the edge radials on both sides of the
- * loop vert, disconnecting the face from its fan */
- if (!BM_edge_is_boundary(l_sep->e)) {
- bmesh_kernel_edge_separate(bm, l_sep->e, l_sep, false);
- }
- if (!BM_edge_is_boundary(l_sep->prev->e)) {
- bmesh_kernel_edge_separate(bm, l_sep->prev->e, l_sep->prev, false);
- }
-
- /* do inline, below */
+ BMVert *v_new = NULL;
+ BMVert *v_sep = l_sep->v;
+ BMEdge *e_iter;
+ BMEdge *edges[2];
+ int i;
+
+ /* peel the face from the edge radials on both sides of the
+ * loop vert, disconnecting the face from its fan */
+ if (!BM_edge_is_boundary(l_sep->e)) {
+ bmesh_kernel_edge_separate(bm, l_sep->e, l_sep, false);
+ }
+ if (!BM_edge_is_boundary(l_sep->prev->e)) {
+ bmesh_kernel_edge_separate(bm, l_sep->prev->e, l_sep->prev, false);
+ }
+
+ /* do inline, below */
#if 0
- if (BM_vert_edge_count_is_equal(v_sep, 2)) {
- return v_sep;
- }
+ if (BM_vert_edge_count_is_equal(v_sep, 2)) {
+ return v_sep;
+ }
#endif
- /* Search for an edge unattached to this loop */
- e_iter = v_sep->e;
- while (!ELEM(e_iter, l_sep->e, l_sep->prev->e)) {
- e_iter = bmesh_disk_edge_next(e_iter, v_sep);
+ /* Search for an edge unattached to this loop */
+ e_iter = v_sep->e;
+ while (!ELEM(e_iter, l_sep->e, l_sep->prev->e)) {
+ e_iter = bmesh_disk_edge_next(e_iter, v_sep);
- /* We've come back around to the initial edge, all touch this loop.
- * If there are still only two edges out of v_sep,
- * then this whole URMV was just a no-op, so exit now. */
- if (e_iter == v_sep->e) {
- BLI_assert(BM_vert_edge_count_is_equal(v_sep, 2));
- return v_sep;
- }
- }
+ /* We've come back around to the initial edge, all touch this loop.
+ * If there are still only two edges out of v_sep,
+ * then this whole URMV was just a no-op, so exit now. */
+ if (e_iter == v_sep->e) {
+ BLI_assert(BM_vert_edge_count_is_equal(v_sep, 2));
+ return v_sep;
+ }
+ }
- v_sep->e = l_sep->e;
+ v_sep->e = l_sep->e;
- v_new = BM_vert_create(bm, v_sep->co, v_sep, BM_CREATE_NOP);
+ v_new = BM_vert_create(bm, v_sep->co, v_sep, BM_CREATE_NOP);
- edges[0] = l_sep->e;
- edges[1] = l_sep->prev->e;
+ edges[0] = l_sep->e;
+ edges[1] = l_sep->prev->e;
- for (i = 0; i < ARRAY_SIZE(edges); i++) {
- BMEdge *e = edges[i];
- bmesh_edge_vert_swap(e, v_new, v_sep);
- }
+ for (i = 0; i < ARRAY_SIZE(edges); i++) {
+ BMEdge *e = edges[i];
+ bmesh_edge_vert_swap(e, v_new, v_sep);
+ }
- BLI_assert(v_sep != l_sep->v);
- BLI_assert(v_sep->e != l_sep->v->e);
+ BLI_assert(v_sep != l_sep->v);
+ BLI_assert(v_sep->e != l_sep->v->e);
- BM_CHECK_ELEMENT(l_sep);
- BM_CHECK_ELEMENT(v_sep);
- BM_CHECK_ELEMENT(edges[0]);
- BM_CHECK_ELEMENT(edges[1]);
- BM_CHECK_ELEMENT(v_new);
+ BM_CHECK_ELEMENT(l_sep);
+ BM_CHECK_ELEMENT(v_sep);
+ BM_CHECK_ELEMENT(edges[0]);
+ BM_CHECK_ELEMENT(edges[1]);
+ BM_CHECK_ELEMENT(v_new);
- return v_new;
+ return v_new;
}
/**
@@ -2724,186 +2721,184 @@ BMVert *bmesh_kernel_unglue_region_make_vert(BMesh *bm, BMLoop *l_sep)
*
* This function handles the details of finding fans boundaries.
*/
-BMVert *bmesh_kernel_unglue_region_make_vert_multi(
- BMesh *bm, BMLoop **larr, int larr_len)
+BMVert *bmesh_kernel_unglue_region_make_vert_multi(BMesh *bm, BMLoop **larr, int larr_len)
{
- BMVert *v_sep = larr[0]->v;
- BMVert *v_new;
- int edges_len = 0;
- int i;
- /* any edges not owned by 'larr' loops connected to 'v_sep'? */
- bool is_mixed_edge_any = false;
- /* any loops not owned by 'larr' radially connected to 'larr' loop edges? */
- bool is_mixed_loop_any = false;
+ BMVert *v_sep = larr[0]->v;
+ BMVert *v_new;
+ int edges_len = 0;
+ int i;
+ /* any edges not owned by 'larr' loops connected to 'v_sep'? */
+ bool is_mixed_edge_any = false;
+ /* any loops not owned by 'larr' radially connected to 'larr' loop edges? */
+ bool is_mixed_loop_any = false;
#define LOOP_VISIT _FLAG_WALK
#define EDGE_VISIT _FLAG_WALK
- for (i = 0; i < larr_len; i++) {
- BMLoop *l_sep = larr[i];
-
- /* all must be from the same vert! */
- BLI_assert(v_sep == l_sep->v);
-
- BLI_assert(!BM_ELEM_API_FLAG_TEST(l_sep, LOOP_VISIT));
- BM_ELEM_API_FLAG_ENABLE(l_sep, LOOP_VISIT);
-
- /* weak! but it makes it simpler to check for edges to split
- * while doing a radial loop (where loops may be adjacent) */
- BM_ELEM_API_FLAG_ENABLE(l_sep->next, LOOP_VISIT);
- BM_ELEM_API_FLAG_ENABLE(l_sep->prev, LOOP_VISIT);
-
- BMLoop *loop_pair[2] = {l_sep, l_sep->prev};
- for (int j = 0; j < ARRAY_SIZE(loop_pair); j++) {
- BMEdge *e = loop_pair[j]->e;
- if (!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT)) {
- BM_ELEM_API_FLAG_ENABLE(e, EDGE_VISIT);
- edges_len += 1;
- }
- }
- }
-
- BMEdge **edges = BLI_array_alloca(edges, edges_len);
- STACK_DECLARE(edges);
-
- STACK_INIT(edges, edges_len);
-
- {
- BMEdge *e_first, *e_iter;
- e_iter = e_first = v_sep->e;
- do {
- if (BM_ELEM_API_FLAG_TEST(e_iter, EDGE_VISIT)) {
- BMLoop *l_iter, *l_first;
- bool is_mixed_loop = false;
-
- l_iter = l_first = e_iter->l;
- do {
- if (!BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
- is_mixed_loop = true;
- break;
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
-
- if (is_mixed_loop) {
- /* ensure the first loop is one we don't own so we can do a quick check below
- * on the edge's loop-flag to see if the edge is mixed or not. */
- e_iter->l = l_iter;
-
- is_mixed_loop_any = true;
- }
-
- STACK_PUSH(edges, e_iter);
- }
- else {
- /* at least one edge attached isn't connected to our loops */
- is_mixed_edge_any = true;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v_sep)) != e_first);
- }
-
- BLI_assert(edges_len == STACK_SIZE(edges));
-
- if (is_mixed_loop_any == false && is_mixed_edge_any == false) {
- /* all loops in 'larr' are the sole owners of their edges.
- * nothing to split away from, this is a no-op */
- v_new = v_sep;
- }
- else {
- v_new = BM_vert_create(bm, v_sep->co, v_sep, BM_CREATE_NOP);
-
- for (i = 0; i < STACK_SIZE(edges); i++) {
- BMEdge *e = edges[i];
- BMLoop *l_iter, *l_first, *l_next;
- BMEdge *e_new;
-
- /* disable so copied edge isn't left dirty (loop edges are cleared last too) */
- BM_ELEM_API_FLAG_DISABLE(e, EDGE_VISIT);
-
- /* will always be false when (is_mixed_loop_any == false) */
- if (!BM_ELEM_API_FLAG_TEST(e->l, LOOP_VISIT)) {
- /* edge has some loops owned by us, some owned by other loops */
- BMVert *e_new_v_pair[2];
-
- if (e->v1 == v_sep) {
- e_new_v_pair[0] = v_new;
- e_new_v_pair[1] = e->v2;
- }
- else {
- BLI_assert(v_sep == e->v2);
- e_new_v_pair[0] = e->v1;
- e_new_v_pair[1] = v_new;
- }
-
- e_new = BM_edge_create(bm, UNPACK2(e_new_v_pair), e, BM_CREATE_NOP);
-
- /* now moved all loops from 'larr' to this newly created edge */
- l_iter = l_first = e->l;
- do {
- l_next = l_iter->radial_next;
- if (BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
- bmesh_radial_loop_remove(e, l_iter);
- bmesh_radial_loop_append(e_new, l_iter);
- l_iter->e = e_new;
- }
- } while ((l_iter = l_next) != l_first);
- }
- else {
- /* we own the edge entirely, replace the vert */
- bmesh_disk_vert_replace(e, v_new, v_sep);
- }
-
- /* loop vert is handled last! */
- }
- }
-
- for (i = 0; i < larr_len; i++) {
- BMLoop *l_sep = larr[i];
-
- l_sep->v = v_new;
-
- BLI_assert(BM_ELEM_API_FLAG_TEST(l_sep, LOOP_VISIT));
- BLI_assert(BM_ELEM_API_FLAG_TEST(l_sep->prev, LOOP_VISIT));
- BLI_assert(BM_ELEM_API_FLAG_TEST(l_sep->next, LOOP_VISIT));
- BM_ELEM_API_FLAG_DISABLE(l_sep, LOOP_VISIT);
- BM_ELEM_API_FLAG_DISABLE(l_sep->prev, LOOP_VISIT);
- BM_ELEM_API_FLAG_DISABLE(l_sep->next, LOOP_VISIT);
-
-
- BM_ELEM_API_FLAG_DISABLE(l_sep->prev->e, EDGE_VISIT);
- BM_ELEM_API_FLAG_DISABLE(l_sep->e, EDGE_VISIT);
- }
+ for (i = 0; i < larr_len; i++) {
+ BMLoop *l_sep = larr[i];
+
+ /* all must be from the same vert! */
+ BLI_assert(v_sep == l_sep->v);
+
+ BLI_assert(!BM_ELEM_API_FLAG_TEST(l_sep, LOOP_VISIT));
+ BM_ELEM_API_FLAG_ENABLE(l_sep, LOOP_VISIT);
+
+ /* weak! but it makes it simpler to check for edges to split
+ * while doing a radial loop (where loops may be adjacent) */
+ BM_ELEM_API_FLAG_ENABLE(l_sep->next, LOOP_VISIT);
+ BM_ELEM_API_FLAG_ENABLE(l_sep->prev, LOOP_VISIT);
+
+ BMLoop *loop_pair[2] = {l_sep, l_sep->prev};
+ for (int j = 0; j < ARRAY_SIZE(loop_pair); j++) {
+ BMEdge *e = loop_pair[j]->e;
+ if (!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT)) {
+ BM_ELEM_API_FLAG_ENABLE(e, EDGE_VISIT);
+ edges_len += 1;
+ }
+ }
+ }
+
+ BMEdge **edges = BLI_array_alloca(edges, edges_len);
+ STACK_DECLARE(edges);
+
+ STACK_INIT(edges, edges_len);
+
+ {
+ BMEdge *e_first, *e_iter;
+ e_iter = e_first = v_sep->e;
+ do {
+ if (BM_ELEM_API_FLAG_TEST(e_iter, EDGE_VISIT)) {
+ BMLoop *l_iter, *l_first;
+ bool is_mixed_loop = false;
+
+ l_iter = l_first = e_iter->l;
+ do {
+ if (!BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
+ is_mixed_loop = true;
+ break;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+
+ if (is_mixed_loop) {
+ /* ensure the first loop is one we don't own so we can do a quick check below
+ * on the edge's loop-flag to see if the edge is mixed or not. */
+ e_iter->l = l_iter;
+
+ is_mixed_loop_any = true;
+ }
+
+ STACK_PUSH(edges, e_iter);
+ }
+ else {
+ /* at least one edge attached isn't connected to our loops */
+ is_mixed_edge_any = true;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v_sep)) != e_first);
+ }
+
+ BLI_assert(edges_len == STACK_SIZE(edges));
+
+ if (is_mixed_loop_any == false && is_mixed_edge_any == false) {
+ /* all loops in 'larr' are the sole owners of their edges.
+ * nothing to split away from, this is a no-op */
+ v_new = v_sep;
+ }
+ else {
+ v_new = BM_vert_create(bm, v_sep->co, v_sep, BM_CREATE_NOP);
+
+ for (i = 0; i < STACK_SIZE(edges); i++) {
+ BMEdge *e = edges[i];
+ BMLoop *l_iter, *l_first, *l_next;
+ BMEdge *e_new;
+
+ /* disable so copied edge isn't left dirty (loop edges are cleared last too) */
+ BM_ELEM_API_FLAG_DISABLE(e, EDGE_VISIT);
+
+ /* will always be false when (is_mixed_loop_any == false) */
+ if (!BM_ELEM_API_FLAG_TEST(e->l, LOOP_VISIT)) {
+ /* edge has some loops owned by us, some owned by other loops */
+ BMVert *e_new_v_pair[2];
+
+ if (e->v1 == v_sep) {
+ e_new_v_pair[0] = v_new;
+ e_new_v_pair[1] = e->v2;
+ }
+ else {
+ BLI_assert(v_sep == e->v2);
+ e_new_v_pair[0] = e->v1;
+ e_new_v_pair[1] = v_new;
+ }
+
+ e_new = BM_edge_create(bm, UNPACK2(e_new_v_pair), e, BM_CREATE_NOP);
+
+ /* now moved all loops from 'larr' to this newly created edge */
+ l_iter = l_first = e->l;
+ do {
+ l_next = l_iter->radial_next;
+ if (BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
+ bmesh_radial_loop_remove(e, l_iter);
+ bmesh_radial_loop_append(e_new, l_iter);
+ l_iter->e = e_new;
+ }
+ } while ((l_iter = l_next) != l_first);
+ }
+ else {
+ /* we own the edge entirely, replace the vert */
+ bmesh_disk_vert_replace(e, v_new, v_sep);
+ }
+
+ /* loop vert is handled last! */
+ }
+ }
+
+ for (i = 0; i < larr_len; i++) {
+ BMLoop *l_sep = larr[i];
+
+ l_sep->v = v_new;
+
+ BLI_assert(BM_ELEM_API_FLAG_TEST(l_sep, LOOP_VISIT));
+ BLI_assert(BM_ELEM_API_FLAG_TEST(l_sep->prev, LOOP_VISIT));
+ BLI_assert(BM_ELEM_API_FLAG_TEST(l_sep->next, LOOP_VISIT));
+ BM_ELEM_API_FLAG_DISABLE(l_sep, LOOP_VISIT);
+ BM_ELEM_API_FLAG_DISABLE(l_sep->prev, LOOP_VISIT);
+ BM_ELEM_API_FLAG_DISABLE(l_sep->next, LOOP_VISIT);
+
+ BM_ELEM_API_FLAG_DISABLE(l_sep->prev->e, EDGE_VISIT);
+ BM_ELEM_API_FLAG_DISABLE(l_sep->e, EDGE_VISIT);
+ }
#undef LOOP_VISIT
#undef EDGE_VISIT
- return v_new;
+ return v_new;
}
static void bmesh_edge_vert_swap__recursive(BMEdge *e, BMVert *v_dst, BMVert *v_src)
{
- BMLoop *l_iter, *l_first;
-
- BLI_assert(ELEM(v_src, e->v1, e->v2));
- bmesh_disk_vert_replace(e, v_dst, v_src);
-
- l_iter = l_first = e->l;
- do {
- if (l_iter->v == v_src) {
- l_iter->v = v_dst;
- if (BM_vert_in_edge(l_iter->prev->e, v_src)) {
- bmesh_edge_vert_swap__recursive(l_iter->prev->e, v_dst, v_src);
- }
- }
- else if (l_iter->next->v == v_src) {
- l_iter->next->v = v_dst;
- if (BM_vert_in_edge(l_iter->next->e, v_src)) {
- bmesh_edge_vert_swap__recursive(l_iter->next->e, v_dst, v_src);
- }
- }
- else {
- BLI_assert(l_iter->prev->v != v_src);
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
+ BMLoop *l_iter, *l_first;
+
+ BLI_assert(ELEM(v_src, e->v1, e->v2));
+ bmesh_disk_vert_replace(e, v_dst, v_src);
+
+ l_iter = l_first = e->l;
+ do {
+ if (l_iter->v == v_src) {
+ l_iter->v = v_dst;
+ if (BM_vert_in_edge(l_iter->prev->e, v_src)) {
+ bmesh_edge_vert_swap__recursive(l_iter->prev->e, v_dst, v_src);
+ }
+ }
+ else if (l_iter->next->v == v_src) {
+ l_iter->next->v = v_dst;
+ if (BM_vert_in_edge(l_iter->next->e, v_src)) {
+ bmesh_edge_vert_swap__recursive(l_iter->next->e, v_dst, v_src);
+ }
+ }
+ else {
+ BLI_assert(l_iter->prev->v != v_src);
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
}
/**
@@ -2912,11 +2907,11 @@ static void bmesh_edge_vert_swap__recursive(BMEdge *e, BMVert *v_dst, BMVert *v_
*/
BMVert *bmesh_kernel_unglue_region_make_vert_multi_isolated(BMesh *bm, BMLoop *l_sep)
{
- BMVert *v_new = BM_vert_create(bm, l_sep->v->co, l_sep->v, BM_CREATE_NOP);
- /* passing either 'l_sep->e', 'l_sep->prev->e' will work */
- bmesh_edge_vert_swap__recursive(l_sep->e, v_new, l_sep->v);
- BLI_assert(l_sep->v == v_new);
- return v_new;
+ BMVert *v_new = BM_vert_create(bm, l_sep->v->co, l_sep->v, BM_CREATE_NOP);
+ /* passing either 'l_sep->e', 'l_sep->prev->e' will work */
+ bmesh_edge_vert_swap__recursive(l_sep->e, v_new, l_sep->v);
+ BLI_assert(l_sep->v == v_new);
+ return v_new;
}
/**
@@ -2926,23 +2921,23 @@ BMVert *bmesh_kernel_unglue_region_make_vert_multi_isolated(BMesh *bm, BMLoop *l
*/
void bmesh_face_swap_data(BMFace *f_a, BMFace *f_b)
{
- BMLoop *l_iter, *l_first;
+ BMLoop *l_iter, *l_first;
- BLI_assert(f_a != f_b);
+ BLI_assert(f_a != f_b);
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
- do {
- l_iter->f = f_b;
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
+ do {
+ l_iter->f = f_b;
+ } while ((l_iter = l_iter->next) != l_first);
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_b);
- do {
- l_iter->f = f_a;
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_b);
+ do {
+ l_iter->f = f_a;
+ } while ((l_iter = l_iter->next) != l_first);
- SWAP(BMFace, (*f_a), (*f_b));
+ SWAP(BMFace, (*f_a), (*f_b));
- /* swap back */
- SWAP(void *, f_a->head.data, f_b->head.data);
- SWAP(int, f_a->head.index, f_b->head.index);
+ /* swap back */
+ SWAP(void *, f_a->head.data, f_b->head.data);
+ SWAP(int, f_a->head.index, f_b->head.index);
}
diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h
index dc20b8afaac..3308f93d5d3 100644
--- a/source/blender/bmesh/intern/bmesh_core.h
+++ b/source/blender/bmesh/intern/bmesh_core.h
@@ -22,96 +22,107 @@
*/
BMFace *BM_face_copy(
- BMesh *bm_dst, BMesh *bm_src, BMFace *f,
- const bool copy_verts, const bool copy_edges);
+ BMesh *bm_dst, BMesh *bm_src, BMFace *f, const bool copy_verts, const bool copy_edges);
typedef enum eBMCreateFlag {
- BM_CREATE_NOP = 0,
- /* faces and edges only */
- BM_CREATE_NO_DOUBLE = (1 << 1),
- /* Skip CustomData - for all element types data,
- * use if we immediately write customdata into the element so this skips copying from 'example'
- * args or setting defaults, speeds up conversion when data is converted all at once. */
- BM_CREATE_SKIP_CD = (1 << 2),
+ BM_CREATE_NOP = 0,
+ /* faces and edges only */
+ BM_CREATE_NO_DOUBLE = (1 << 1),
+ /* Skip CustomData - for all element types data,
+ * use if we immediately write customdata into the element so this skips copying from 'example'
+ * args or setting defaults, speeds up conversion when data is converted all at once. */
+ BM_CREATE_SKIP_CD = (1 << 2),
} eBMCreateFlag;
-BMVert *BM_vert_create(
- BMesh *bm, const float co[3],
- const BMVert *v_example, const eBMCreateFlag create_flag);
+BMVert *BM_vert_create(BMesh *bm,
+ const float co[3],
+ const BMVert *v_example,
+ const eBMCreateFlag create_flag);
BMEdge *BM_edge_create(
- BMesh *bm, BMVert *v1, BMVert *v2,
- const BMEdge *e_example, const eBMCreateFlag create_flag);
-BMFace *BM_face_create(
- BMesh *bm, BMVert **verts, BMEdge **edges, const int len,
- const BMFace *f_example, const eBMCreateFlag create_flag);
-BMFace *BM_face_create_verts(
- BMesh *bm, BMVert **verts, const int len,
- const BMFace *f_example, const eBMCreateFlag create_flag,
- const bool create_edges);
-
-void BM_face_edges_kill(BMesh *bm, BMFace *f);
-void BM_face_verts_kill(BMesh *bm, BMFace *f);
-
-void BM_face_kill_loose(BMesh *bm, BMFace *f);
-
-void BM_face_kill(BMesh *bm, BMFace *f);
-void BM_edge_kill(BMesh *bm, BMEdge *e);
-void BM_vert_kill(BMesh *bm, BMVert *v);
-
-bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src);
-bool BM_vert_splice(BMesh *bm, BMVert *v_dst, BMVert *v_src);
-bool BM_vert_splice_check_double(BMVert *v_a, BMVert *v_b);
-
-void bmesh_kernel_loop_reverse(
- BMesh *bm, BMFace *f,
- const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip);
-
-void bmesh_face_swap_data(BMFace *f_a, BMFace *f_b);
+ BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *e_example, const eBMCreateFlag create_flag);
+BMFace *BM_face_create(BMesh *bm,
+ BMVert **verts,
+ BMEdge **edges,
+ const int len,
+ const BMFace *f_example,
+ const eBMCreateFlag create_flag);
+BMFace *BM_face_create_verts(BMesh *bm,
+ BMVert **verts,
+ const int len,
+ const BMFace *f_example,
+ const eBMCreateFlag create_flag,
+ const bool create_edges);
+
+void BM_face_edges_kill(BMesh *bm, BMFace *f);
+void BM_face_verts_kill(BMesh *bm, BMFace *f);
+
+void BM_face_kill_loose(BMesh *bm, BMFace *f);
+
+void BM_face_kill(BMesh *bm, BMFace *f);
+void BM_edge_kill(BMesh *bm, BMEdge *e);
+void BM_vert_kill(BMesh *bm, BMVert *v);
+
+bool BM_edge_splice(BMesh *bm, BMEdge *e_dst, BMEdge *e_src);
+bool BM_vert_splice(BMesh *bm, BMVert *v_dst, BMVert *v_src);
+bool BM_vert_splice_check_double(BMVert *v_a, BMVert *v_b);
+
+void bmesh_kernel_loop_reverse(BMesh *bm,
+ BMFace *f,
+ const int cd_loop_mdisp_offset,
+ const bool use_loop_mdisp_flip);
+
+void bmesh_face_swap_data(BMFace *f_a, BMFace *f_b);
BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface, const bool do_del);
-void BM_vert_separate(
- BMesh *bm, BMVert *v, BMEdge **e_in, int e_in_len, const bool copy_select,
- BMVert ***r_vout, int *r_vout_len);
-void BM_vert_separate_hflag(
- BMesh *bm, BMVert *v, const char hflag, const bool copy_select,
- BMVert ***r_vout, int *r_vout_len);
+void BM_vert_separate(BMesh *bm,
+ BMVert *v,
+ BMEdge **e_in,
+ int e_in_len,
+ const bool copy_select,
+ BMVert ***r_vout,
+ int *r_vout_len);
+void BM_vert_separate_hflag(BMesh *bm,
+ BMVert *v,
+ const char hflag,
+ const bool copy_select,
+ BMVert ***r_vout,
+ int *r_vout_len);
void BM_vert_separate_tested_edges(
- BMesh *bm, BMVert *v_dst, BMVert *v_src,
- bool (*testfn)(BMEdge *, void *arg), void *arg);
+ BMesh *bm, BMVert *v_dst, BMVert *v_src, bool (*testfn)(BMEdge *, void *arg), void *arg);
/**
* BMesh Kernel: For modifying structure.
*
* Names are on the verbose side but these are only for low-level access.
*/
-void bmesh_kernel_vert_separate(
- BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
- const bool copy_select);
-void bmesh_kernel_edge_separate(
- BMesh *bm, BMEdge *e, BMLoop *l_sep,
- const bool copy_select);
-
-BMFace *bmesh_kernel_split_face_make_edge(
- BMesh *bm, BMFace *f,
- BMLoop *l1, BMLoop *l2,
- BMLoop **r_l,
+void bmesh_kernel_vert_separate(
+ BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, const bool copy_select);
+void bmesh_kernel_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep, const bool copy_select);
+
+BMFace *bmesh_kernel_split_face_make_edge(BMesh *bm,
+ BMFace *f,
+ BMLoop *l1,
+ BMLoop *l2,
+ BMLoop **r_l,
#ifdef USE_BMESH_HOLES
- ListBase *holes,
+ ListBase *holes,
#endif
- BMEdge *example,
- const bool no_double
- );
-
-BMVert *bmesh_kernel_split_edge_make_vert(
- BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e);
-BMEdge *bmesh_kernel_join_edge_kill_vert(
- BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
- const bool do_del, const bool check_edge_splice,
- const bool kill_degenerate_faces);
-BMVert *bmesh_kernel_join_vert_kill_edge(
- BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
- const bool do_del, const bool check_edge_double,
- const bool kill_degenerate_faces);
+ BMEdge *example,
+ const bool no_double);
+
+BMVert *bmesh_kernel_split_edge_make_vert(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e);
+BMEdge *bmesh_kernel_join_edge_kill_vert(BMesh *bm,
+ BMEdge *e_kill,
+ BMVert *v_kill,
+ const bool do_del,
+ const bool check_edge_splice,
+ const bool kill_degenerate_faces);
+BMVert *bmesh_kernel_join_vert_kill_edge(BMesh *bm,
+ BMEdge *e_kill,
+ BMVert *v_kill,
+ const bool do_del,
+ const bool check_edge_double,
+ const bool kill_degenerate_faces);
BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e);
BMVert *bmesh_kernel_unglue_region_make_vert(BMesh *bm, BMLoop *l_sep);
diff --git a/source/blender/bmesh/intern/bmesh_delete.c b/source/blender/bmesh/intern/bmesh_delete.c
index 23fe8a31b41..4e2c81c80c3 100644
--- a/source/blender/bmesh/intern/bmesh_delete.c
+++ b/source/blender/bmesh/intern/bmesh_delete.c
@@ -23,13 +23,11 @@
* BM remove functions.
*/
-
#include "BLI_utildefines.h"
#include "bmesh.h"
#include "intern/bmesh_private.h"
-
/* -------------------------------------------------------------------- */
/* BMO functions */
@@ -42,63 +40,63 @@
*/
static void bmo_remove_tagged_faces(BMesh *bm, const short oflag)
{
- BMFace *f, *f_next;
- BMIter iter;
-
- BM_ITER_MESH_MUTABLE (f, f_next, &iter, bm, BM_FACES_OF_MESH) {
- if (BMO_face_flag_test(bm, f, oflag)) {
- BM_face_kill(bm, f);
- }
- }
+ BMFace *f, *f_next;
+ BMIter iter;
+
+ BM_ITER_MESH_MUTABLE (f, f_next, &iter, bm, BM_FACES_OF_MESH) {
+ if (BMO_face_flag_test(bm, f, oflag)) {
+ BM_face_kill(bm, f);
+ }
+ }
}
static void bmo_remove_tagged_edges(BMesh *bm, const short oflag)
{
- BMEdge *e, *e_next;
- BMIter iter;
-
- BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
- if (BMO_edge_flag_test(bm, e, oflag)) {
- BM_edge_kill(bm, e);
- }
- }
+ BMEdge *e, *e_next;
+ BMIter iter;
+
+ BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BMO_edge_flag_test(bm, e, oflag)) {
+ BM_edge_kill(bm, e);
+ }
+ }
}
static void bmo_remove_tagged_verts(BMesh *bm, const short oflag)
{
- BMVert *v, *v_next;
- BMIter iter;
-
- BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
- if (BMO_vert_flag_test(bm, v, oflag)) {
- BM_vert_kill(bm, v);
- }
- }
+ BMVert *v, *v_next;
+ BMIter iter;
+
+ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BMO_vert_flag_test(bm, v, oflag)) {
+ BM_vert_kill(bm, v);
+ }
+ }
}
static void bmo_remove_tagged_verts_loose(BMesh *bm, const short oflag)
{
- BMVert *v, *v_next;
- BMIter iter;
-
- BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
- if (BMO_vert_flag_test(bm, v, oflag) && (v->e == NULL)) {
- BM_vert_kill(bm, v);
- }
- }
+ BMVert *v, *v_next;
+ BMIter iter;
+
+ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BMO_vert_flag_test(bm, v, oflag) && (v->e == NULL)) {
+ BM_vert_kill(bm, v);
+ }
+ }
}
void BMO_mesh_delete_oflag_tagged(BMesh *bm, const short oflag, const char htype)
{
- if (htype & BM_FACE) {
- bmo_remove_tagged_faces(bm, oflag);
- }
- if (htype & BM_EDGE) {
- bmo_remove_tagged_edges(bm, oflag);
- }
- if (htype & BM_VERT) {
- bmo_remove_tagged_verts(bm, oflag);
- }
+ if (htype & BM_FACE) {
+ bmo_remove_tagged_faces(bm, oflag);
+ }
+ if (htype & BM_EDGE) {
+ bmo_remove_tagged_edges(bm, oflag);
+ }
+ if (htype & BM_VERT) {
+ bmo_remove_tagged_verts(bm, oflag);
+ }
}
/**
@@ -107,111 +105,104 @@ void BMO_mesh_delete_oflag_tagged(BMesh *bm, const short oflag, const char htype
*/
void BMO_mesh_delete_oflag_context(BMesh *bm, const short oflag, const int type)
{
- BMEdge *e;
- BMFace *f;
-
- BMIter eiter;
- BMIter fiter;
-
- switch (type) {
- case DEL_VERTS:
- {
- bmo_remove_tagged_verts(bm, oflag);
-
- break;
- }
- case DEL_EDGES:
- {
- /* flush down to vert */
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (BMO_edge_flag_test(bm, e, oflag)) {
- BMO_vert_flag_enable(bm, e->v1, oflag);
- BMO_vert_flag_enable(bm, e->v2, oflag);
- }
- }
- bmo_remove_tagged_edges(bm, oflag);
- bmo_remove_tagged_verts_loose(bm, oflag);
-
- break;
- }
- case DEL_EDGESFACES:
- {
- bmo_remove_tagged_edges(bm, oflag);
-
- break;
- }
- case DEL_ONLYFACES:
- {
- bmo_remove_tagged_faces(bm, oflag);
-
- break;
- }
- case DEL_ONLYTAGGED:
- {
- BMO_mesh_delete_oflag_tagged(bm, oflag, BM_ALL_NOLOOP);
-
- break;
- }
- case DEL_FACES:
- case DEL_FACES_KEEP_BOUNDARY:
- {
- /* go through and mark all edges and all verts of all faces for delete */
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- if (BMO_face_flag_test(bm, f, oflag)) {
- BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
- BMLoop *l_iter;
-
- l_iter = l_first;
- do {
- BMO_vert_flag_enable(bm, l_iter->v, oflag);
- BMO_edge_flag_enable(bm, l_iter->e, oflag);
- } while ((l_iter = l_iter->next) != l_first);
- }
- }
- /* now go through and mark all remaining faces all edges for keeping */
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- if (!BMO_face_flag_test(bm, f, oflag)) {
- BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
- BMLoop *l_iter;
-
- l_iter = l_first;
- do {
- BMO_vert_flag_disable(bm, l_iter->v, oflag);
- BMO_edge_flag_disable(bm, l_iter->e, oflag);
- } while ((l_iter = l_iter->next) != l_first);
- }
- }
- /* also mark all the vertices of remaining edges for keeping */
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
-
- /* Only exception to normal 'DEL_FACES' logic. */
- if (type == DEL_FACES_KEEP_BOUNDARY) {
- if (BM_edge_is_boundary(e)) {
- BMO_edge_flag_disable(bm, e, oflag);
- }
- }
-
- if (!BMO_edge_flag_test(bm, e, oflag)) {
- BMO_vert_flag_disable(bm, e->v1, oflag);
- BMO_vert_flag_disable(bm, e->v2, oflag);
- }
- }
-
- /* now delete marked face */
- bmo_remove_tagged_faces(bm, oflag);
- /* delete marked edge */
- bmo_remove_tagged_edges(bm, oflag);
- /* remove loose vertice */
- bmo_remove_tagged_verts(bm, oflag);
-
- break;
- }
- }
+ BMEdge *e;
+ BMFace *f;
+
+ BMIter eiter;
+ BMIter fiter;
+
+ switch (type) {
+ case DEL_VERTS: {
+ bmo_remove_tagged_verts(bm, oflag);
+
+ break;
+ }
+ case DEL_EDGES: {
+ /* flush down to vert */
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BMO_edge_flag_test(bm, e, oflag)) {
+ BMO_vert_flag_enable(bm, e->v1, oflag);
+ BMO_vert_flag_enable(bm, e->v2, oflag);
+ }
+ }
+ bmo_remove_tagged_edges(bm, oflag);
+ bmo_remove_tagged_verts_loose(bm, oflag);
+
+ break;
+ }
+ case DEL_EDGESFACES: {
+ bmo_remove_tagged_edges(bm, oflag);
+
+ break;
+ }
+ case DEL_ONLYFACES: {
+ bmo_remove_tagged_faces(bm, oflag);
+
+ break;
+ }
+ case DEL_ONLYTAGGED: {
+ BMO_mesh_delete_oflag_tagged(bm, oflag, BM_ALL_NOLOOP);
+
+ break;
+ }
+ case DEL_FACES:
+ case DEL_FACES_KEEP_BOUNDARY: {
+ /* go through and mark all edges and all verts of all faces for delete */
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (BMO_face_flag_test(bm, f, oflag)) {
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
+
+ l_iter = l_first;
+ do {
+ BMO_vert_flag_enable(bm, l_iter->v, oflag);
+ BMO_edge_flag_enable(bm, l_iter->e, oflag);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+ /* now go through and mark all remaining faces all edges for keeping */
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (!BMO_face_flag_test(bm, f, oflag)) {
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
+
+ l_iter = l_first;
+ do {
+ BMO_vert_flag_disable(bm, l_iter->v, oflag);
+ BMO_edge_flag_disable(bm, l_iter->e, oflag);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+ /* also mark all the vertices of remaining edges for keeping */
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+
+ /* Only exception to normal 'DEL_FACES' logic. */
+ if (type == DEL_FACES_KEEP_BOUNDARY) {
+ if (BM_edge_is_boundary(e)) {
+ BMO_edge_flag_disable(bm, e, oflag);
+ }
+ }
+
+ if (!BMO_edge_flag_test(bm, e, oflag)) {
+ BMO_vert_flag_disable(bm, e->v1, oflag);
+ BMO_vert_flag_disable(bm, e->v2, oflag);
+ }
+ }
+
+ /* now delete marked face */
+ bmo_remove_tagged_faces(bm, oflag);
+ /* delete marked edge */
+ bmo_remove_tagged_edges(bm, oflag);
+ /* remove loose vertice */
+ bmo_remove_tagged_verts(bm, oflag);
+
+ break;
+ }
+ }
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* BM functions
*
@@ -225,63 +216,63 @@ void BMO_mesh_delete_oflag_context(BMesh *bm, const short oflag, const int type)
static void bm_remove_tagged_faces(BMesh *bm, const char hflag)
{
- BMFace *f, *f_next;
- BMIter iter;
-
- BM_ITER_MESH_MUTABLE (f, f_next, &iter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(f, hflag)) {
- BM_face_kill(bm, f);
- }
- }
+ BMFace *f, *f_next;
+ BMIter iter;
+
+ BM_ITER_MESH_MUTABLE (f, f_next, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, hflag)) {
+ BM_face_kill(bm, f);
+ }
+ }
}
static void bm_remove_tagged_edges(BMesh *bm, const char hflag)
{
- BMEdge *e, *e_next;
- BMIter iter;
-
- BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, hflag)) {
- BM_edge_kill(bm, e);
- }
- }
+ BMEdge *e, *e_next;
+ BMIter iter;
+
+ BM_ITER_MESH_MUTABLE (e, e_next, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, hflag)) {
+ BM_edge_kill(bm, e);
+ }
+ }
}
static void bm_remove_tagged_verts(BMesh *bm, const char hflag)
{
- BMVert *v, *v_next;
- BMIter iter;
-
- BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, hflag)) {
- BM_vert_kill(bm, v);
- }
- }
+ BMVert *v, *v_next;
+ BMIter iter;
+
+ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, hflag)) {
+ BM_vert_kill(bm, v);
+ }
+ }
}
static void bm_remove_tagged_verts_loose(BMesh *bm, const char hflag)
{
- BMVert *v, *v_next;
- BMIter iter;
-
- BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, hflag) && (v->e == NULL)) {
- BM_vert_kill(bm, v);
- }
- }
+ BMVert *v, *v_next;
+ BMIter iter;
+
+ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, hflag) && (v->e == NULL)) {
+ BM_vert_kill(bm, v);
+ }
+ }
}
void BM_mesh_delete_hflag_tagged(BMesh *bm, const char hflag, const char htype)
{
- if (htype & BM_FACE) {
- bm_remove_tagged_faces(bm, hflag);
- }
- if (htype & BM_EDGE) {
- bm_remove_tagged_edges(bm, hflag);
- }
- if (htype & BM_VERT) {
- bm_remove_tagged_verts(bm, hflag);
- }
+ if (htype & BM_FACE) {
+ bm_remove_tagged_faces(bm, hflag);
+ }
+ if (htype & BM_EDGE) {
+ bm_remove_tagged_edges(bm, hflag);
+ }
+ if (htype & BM_VERT) {
+ bm_remove_tagged_verts(bm, hflag);
+ }
}
/**
@@ -290,96 +281,90 @@ void BM_mesh_delete_hflag_tagged(BMesh *bm, const char hflag, const char htype)
*/
void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type)
{
- BMEdge *e;
- BMFace *f;
-
- BMIter eiter;
- BMIter fiter;
-
- switch (type) {
- case DEL_VERTS:
- {
- bm_remove_tagged_verts(bm, hflag);
-
- break;
- }
- case DEL_EDGES:
- {
- /* flush down to vert */
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, hflag)) {
- BM_elem_flag_enable(e->v1, hflag);
- BM_elem_flag_enable(e->v2, hflag);
- }
- }
- bm_remove_tagged_edges(bm, hflag);
- bm_remove_tagged_verts_loose(bm, hflag);
-
- break;
- }
- case DEL_EDGESFACES:
- {
- bm_remove_tagged_edges(bm, hflag);
-
- break;
- }
- case DEL_ONLYFACES:
- {
- bm_remove_tagged_faces(bm, hflag);
-
- break;
- }
- case DEL_ONLYTAGGED:
- {
- BM_mesh_delete_hflag_tagged(bm, hflag, BM_ALL_NOLOOP);
-
- break;
- }
- case DEL_FACES:
- {
- /* go through and mark all edges and all verts of all faces for delete */
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(f, hflag)) {
- BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
- BMLoop *l_iter;
-
- l_iter = l_first;
- do {
- BM_elem_flag_enable(l_iter->v, hflag);
- BM_elem_flag_enable(l_iter->e, hflag);
- } while ((l_iter = l_iter->next) != l_first);
- }
- }
- /* now go through and mark all remaining faces all edges for keeping */
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- if (!BM_elem_flag_test(f, hflag)) {
- BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
- BMLoop *l_iter;
-
- l_iter = l_first;
- do {
- BM_elem_flag_disable(l_iter->v, hflag);
- BM_elem_flag_disable(l_iter->e, hflag);
- } while ((l_iter = l_iter->next) != l_first);
- }
- }
- /* also mark all the vertices of remaining edges for keeping */
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (!BM_elem_flag_test(e, hflag)) {
- BM_elem_flag_disable(e->v1, hflag);
- BM_elem_flag_disable(e->v2, hflag);
- }
- }
- /* now delete marked face */
- bm_remove_tagged_faces(bm, hflag);
- /* delete marked edge */
- bm_remove_tagged_edges(bm, hflag);
- /* remove loose vertice */
- bm_remove_tagged_verts(bm, hflag);
-
- break;
- }
- }
+ BMEdge *e;
+ BMFace *f;
+
+ BMIter eiter;
+ BMIter fiter;
+
+ switch (type) {
+ case DEL_VERTS: {
+ bm_remove_tagged_verts(bm, hflag);
+
+ break;
+ }
+ case DEL_EDGES: {
+ /* flush down to vert */
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, hflag)) {
+ BM_elem_flag_enable(e->v1, hflag);
+ BM_elem_flag_enable(e->v2, hflag);
+ }
+ }
+ bm_remove_tagged_edges(bm, hflag);
+ bm_remove_tagged_verts_loose(bm, hflag);
+
+ break;
+ }
+ case DEL_EDGESFACES: {
+ bm_remove_tagged_edges(bm, hflag);
+
+ break;
+ }
+ case DEL_ONLYFACES: {
+ bm_remove_tagged_faces(bm, hflag);
+
+ break;
+ }
+ case DEL_ONLYTAGGED: {
+ BM_mesh_delete_hflag_tagged(bm, hflag, BM_ALL_NOLOOP);
+
+ break;
+ }
+ case DEL_FACES: {
+ /* go through and mark all edges and all verts of all faces for delete */
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, hflag)) {
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
+
+ l_iter = l_first;
+ do {
+ BM_elem_flag_enable(l_iter->v, hflag);
+ BM_elem_flag_enable(l_iter->e, hflag);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+ /* now go through and mark all remaining faces all edges for keeping */
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(f, hflag)) {
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
+
+ l_iter = l_first;
+ do {
+ BM_elem_flag_disable(l_iter->v, hflag);
+ BM_elem_flag_disable(l_iter->e, hflag);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+ /* also mark all the vertices of remaining edges for keeping */
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (!BM_elem_flag_test(e, hflag)) {
+ BM_elem_flag_disable(e->v1, hflag);
+ BM_elem_flag_disable(e->v2, hflag);
+ }
+ }
+ /* now delete marked face */
+ bm_remove_tagged_faces(bm, hflag);
+ /* delete marked edge */
+ bm_remove_tagged_edges(bm, hflag);
+ /* remove loose vertice */
+ bm_remove_tagged_verts(bm, hflag);
+
+ break;
+ }
+ }
}
/** \} */
diff --git a/source/blender/bmesh/intern/bmesh_delete.h b/source/blender/bmesh/intern/bmesh_delete.h
index 616485b242e..d41f26baddd 100644
--- a/source/blender/bmesh/intern/bmesh_delete.h
+++ b/source/blender/bmesh/intern/bmesh_delete.h
@@ -22,9 +22,9 @@
*/
void BMO_mesh_delete_oflag_tagged(BMesh *bm, const short oflag, const char htype);
-void BM_mesh_delete_hflag_tagged(BMesh *bm, const char hflag, const char htype);
+void BM_mesh_delete_hflag_tagged(BMesh *bm, const char hflag, const char htype);
void BMO_mesh_delete_oflag_context(BMesh *bm, const short oflag, const int type);
-void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type);
+void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type);
#endif /* __BMESH_DELETE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c
index 1f8661c3e04..a802515a3b2 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.c
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.c
@@ -33,15 +33,15 @@
#include "bmesh.h"
-#include "bmesh_edgeloop.h" /* own include */
+#include "bmesh_edgeloop.h" /* own include */
typedef struct BMEdgeLoopStore {
- struct BMEdgeLoopStore *next, *prev;
- ListBase verts;
- int flag;
- int len;
- /* optional values to calc */
- float co[3], no[3];
+ struct BMEdgeLoopStore *next, *prev;
+ ListBase verts;
+ int flag;
+ int len;
+ /* optional values to calc */
+ float co[3], no[3];
} BMEdgeLoopStore;
#define BM_EDGELOOP_IS_CLOSED (1 << 0)
@@ -50,26 +50,24 @@ typedef struct BMEdgeLoopStore {
/* -------------------------------------------------------------------- */
/* BM_mesh_edgeloops_find & Util Functions */
-static int bm_vert_other_tag(
- BMVert *v, BMVert *v_prev,
- BMEdge **r_e)
+static int bm_vert_other_tag(BMVert *v, BMVert *v_prev, BMEdge **r_e)
{
- BMIter iter;
- BMEdge *e, *e_next = NULL;
- uint count = 0;
-
- BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)) {
- BMVert *v_other = BM_edge_other_vert(e, v);
- if (v_other != v_prev) {
- e_next = e;
- count++;
- }
- }
- }
-
- *r_e = e_next;
- return count;
+ BMIter iter;
+ BMEdge *e, *e_next = NULL;
+ uint count = 0;
+
+ BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)) {
+ BMVert *v_other = BM_edge_other_vert(e, v);
+ if (v_other != v_prev) {
+ e_next = e;
+ count++;
+ }
+ }
+ }
+
+ *r_e = e_next;
+ return count;
}
/**
@@ -77,117 +75,115 @@ static int bm_vert_other_tag(
*/
static bool bm_loop_build(BMEdgeLoopStore *el_store, BMVert *v_prev, BMVert *v, int dir)
{
- void (*add_fn)(ListBase *, void *) = dir == 1 ? BLI_addhead : BLI_addtail;
- BMEdge *e_next;
- BMVert *v_next;
- BMVert *v_first = v;
-
- BLI_assert(ABS(dir) == 1);
-
- if (!BM_elem_flag_test(v, BM_ELEM_INTERNAL_TAG)) {
- return true;
- }
-
- while (v) {
- LinkData *node = MEM_callocN(sizeof(*node), __func__);
- int count;
- node->data = v;
- add_fn(&el_store->verts, node);
- el_store->len++;
- BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG);
-
- count = bm_vert_other_tag(v, v_prev, &e_next);
- if (count == 1) {
- v_next = BM_edge_other_vert(e_next, v);
- BM_elem_flag_disable(e_next, BM_ELEM_INTERNAL_TAG);
- if (UNLIKELY(v_next == v_first)) {
- el_store->flag |= BM_EDGELOOP_IS_CLOSED;
- v_next = NULL;
- }
- }
- else if (count == 0) {
- /* pass */
- v_next = NULL;
- }
- else {
- v_next = NULL;
- return false;
- }
-
- v_prev = v;
- v = v_next;
- }
-
- return true;
+ void (*add_fn)(ListBase *, void *) = dir == 1 ? BLI_addhead : BLI_addtail;
+ BMEdge *e_next;
+ BMVert *v_next;
+ BMVert *v_first = v;
+
+ BLI_assert(ABS(dir) == 1);
+
+ if (!BM_elem_flag_test(v, BM_ELEM_INTERNAL_TAG)) {
+ return true;
+ }
+
+ while (v) {
+ LinkData *node = MEM_callocN(sizeof(*node), __func__);
+ int count;
+ node->data = v;
+ add_fn(&el_store->verts, node);
+ el_store->len++;
+ BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG);
+
+ count = bm_vert_other_tag(v, v_prev, &e_next);
+ if (count == 1) {
+ v_next = BM_edge_other_vert(e_next, v);
+ BM_elem_flag_disable(e_next, BM_ELEM_INTERNAL_TAG);
+ if (UNLIKELY(v_next == v_first)) {
+ el_store->flag |= BM_EDGELOOP_IS_CLOSED;
+ v_next = NULL;
+ }
+ }
+ else if (count == 0) {
+ /* pass */
+ v_next = NULL;
+ }
+ else {
+ v_next = NULL;
+ return false;
+ }
+
+ v_prev = v;
+ v = v_next;
+ }
+
+ return true;
}
/**
* \return listbase of listbases, each linking to a vertex.
*/
-int BM_mesh_edgeloops_find(
- BMesh *bm, ListBase *r_eloops,
- bool (*test_fn)(BMEdge *, void *user_data), void *user_data)
+int BM_mesh_edgeloops_find(BMesh *bm,
+ ListBase *r_eloops,
+ bool (*test_fn)(BMEdge *, void *user_data),
+ void *user_data)
{
- BMIter iter;
- BMEdge *e;
- BMVert *v;
- int count = 0;
-
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG);
- }
-
- /* first flush edges to tags, and tag verts */
- BLI_Stack *edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__);
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- BLI_assert(!BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG));
- if (test_fn(e, user_data)) {
- BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG);
- BLI_stack_push(edge_stack, (void *)&e);
- }
- else {
- BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
- }
- }
-
- const uint edges_len = BLI_stack_count(edge_stack);
- BMEdge **edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
- BLI_stack_pop_n_reverse(edge_stack, edges, BLI_stack_count(edge_stack));
- BLI_stack_free(edge_stack);
-
- for (uint i = 0; i < edges_len; i += 1) {
- e = edges[i];
- if (BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)) {
- BMEdgeLoopStore *el_store = MEM_callocN(sizeof(BMEdgeLoopStore), __func__);
-
- /* add both directions */
- if (bm_loop_build(el_store, e->v1, e->v2, 1) &&
- bm_loop_build(el_store, e->v2, e->v1, -1) &&
- el_store->len > 1)
- {
- BLI_addtail(r_eloops, el_store);
- count++;
- }
- else {
- BM_edgeloop_free(el_store);
- }
- }
- }
-
- for (uint i = 0; i < edges_len; i += 1) {
- e = edges[i];
- BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_disable(e->v1, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_disable(e->v2, BM_ELEM_INTERNAL_TAG);
- }
-
- MEM_freeN(edges);
- return count;
+ BMIter iter;
+ BMEdge *e;
+ BMVert *v;
+ int count = 0;
+
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG);
+ }
+
+ /* first flush edges to tags, and tag verts */
+ BLI_Stack *edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__);
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BLI_assert(!BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG));
+ if (test_fn(e, user_data)) {
+ BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG);
+ BLI_stack_push(edge_stack, (void *)&e);
+ }
+ else {
+ BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
+ }
+ }
+
+ const uint edges_len = BLI_stack_count(edge_stack);
+ BMEdge **edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
+ BLI_stack_pop_n_reverse(edge_stack, edges, BLI_stack_count(edge_stack));
+ BLI_stack_free(edge_stack);
+
+ for (uint i = 0; i < edges_len; i += 1) {
+ e = edges[i];
+ if (BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)) {
+ BMEdgeLoopStore *el_store = MEM_callocN(sizeof(BMEdgeLoopStore), __func__);
+
+ /* add both directions */
+ if (bm_loop_build(el_store, e->v1, e->v2, 1) && bm_loop_build(el_store, e->v2, e->v1, -1) &&
+ el_store->len > 1) {
+ BLI_addtail(r_eloops, el_store);
+ count++;
+ }
+ else {
+ BM_edgeloop_free(el_store);
+ }
+ }
+ }
+
+ for (uint i = 0; i < edges_len; i += 1) {
+ e = edges[i];
+ BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_disable(e->v1, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_disable(e->v2, BM_ELEM_INTERNAL_TAG);
+ }
+
+ MEM_freeN(edges);
+ return count;
}
-
/* -------------------------------------------------------------------- */
/* BM_mesh_edgeloops_find_path & Util Functions */
@@ -196,310 +192,312 @@ int BM_mesh_edgeloops_find(
* Add to
*/
struct VertStep {
- struct VertStep *next, *prev;
- BMVert *v;
+ struct VertStep *next, *prev;
+ BMVert *v;
};
static void vs_add(
- BLI_mempool *vs_pool, ListBase *lb,
- BMVert *v, BMEdge *e_prev, const int iter_tot)
+ BLI_mempool *vs_pool, ListBase *lb, BMVert *v, BMEdge *e_prev, const int iter_tot)
{
- struct VertStep *vs_new = BLI_mempool_alloc(vs_pool);
- vs_new->v = v;
+ struct VertStep *vs_new = BLI_mempool_alloc(vs_pool);
+ vs_new->v = v;
- BM_elem_index_set(v, iter_tot); /* set_dirty */
+ BM_elem_index_set(v, iter_tot); /* set_dirty */
- /* This edge stores a direct path back to the original vertex so we can
- * backtrack without having to store an array of previous verts. */
+ /* This edge stores a direct path back to the original vertex so we can
+ * backtrack without having to store an array of previous verts. */
- /* WARNING - setting the edge is not common practice
- * but currently harmless, take care. */
- BLI_assert(BM_vert_in_edge(e_prev, v));
- v->e = e_prev;
+ /* WARNING - setting the edge is not common practice
+ * but currently harmless, take care. */
+ BLI_assert(BM_vert_in_edge(e_prev, v));
+ v->e = e_prev;
- BLI_addtail(lb, vs_new);
+ BLI_addtail(lb, vs_new);
}
-static bool bm_loop_path_build_step(BLI_mempool *vs_pool, ListBase *lb, const int dir, BMVert *v_match[2])
+static bool bm_loop_path_build_step(BLI_mempool *vs_pool,
+ ListBase *lb,
+ const int dir,
+ BMVert *v_match[2])
{
- ListBase lb_tmp = {NULL, NULL};
- struct VertStep *vs, *vs_next;
- BLI_assert(ABS(dir) == 1);
-
- for (vs = lb->first; vs; vs = vs_next) {
- BMIter iter;
- BMEdge *e;
- /* these values will be the same every iteration */
- const int vs_iter_tot = BM_elem_index_get(vs->v);
- const int vs_iter_next = vs_iter_tot + dir;
-
- vs_next = vs->next;
-
- BM_ITER_ELEM (e, &iter, vs->v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)) {
- BMVert *v_next = BM_edge_other_vert(e, vs->v);
- const int v_next_index = BM_elem_index_get(v_next);
- /* not essential to clear flag but prevents more checking next time round */
- BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
- if (v_next_index == 0) {
- vs_add(vs_pool, &lb_tmp, v_next, e, vs_iter_next);
- }
- else if ((dir < 0) == (v_next_index < 0)) {
- /* on the same side - do nothing */
- }
- else {
- /* we have met out match! (vertices from different sides meet) */
- if (dir == 1) {
- v_match[0] = vs->v;
- v_match[1] = v_next;
- }
- else {
- v_match[0] = v_next;
- v_match[1] = vs->v;
- }
- /* normally we would manage memory of remaining items in (lb, lb_tmp),
- * but search is done, vs_pool will get destroyed immediately */
- return true;
- }
- }
- }
-
- BLI_mempool_free(vs_pool, vs);
- }
- /* bm->elem_index_dirty |= BM_VERT; */ /* Commented because used in a loop, and this flag has already been set. */
-
- /* lb is now full of free'd items, overwrite */
- *lb = lb_tmp;
-
- return (BLI_listbase_is_empty(lb) == false);
+ ListBase lb_tmp = {NULL, NULL};
+ struct VertStep *vs, *vs_next;
+ BLI_assert(ABS(dir) == 1);
+
+ for (vs = lb->first; vs; vs = vs_next) {
+ BMIter iter;
+ BMEdge *e;
+ /* these values will be the same every iteration */
+ const int vs_iter_tot = BM_elem_index_get(vs->v);
+ const int vs_iter_next = vs_iter_tot + dir;
+
+ vs_next = vs->next;
+
+ BM_ITER_ELEM (e, &iter, vs->v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)) {
+ BMVert *v_next = BM_edge_other_vert(e, vs->v);
+ const int v_next_index = BM_elem_index_get(v_next);
+ /* not essential to clear flag but prevents more checking next time round */
+ BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
+ if (v_next_index == 0) {
+ vs_add(vs_pool, &lb_tmp, v_next, e, vs_iter_next);
+ }
+ else if ((dir < 0) == (v_next_index < 0)) {
+ /* on the same side - do nothing */
+ }
+ else {
+ /* we have met out match! (vertices from different sides meet) */
+ if (dir == 1) {
+ v_match[0] = vs->v;
+ v_match[1] = v_next;
+ }
+ else {
+ v_match[0] = v_next;
+ v_match[1] = vs->v;
+ }
+ /* normally we would manage memory of remaining items in (lb, lb_tmp),
+ * but search is done, vs_pool will get destroyed immediately */
+ return true;
+ }
+ }
+ }
+
+ BLI_mempool_free(vs_pool, vs);
+ }
+ /* bm->elem_index_dirty |= BM_VERT; */ /* Commented because used in a loop, and this flag has already been set. */
+
+ /* lb is now full of free'd items, overwrite */
+ *lb = lb_tmp;
+
+ return (BLI_listbase_is_empty(lb) == false);
}
-bool BM_mesh_edgeloops_find_path(
- BMesh *bm, ListBase *r_eloops,
- bool (*test_fn)(BMEdge *, void *user_data), void *user_data,
- BMVert *v_src, BMVert *v_dst)
+bool BM_mesh_edgeloops_find_path(BMesh *bm,
+ ListBase *r_eloops,
+ bool (*test_fn)(BMEdge *, void *user_data),
+ void *user_data,
+ BMVert *v_src,
+ BMVert *v_dst)
{
- BMIter iter;
- BMEdge *e;
- bool found = false;
-
- BLI_assert(v_src != v_dst);
-
- {
- BMVert *v;
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BM_elem_index_set(v, 0);
- BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG);
- }
- }
- bm->elem_index_dirty |= BM_VERT;
-
- /* first flush edges to tags, and tag verts */
- int edges_len;
- BMEdge **edges;
-
- if (test_fn) {
- BLI_Stack *edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__);
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (test_fn(e, user_data)) {
- BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG);
- BLI_stack_push(edge_stack, (void *)&e);
- }
- else {
- BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
- }
- }
- edges_len = BLI_stack_count(edge_stack);
- edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
- BLI_stack_pop_n_reverse(edge_stack, edges, BLI_stack_count(edge_stack));
- BLI_stack_free(edge_stack);
- }
- else {
- int i = 0;
- edges_len = bm->totedge;
- edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
-
- BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
- BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG);
- edges[i] = e;
- }
- }
-
- /* prime the lists and begin search */
- {
- BMVert *v_match[2] = {NULL, NULL};
- ListBase lb_src = {NULL, NULL};
- ListBase lb_dst = {NULL, NULL};
- BLI_mempool *vs_pool = BLI_mempool_create(sizeof(struct VertStep), 0, 512, BLI_MEMPOOL_NOP);
-
- /* edge args are dummy */
- vs_add(vs_pool, &lb_src, v_src, v_src->e, 1);
- vs_add(vs_pool, &lb_dst, v_dst, v_dst->e, -1);
- bm->elem_index_dirty |= BM_VERT;
-
- do {
- if ((bm_loop_path_build_step(vs_pool, &lb_src, 1, v_match) == false) || v_match[0]) {
- break;
- }
- if ((bm_loop_path_build_step(vs_pool, &lb_dst, -1, v_match) == false) || v_match[0]) {
- break;
- }
- } while (true);
-
- BLI_mempool_destroy(vs_pool);
-
- if (v_match[0]) {
- BMEdgeLoopStore *el_store = MEM_callocN(sizeof(BMEdgeLoopStore), __func__);
- BMVert *v;
-
- /* build loop from edge pointers */
- v = v_match[0];
- while (true) {
- LinkData *node = MEM_callocN(sizeof(*node), __func__);
- node->data = v;
- BLI_addhead(&el_store->verts, node);
- el_store->len++;
- if (v == v_src) {
- break;
- }
- v = BM_edge_other_vert(v->e, v);
- }
-
- v = v_match[1];
- while (true) {
- LinkData *node = MEM_callocN(sizeof(*node), __func__);
- node->data = v;
- BLI_addtail(&el_store->verts, node);
- el_store->len++;
- if (v == v_dst) {
- break;
- }
- v = BM_edge_other_vert(v->e, v);
- }
-
-
- BLI_addtail(r_eloops, el_store);
-
- found = true;
- }
- }
-
- for (uint i = 0; i < edges_len; i += 1) {
- e = edges[i];
- BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_disable(e->v1, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_disable(e->v2, BM_ELEM_INTERNAL_TAG);
- }
- MEM_freeN(edges);
-
- return found;
+ BMIter iter;
+ BMEdge *e;
+ bool found = false;
+
+ BLI_assert(v_src != v_dst);
+
+ {
+ BMVert *v;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_elem_index_set(v, 0);
+ BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG);
+ }
+ }
+ bm->elem_index_dirty |= BM_VERT;
+
+ /* first flush edges to tags, and tag verts */
+ int edges_len;
+ BMEdge **edges;
+
+ if (test_fn) {
+ BLI_Stack *edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__);
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (test_fn(e, user_data)) {
+ BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG);
+ BLI_stack_push(edge_stack, (void *)&e);
+ }
+ else {
+ BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
+ }
+ }
+ edges_len = BLI_stack_count(edge_stack);
+ edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
+ BLI_stack_pop_n_reverse(edge_stack, edges, BLI_stack_count(edge_stack));
+ BLI_stack_free(edge_stack);
+ }
+ else {
+ int i = 0;
+ edges_len = bm->totedge;
+ edges = MEM_mallocN(sizeof(*edges) * edges_len, __func__);
+
+ BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
+ BM_elem_flag_enable(e, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_enable(e->v1, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_enable(e->v2, BM_ELEM_INTERNAL_TAG);
+ edges[i] = e;
+ }
+ }
+
+ /* prime the lists and begin search */
+ {
+ BMVert *v_match[2] = {NULL, NULL};
+ ListBase lb_src = {NULL, NULL};
+ ListBase lb_dst = {NULL, NULL};
+ BLI_mempool *vs_pool = BLI_mempool_create(sizeof(struct VertStep), 0, 512, BLI_MEMPOOL_NOP);
+
+ /* edge args are dummy */
+ vs_add(vs_pool, &lb_src, v_src, v_src->e, 1);
+ vs_add(vs_pool, &lb_dst, v_dst, v_dst->e, -1);
+ bm->elem_index_dirty |= BM_VERT;
+
+ do {
+ if ((bm_loop_path_build_step(vs_pool, &lb_src, 1, v_match) == false) || v_match[0]) {
+ break;
+ }
+ if ((bm_loop_path_build_step(vs_pool, &lb_dst, -1, v_match) == false) || v_match[0]) {
+ break;
+ }
+ } while (true);
+
+ BLI_mempool_destroy(vs_pool);
+
+ if (v_match[0]) {
+ BMEdgeLoopStore *el_store = MEM_callocN(sizeof(BMEdgeLoopStore), __func__);
+ BMVert *v;
+
+ /* build loop from edge pointers */
+ v = v_match[0];
+ while (true) {
+ LinkData *node = MEM_callocN(sizeof(*node), __func__);
+ node->data = v;
+ BLI_addhead(&el_store->verts, node);
+ el_store->len++;
+ if (v == v_src) {
+ break;
+ }
+ v = BM_edge_other_vert(v->e, v);
+ }
+
+ v = v_match[1];
+ while (true) {
+ LinkData *node = MEM_callocN(sizeof(*node), __func__);
+ node->data = v;
+ BLI_addtail(&el_store->verts, node);
+ el_store->len++;
+ if (v == v_dst) {
+ break;
+ }
+ v = BM_edge_other_vert(v->e, v);
+ }
+
+ BLI_addtail(r_eloops, el_store);
+
+ found = true;
+ }
+ }
+
+ for (uint i = 0; i < edges_len; i += 1) {
+ e = edges[i];
+ BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_disable(e->v1, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_disable(e->v2, BM_ELEM_INTERNAL_TAG);
+ }
+ MEM_freeN(edges);
+
+ return found;
}
-
/* -------------------------------------------------------------------- */
/* BM_mesh_edgeloops_xxx utility function */
void BM_mesh_edgeloops_free(ListBase *eloops)
{
- BMEdgeLoopStore *el_store;
- while ((el_store = BLI_pophead(eloops))) {
- BM_edgeloop_free(el_store);
- }
+ BMEdgeLoopStore *el_store;
+ while ((el_store = BLI_pophead(eloops))) {
+ BM_edgeloop_free(el_store);
+ }
}
void BM_mesh_edgeloops_calc_center(BMesh *bm, ListBase *eloops)
{
- BMEdgeLoopStore *el_store;
- for (el_store = eloops->first; el_store; el_store = el_store->next) {
- BM_edgeloop_calc_center(bm, el_store);
- }
+ BMEdgeLoopStore *el_store;
+ for (el_store = eloops->first; el_store; el_store = el_store->next) {
+ BM_edgeloop_calc_center(bm, el_store);
+ }
}
void BM_mesh_edgeloops_calc_normal(BMesh *bm, ListBase *eloops)
{
- BMEdgeLoopStore *el_store;
- for (el_store = eloops->first; el_store; el_store = el_store->next) {
- BM_edgeloop_calc_normal(bm, el_store);
- }
+ BMEdgeLoopStore *el_store;
+ for (el_store = eloops->first; el_store; el_store = el_store->next) {
+ BM_edgeloop_calc_normal(bm, el_store);
+ }
}
void BM_mesh_edgeloops_calc_normal_aligned(BMesh *bm, ListBase *eloops, const float no_align[3])
{
- BMEdgeLoopStore *el_store;
- for (el_store = eloops->first; el_store; el_store = el_store->next) {
- BM_edgeloop_calc_normal_aligned(bm, el_store, no_align);
- }
+ BMEdgeLoopStore *el_store;
+ for (el_store = eloops->first; el_store; el_store = el_store->next) {
+ BM_edgeloop_calc_normal_aligned(bm, el_store, no_align);
+ }
}
void BM_mesh_edgeloops_calc_order(BMesh *UNUSED(bm), ListBase *eloops, const bool use_normals)
{
- ListBase eloops_ordered = {NULL};
- BMEdgeLoopStore *el_store;
- float cent[3];
- int tot = 0;
- zero_v3(cent);
- /* assumes we calculated centers already */
- for (el_store = eloops->first; el_store; el_store = el_store->next, tot++) {
- add_v3_v3(cent, el_store->co);
- }
- mul_v3_fl(cent, 1.0f / (float)tot);
-
- /* find far outest loop */
- {
- BMEdgeLoopStore *el_store_best = NULL;
- float len_best_sq = -1.0f;
- for (el_store = eloops->first; el_store; el_store = el_store->next) {
- const float len_sq = len_squared_v3v3(cent, el_store->co);
- if (len_sq > len_best_sq) {
- len_best_sq = len_sq;
- el_store_best = el_store;
- }
- }
-
- BLI_remlink(eloops, el_store_best);
- BLI_addtail(&eloops_ordered, el_store_best);
- }
-
- /* not so efficient re-ordering */
- while (eloops->first) {
- BMEdgeLoopStore *el_store_best = NULL;
- const float *co = ((BMEdgeLoopStore *)eloops_ordered.last)->co;
- const float *no = ((BMEdgeLoopStore *)eloops_ordered.last)->no;
- float len_best_sq = FLT_MAX;
-
- if (use_normals) {
- BLI_ASSERT_UNIT_V3(no);
- }
-
- for (el_store = eloops->first; el_store; el_store = el_store->next) {
- float len_sq;
- if (use_normals) {
- /* scale the length by how close the loops are to pointing at eachother */
- float dir[3];
- sub_v3_v3v3(dir, co, el_store->co);
- len_sq = normalize_v3(dir);
- len_sq = len_sq * ((1.0f - fabsf(dot_v3v3(dir, no))) +
- (1.0f - fabsf(dot_v3v3(dir, el_store->no))));
- }
- else {
- len_sq = len_squared_v3v3(co, el_store->co);
- }
-
- if (len_sq < len_best_sq) {
- len_best_sq = len_sq;
- el_store_best = el_store;
- }
- }
-
- BLI_remlink(eloops, el_store_best);
- BLI_addtail(&eloops_ordered, el_store_best);
- }
-
- *eloops = eloops_ordered;
+ ListBase eloops_ordered = {NULL};
+ BMEdgeLoopStore *el_store;
+ float cent[3];
+ int tot = 0;
+ zero_v3(cent);
+ /* assumes we calculated centers already */
+ for (el_store = eloops->first; el_store; el_store = el_store->next, tot++) {
+ add_v3_v3(cent, el_store->co);
+ }
+ mul_v3_fl(cent, 1.0f / (float)tot);
+
+ /* find far outest loop */
+ {
+ BMEdgeLoopStore *el_store_best = NULL;
+ float len_best_sq = -1.0f;
+ for (el_store = eloops->first; el_store; el_store = el_store->next) {
+ const float len_sq = len_squared_v3v3(cent, el_store->co);
+ if (len_sq > len_best_sq) {
+ len_best_sq = len_sq;
+ el_store_best = el_store;
+ }
+ }
+
+ BLI_remlink(eloops, el_store_best);
+ BLI_addtail(&eloops_ordered, el_store_best);
+ }
+
+ /* not so efficient re-ordering */
+ while (eloops->first) {
+ BMEdgeLoopStore *el_store_best = NULL;
+ const float *co = ((BMEdgeLoopStore *)eloops_ordered.last)->co;
+ const float *no = ((BMEdgeLoopStore *)eloops_ordered.last)->no;
+ float len_best_sq = FLT_MAX;
+
+ if (use_normals) {
+ BLI_ASSERT_UNIT_V3(no);
+ }
+
+ for (el_store = eloops->first; el_store; el_store = el_store->next) {
+ float len_sq;
+ if (use_normals) {
+ /* scale the length by how close the loops are to pointing at eachother */
+ float dir[3];
+ sub_v3_v3v3(dir, co, el_store->co);
+ len_sq = normalize_v3(dir);
+ len_sq = len_sq *
+ ((1.0f - fabsf(dot_v3v3(dir, no))) + (1.0f - fabsf(dot_v3v3(dir, el_store->no))));
+ }
+ else {
+ len_sq = len_squared_v3v3(co, el_store->co);
+ }
+
+ if (len_sq < len_best_sq) {
+ len_best_sq = len_sq;
+ el_store_best = el_store;
+ }
+ }
+
+ BLI_remlink(eloops, el_store_best);
+ BLI_addtail(&eloops_ordered, el_store_best);
+ }
+
+ *eloops = eloops_ordered;
}
/* -------------------------------------------------------------------- */
@@ -508,60 +506,60 @@ void BM_mesh_edgeloops_calc_order(BMesh *UNUSED(bm), ListBase *eloops, const boo
/* return new edgeloops */
BMEdgeLoopStore *BM_edgeloop_copy(BMEdgeLoopStore *el_store)
{
- BMEdgeLoopStore *el_store_copy = MEM_mallocN(sizeof(*el_store), __func__);
- *el_store_copy = *el_store;
- BLI_duplicatelist(&el_store_copy->verts, &el_store->verts);
- return el_store_copy;
+ BMEdgeLoopStore *el_store_copy = MEM_mallocN(sizeof(*el_store), __func__);
+ *el_store_copy = *el_store;
+ BLI_duplicatelist(&el_store_copy->verts, &el_store->verts);
+ return el_store_copy;
}
BMEdgeLoopStore *BM_edgeloop_from_verts(BMVert **v_arr, const int v_arr_tot, bool is_closed)
{
- BMEdgeLoopStore *el_store = MEM_callocN(sizeof(*el_store), __func__);
- int i;
- for (i = 0; i < v_arr_tot; i++) {
- LinkData *node = MEM_callocN(sizeof(*node), __func__);
- node->data = v_arr[i];
- BLI_addtail(&el_store->verts, node);
- }
- el_store->len = v_arr_tot;
- if (is_closed) {
- el_store->flag |= BM_EDGELOOP_IS_CLOSED;
- }
- return el_store;
+ BMEdgeLoopStore *el_store = MEM_callocN(sizeof(*el_store), __func__);
+ int i;
+ for (i = 0; i < v_arr_tot; i++) {
+ LinkData *node = MEM_callocN(sizeof(*node), __func__);
+ node->data = v_arr[i];
+ BLI_addtail(&el_store->verts, node);
+ }
+ el_store->len = v_arr_tot;
+ if (is_closed) {
+ el_store->flag |= BM_EDGELOOP_IS_CLOSED;
+ }
+ return el_store;
}
void BM_edgeloop_free(BMEdgeLoopStore *el_store)
{
- BLI_freelistN(&el_store->verts);
- MEM_freeN(el_store);
+ BLI_freelistN(&el_store->verts);
+ MEM_freeN(el_store);
}
bool BM_edgeloop_is_closed(BMEdgeLoopStore *el_store)
{
- return (el_store->flag & BM_EDGELOOP_IS_CLOSED) != 0;
+ return (el_store->flag & BM_EDGELOOP_IS_CLOSED) != 0;
}
ListBase *BM_edgeloop_verts_get(BMEdgeLoopStore *el_store)
{
- return &el_store->verts;
+ return &el_store->verts;
}
int BM_edgeloop_length_get(BMEdgeLoopStore *el_store)
{
- return el_store->len;
+ return el_store->len;
}
const float *BM_edgeloop_normal_get(struct BMEdgeLoopStore *el_store)
{
- return el_store->no;
+ return el_store->no;
}
const float *BM_edgeloop_center_get(struct BMEdgeLoopStore *el_store)
{
- return el_store->co;
+ return el_store->co;
}
-#define NODE_AS_V(n) ((BMVert *)((LinkData *)n)->data)
+#define NODE_AS_V(n) ((BMVert *)((LinkData *)n)->data)
#define NODE_AS_CO(n) ((BMVert *)((LinkData *)n)->data)->co
/**
@@ -569,92 +567,89 @@ const float *BM_edgeloop_center_get(struct BMEdgeLoopStore *el_store)
*/
void BM_edgeloop_edges_get(struct BMEdgeLoopStore *el_store, BMEdge **e_arr)
{
- LinkData *node;
- int i = 0;
- for (node = el_store->verts.first; node && node->next; node = node->next) {
- e_arr[i++] = BM_edge_exists(NODE_AS_V(node), NODE_AS_V(node->next));
- BLI_assert(e_arr[i - 1] != NULL);
- }
-
- if (el_store->flag & BM_EDGELOOP_IS_CLOSED) {
- e_arr[i] = BM_edge_exists(NODE_AS_V(el_store->verts.first), NODE_AS_V(el_store->verts.last));
- BLI_assert(e_arr[i] != NULL);
- }
- BLI_assert(el_store->len == i + 1);
+ LinkData *node;
+ int i = 0;
+ for (node = el_store->verts.first; node && node->next; node = node->next) {
+ e_arr[i++] = BM_edge_exists(NODE_AS_V(node), NODE_AS_V(node->next));
+ BLI_assert(e_arr[i - 1] != NULL);
+ }
+
+ if (el_store->flag & BM_EDGELOOP_IS_CLOSED) {
+ e_arr[i] = BM_edge_exists(NODE_AS_V(el_store->verts.first), NODE_AS_V(el_store->verts.last));
+ BLI_assert(e_arr[i] != NULL);
+ }
+ BLI_assert(el_store->len == i + 1);
}
void BM_edgeloop_calc_center(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
{
- LinkData *node_curr = el_store->verts.last;
- LinkData *node_prev = ((LinkData *)el_store->verts.last)->prev;
- LinkData *node_first = el_store->verts.first;
- LinkData *node_next = node_first;
-
- const float *v_prev = NODE_AS_CO(node_prev);
- const float *v_curr = NODE_AS_CO(node_curr);
- const float *v_next = NODE_AS_CO(node_next);
-
- float totw = 0.0f;
- float w_prev;
-
- zero_v3(el_store->co);
-
- w_prev = len_v3v3(v_prev, v_curr);
- do {
- const float w_curr = len_v3v3(v_curr, v_next);
- const float w = (w_curr + w_prev);
- madd_v3_v3fl(el_store->co, v_curr, w);
- totw += w;
- w_prev = w_curr;
-
-
- node_prev = node_curr;
- node_curr = node_next;
- node_next = node_next->next;
-
- if (node_next == NULL) {
- break;
- }
- v_prev = v_curr;
- v_curr = v_next;
- v_next = NODE_AS_CO(node_next);
- } while (1);
-
- if (totw != 0.0f) {
- mul_v3_fl(el_store->co, 1.0f / (float) totw);
- }
-
+ LinkData *node_curr = el_store->verts.last;
+ LinkData *node_prev = ((LinkData *)el_store->verts.last)->prev;
+ LinkData *node_first = el_store->verts.first;
+ LinkData *node_next = node_first;
+
+ const float *v_prev = NODE_AS_CO(node_prev);
+ const float *v_curr = NODE_AS_CO(node_curr);
+ const float *v_next = NODE_AS_CO(node_next);
+
+ float totw = 0.0f;
+ float w_prev;
+
+ zero_v3(el_store->co);
+
+ w_prev = len_v3v3(v_prev, v_curr);
+ do {
+ const float w_curr = len_v3v3(v_curr, v_next);
+ const float w = (w_curr + w_prev);
+ madd_v3_v3fl(el_store->co, v_curr, w);
+ totw += w;
+ w_prev = w_curr;
+
+ node_prev = node_curr;
+ node_curr = node_next;
+ node_next = node_next->next;
+
+ if (node_next == NULL) {
+ break;
+ }
+ v_prev = v_curr;
+ v_curr = v_next;
+ v_next = NODE_AS_CO(node_next);
+ } while (1);
+
+ if (totw != 0.0f) {
+ mul_v3_fl(el_store->co, 1.0f / (float)totw);
+ }
}
bool BM_edgeloop_calc_normal(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
{
- LinkData *node_curr = el_store->verts.first;
- const float *v_prev = NODE_AS_CO(el_store->verts.last);
- const float *v_curr = NODE_AS_CO(node_curr);
-
- zero_v3(el_store->no);
-
- /* Newell's Method */
- do {
- add_newell_cross_v3_v3v3(el_store->no, v_prev, v_curr);
-
- if ((node_curr = node_curr->next)) {
- v_prev = v_curr;
- v_curr = NODE_AS_CO(node_curr);
- }
- else {
- break;
- }
- } while (true);
-
- if (UNLIKELY(normalize_v3(el_store->no) < EDGELOOP_EPS)) {
- el_store->no[2] = 1.0f; /* other axis set to 0.0 */
- return false;
-
- }
- else {
- return true;
- }
+ LinkData *node_curr = el_store->verts.first;
+ const float *v_prev = NODE_AS_CO(el_store->verts.last);
+ const float *v_curr = NODE_AS_CO(node_curr);
+
+ zero_v3(el_store->no);
+
+ /* Newell's Method */
+ do {
+ add_newell_cross_v3_v3v3(el_store->no, v_prev, v_curr);
+
+ if ((node_curr = node_curr->next)) {
+ v_prev = v_curr;
+ v_curr = NODE_AS_CO(node_curr);
+ }
+ else {
+ break;
+ }
+ } while (true);
+
+ if (UNLIKELY(normalize_v3(el_store->no) < EDGELOOP_EPS)) {
+ el_store->no[2] = 1.0f; /* other axis set to 0.0 */
+ return false;
+ }
+ else {
+ return true;
+ }
}
/**
@@ -663,159 +658,164 @@ bool BM_edgeloop_calc_normal(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
*
* Instead use an alignment vector and calculate the normal based on that.
*/
-bool BM_edgeloop_calc_normal_aligned(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store, const float no_align[3])
+bool BM_edgeloop_calc_normal_aligned(BMesh *UNUSED(bm),
+ BMEdgeLoopStore *el_store,
+ const float no_align[3])
{
- LinkData *node_curr = el_store->verts.first;
- const float *v_prev = NODE_AS_CO(el_store->verts.last);
- const float *v_curr = NODE_AS_CO(node_curr);
-
- zero_v3(el_store->no);
-
- /* Own Method */
- do {
- float cross[3], no[3], dir[3];
- sub_v3_v3v3(dir, v_curr, v_prev);
- cross_v3_v3v3(cross, no_align, dir);
- cross_v3_v3v3(no, dir, cross);
- add_v3_v3(el_store->no, no);
-
- if ((node_curr = node_curr->next)) {
- v_prev = v_curr;
- v_curr = NODE_AS_CO(node_curr);
- }
- else {
- break;
- }
- } while (true);
-
- if (UNLIKELY(normalize_v3(el_store->no) < EDGELOOP_EPS)) {
- el_store->no[2] = 1.0f; /* other axis set to 0.0 */
- return false;
- }
- else {
- return true;
- }
+ LinkData *node_curr = el_store->verts.first;
+ const float *v_prev = NODE_AS_CO(el_store->verts.last);
+ const float *v_curr = NODE_AS_CO(node_curr);
+
+ zero_v3(el_store->no);
+
+ /* Own Method */
+ do {
+ float cross[3], no[3], dir[3];
+ sub_v3_v3v3(dir, v_curr, v_prev);
+ cross_v3_v3v3(cross, no_align, dir);
+ cross_v3_v3v3(no, dir, cross);
+ add_v3_v3(el_store->no, no);
+
+ if ((node_curr = node_curr->next)) {
+ v_prev = v_curr;
+ v_curr = NODE_AS_CO(node_curr);
+ }
+ else {
+ break;
+ }
+ } while (true);
+
+ if (UNLIKELY(normalize_v3(el_store->no) < EDGELOOP_EPS)) {
+ el_store->no[2] = 1.0f; /* other axis set to 0.0 */
+ return false;
+ }
+ else {
+ return true;
+ }
}
-
-
void BM_edgeloop_flip(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store)
{
- negate_v3(el_store->no);
- BLI_listbase_reverse(&el_store->verts);
+ negate_v3(el_store->no);
+ BLI_listbase_reverse(&el_store->verts);
}
void BM_edgeloop_expand(
- BMesh *bm, BMEdgeLoopStore *el_store, int el_store_len,
- bool split, GSet *split_edges)
+ BMesh *bm, BMEdgeLoopStore *el_store, int el_store_len, bool split, GSet *split_edges)
{
- bool split_swap = true;
-
-#define EDGE_SPLIT(node_copy, node_other) { \
- BMVert *v_split, *v_other = (node_other)->data; \
- BMEdge *e_split, *e_other = BM_edge_exists((node_copy)->data, v_other); \
- v_split = BM_edge_split(bm, e_other, split_swap ? (node_copy)->data : v_other, &e_split, 0.0f); \
- v_split->e = e_split; \
- BLI_assert(v_split == e_split->v2); \
- BLI_gset_insert(split_edges, e_split); \
- (node_copy)->data = v_split; \
- } ((void)0)
-
- /* first double until we are more than half as big */
- while ((el_store->len * 2) < el_store_len) {
- LinkData *node_curr = el_store->verts.first;
- while (node_curr) {
- LinkData *node_curr_copy = MEM_dupallocN(node_curr);
- if (split == false) {
- BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy);
- node_curr = node_curr_copy->next;
- }
- else {
- if (node_curr->next || (el_store->flag & BM_EDGELOOP_IS_CLOSED)) {
- EDGE_SPLIT(node_curr_copy, node_curr->next ? node_curr->next : (LinkData *)el_store->verts.first);
- BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy);
- node_curr = node_curr_copy->next;
- }
- else {
- EDGE_SPLIT(node_curr_copy, node_curr->prev);
- BLI_insertlinkbefore(&el_store->verts, node_curr, node_curr_copy);
- node_curr = node_curr->next;
- }
- split_swap = !split_swap;
- }
- el_store->len++;
- }
- split_swap = !split_swap;
- }
-
- if (el_store->len < el_store_len) {
- LinkData *node_curr = el_store->verts.first;
-
- int iter_prev = 0;
- BLI_FOREACH_SPARSE_RANGE(el_store->len, (el_store_len - el_store->len), iter) {
- while (iter_prev < iter) {
- node_curr = node_curr->next;
- iter_prev += 1;
- }
-
- LinkData *node_curr_copy;
- node_curr_copy = MEM_dupallocN(node_curr);
- if (split == false) {
- BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy);
- node_curr = node_curr_copy->next;
- }
- else {
- if (node_curr->next || (el_store->flag & BM_EDGELOOP_IS_CLOSED)) {
- EDGE_SPLIT(node_curr_copy,
- node_curr->next ? node_curr->next : (LinkData *)el_store->verts.first);
- BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy);
- node_curr = node_curr_copy->next;
- }
- else {
- EDGE_SPLIT(node_curr_copy, node_curr->prev);
- BLI_insertlinkbefore(&el_store->verts, node_curr, node_curr_copy);
- node_curr = node_curr->next;
- }
- split_swap = !split_swap;
- }
- el_store->len++;
- iter_prev += 1;
- }
- }
+ bool split_swap = true;
+
+#define EDGE_SPLIT(node_copy, node_other) \
+ { \
+ BMVert *v_split, *v_other = (node_other)->data; \
+ BMEdge *e_split, *e_other = BM_edge_exists((node_copy)->data, v_other); \
+ v_split = BM_edge_split( \
+ bm, e_other, split_swap ? (node_copy)->data : v_other, &e_split, 0.0f); \
+ v_split->e = e_split; \
+ BLI_assert(v_split == e_split->v2); \
+ BLI_gset_insert(split_edges, e_split); \
+ (node_copy)->data = v_split; \
+ } \
+ ((void)0)
+
+ /* first double until we are more than half as big */
+ while ((el_store->len * 2) < el_store_len) {
+ LinkData *node_curr = el_store->verts.first;
+ while (node_curr) {
+ LinkData *node_curr_copy = MEM_dupallocN(node_curr);
+ if (split == false) {
+ BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy);
+ node_curr = node_curr_copy->next;
+ }
+ else {
+ if (node_curr->next || (el_store->flag & BM_EDGELOOP_IS_CLOSED)) {
+ EDGE_SPLIT(node_curr_copy,
+ node_curr->next ? node_curr->next : (LinkData *)el_store->verts.first);
+ BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy);
+ node_curr = node_curr_copy->next;
+ }
+ else {
+ EDGE_SPLIT(node_curr_copy, node_curr->prev);
+ BLI_insertlinkbefore(&el_store->verts, node_curr, node_curr_copy);
+ node_curr = node_curr->next;
+ }
+ split_swap = !split_swap;
+ }
+ el_store->len++;
+ }
+ split_swap = !split_swap;
+ }
+
+ if (el_store->len < el_store_len) {
+ LinkData *node_curr = el_store->verts.first;
+
+ int iter_prev = 0;
+ BLI_FOREACH_SPARSE_RANGE(el_store->len, (el_store_len - el_store->len), iter)
+ {
+ while (iter_prev < iter) {
+ node_curr = node_curr->next;
+ iter_prev += 1;
+ }
+
+ LinkData *node_curr_copy;
+ node_curr_copy = MEM_dupallocN(node_curr);
+ if (split == false) {
+ BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy);
+ node_curr = node_curr_copy->next;
+ }
+ else {
+ if (node_curr->next || (el_store->flag & BM_EDGELOOP_IS_CLOSED)) {
+ EDGE_SPLIT(node_curr_copy,
+ node_curr->next ? node_curr->next : (LinkData *)el_store->verts.first);
+ BLI_insertlinkafter(&el_store->verts, node_curr, node_curr_copy);
+ node_curr = node_curr_copy->next;
+ }
+ else {
+ EDGE_SPLIT(node_curr_copy, node_curr->prev);
+ BLI_insertlinkbefore(&el_store->verts, node_curr, node_curr_copy);
+ node_curr = node_curr->next;
+ }
+ split_swap = !split_swap;
+ }
+ el_store->len++;
+ iter_prev += 1;
+ }
+ }
#undef BKE_FOREACH_SUBSET_OF_RANGE
#undef EDGE_SPLIT
- BLI_assert(el_store->len == el_store_len);
+ BLI_assert(el_store->len == el_store_len);
}
-bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a, struct BMEdgeLoopStore *el_store_b)
+bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a,
+ struct BMEdgeLoopStore *el_store_b)
{
- LinkData *node;
-
- /* A little more efficient if 'a' as smaller. */
- if (el_store_a->len > el_store_b->len) {
- SWAP(BMEdgeLoopStore *, el_store_a, el_store_b);
- }
-
- /* init */
- for (node = el_store_a->verts.first; node; node = node->next) {
- BM_elem_flag_enable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
- }
- for (node = el_store_b->verts.first; node; node = node->next) {
- BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
- }
-
- /* Check 'a' (clear as we go). */
- for (node = el_store_a->verts.first; node; node = node->next) {
- if (!BM_elem_flag_test((BMVert *)node->data, BM_ELEM_INTERNAL_TAG)) {
- /* Finish clearing 'a', leave tag clean. */
- while ((node = node->next)) {
- BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
- }
- return true;
- }
- BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
- }
- return false;
+ LinkData *node;
+
+ /* A little more efficient if 'a' as smaller. */
+ if (el_store_a->len > el_store_b->len) {
+ SWAP(BMEdgeLoopStore *, el_store_a, el_store_b);
+ }
+
+ /* init */
+ for (node = el_store_a->verts.first; node; node = node->next) {
+ BM_elem_flag_enable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
+ }
+ for (node = el_store_b->verts.first; node; node = node->next) {
+ BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
+ }
+
+ /* Check 'a' (clear as we go). */
+ for (node = el_store_a->verts.first; node; node = node->next) {
+ if (!BM_elem_flag_test((BMVert *)node->data, BM_ELEM_INTERNAL_TAG)) {
+ /* Finish clearing 'a', leave tag clean. */
+ while ((node = node->next)) {
+ BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
+ }
+ return true;
+ }
+ BM_elem_flag_disable((BMVert *)node->data, BM_ELEM_INTERNAL_TAG);
+ }
+ return false;
}
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.h b/source/blender/bmesh/intern/bmesh_edgeloop.h
index e21a62bc25f..7701c680ae9 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.h
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.h
@@ -29,51 +29,60 @@ struct GSet;
struct ListBase;
/* multiple edgeloops (ListBase) */
-int BM_mesh_edgeloops_find(
- BMesh *bm, struct ListBase *r_lb,
- bool (*test_fn)(BMEdge *, void *user_data), void *user_data);
-bool BM_mesh_edgeloops_find_path(
- BMesh *bm, ListBase *r_eloops,
- bool (*test_fn)(BMEdge *, void *user_data), void *user_data,
- BMVert *v_src, BMVert *v_dst);
-
-void BM_mesh_edgeloops_free(struct ListBase *eloops);
-void BM_mesh_edgeloops_calc_center(BMesh *bm, struct ListBase *eloops);
-void BM_mesh_edgeloops_calc_normal(BMesh *bm, struct ListBase *eloops);
-void BM_mesh_edgeloops_calc_normal_aligned(
- BMesh *bm, struct ListBase *eloops,
- const float no_align[3]);
-void BM_mesh_edgeloops_calc_order(BMesh *UNUSED(bm), ListBase *eloops, const bool use_normals);
+int BM_mesh_edgeloops_find(BMesh *bm,
+ struct ListBase *r_lb,
+ bool (*test_fn)(BMEdge *, void *user_data),
+ void *user_data);
+bool BM_mesh_edgeloops_find_path(BMesh *bm,
+ ListBase *r_eloops,
+ bool (*test_fn)(BMEdge *, void *user_data),
+ void *user_data,
+ BMVert *v_src,
+ BMVert *v_dst);
+void BM_mesh_edgeloops_free(struct ListBase *eloops);
+void BM_mesh_edgeloops_calc_center(BMesh *bm, struct ListBase *eloops);
+void BM_mesh_edgeloops_calc_normal(BMesh *bm, struct ListBase *eloops);
+void BM_mesh_edgeloops_calc_normal_aligned(BMesh *bm,
+ struct ListBase *eloops,
+ const float no_align[3]);
+void BM_mesh_edgeloops_calc_order(BMesh *UNUSED(bm), ListBase *eloops, const bool use_normals);
/* single edgeloop */
struct BMEdgeLoopStore *BM_edgeloop_copy(struct BMEdgeLoopStore *el_store);
-struct BMEdgeLoopStore *BM_edgeloop_from_verts(BMVert **v_arr, const int v_arr_tot, bool is_closed);
+struct BMEdgeLoopStore *BM_edgeloop_from_verts(BMVert **v_arr,
+ const int v_arr_tot,
+ bool is_closed);
-void BM_edgeloop_free(struct BMEdgeLoopStore *el_store);
-bool BM_edgeloop_is_closed(struct BMEdgeLoopStore *el_store);
-int BM_edgeloop_length_get(struct BMEdgeLoopStore *el_store);
-struct ListBase *BM_edgeloop_verts_get(struct BMEdgeLoopStore *el_store);
-const float *BM_edgeloop_normal_get(struct BMEdgeLoopStore *el_store);
-const float *BM_edgeloop_center_get(struct BMEdgeLoopStore *el_store);
-void BM_edgeloop_edges_get(struct BMEdgeLoopStore *el_store, BMEdge **e_arr);
-void BM_edgeloop_calc_center(BMesh *bm, struct BMEdgeLoopStore *el_store);
-bool BM_edgeloop_calc_normal(BMesh *bm, struct BMEdgeLoopStore *el_store);
-bool BM_edgeloop_calc_normal_aligned(
- BMesh *bm, struct BMEdgeLoopStore *el_store,
- const float no_align[3]);
-void BM_edgeloop_flip(BMesh *bm, struct BMEdgeLoopStore *el_store);
-void BM_edgeloop_expand(
- BMesh *bm, struct BMEdgeLoopStore *el_store, int el_store_len,
- bool split, struct GSet *split_edges);
+void BM_edgeloop_free(struct BMEdgeLoopStore *el_store);
+bool BM_edgeloop_is_closed(struct BMEdgeLoopStore *el_store);
+int BM_edgeloop_length_get(struct BMEdgeLoopStore *el_store);
+struct ListBase *BM_edgeloop_verts_get(struct BMEdgeLoopStore *el_store);
+const float *BM_edgeloop_normal_get(struct BMEdgeLoopStore *el_store);
+const float *BM_edgeloop_center_get(struct BMEdgeLoopStore *el_store);
+void BM_edgeloop_edges_get(struct BMEdgeLoopStore *el_store, BMEdge **e_arr);
+void BM_edgeloop_calc_center(BMesh *bm, struct BMEdgeLoopStore *el_store);
+bool BM_edgeloop_calc_normal(BMesh *bm, struct BMEdgeLoopStore *el_store);
+bool BM_edgeloop_calc_normal_aligned(BMesh *bm,
+ struct BMEdgeLoopStore *el_store,
+ const float no_align[3]);
+void BM_edgeloop_flip(BMesh *bm, struct BMEdgeLoopStore *el_store);
+void BM_edgeloop_expand(BMesh *bm,
+ struct BMEdgeLoopStore *el_store,
+ int el_store_len,
+ bool split,
+ struct GSet *split_edges);
-bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a, struct BMEdgeLoopStore *el_store_b);
+bool BM_edgeloop_overlap_check(struct BMEdgeLoopStore *el_store_a,
+ struct BMEdgeLoopStore *el_store_b);
#define BM_EDGELINK_NEXT(el_store, elink) \
- (elink)->next ? elink->next : (BM_edgeloop_is_closed(el_store) ? BM_edgeloop_verts_get(el_store)->first : NULL)
+ (elink)->next ? \
+ elink->next : \
+ (BM_edgeloop_is_closed(el_store) ? BM_edgeloop_verts_get(el_store)->first : NULL)
#define BM_EDGELOOP_NEXT(el_store) \
- (CHECK_TYPE_INLINE(el_store, struct BMEdgeLoopStore *), \
- (struct BMEdgeLoopStore *)((LinkData *)el_store)->next)
+ (CHECK_TYPE_INLINE(el_store, struct BMEdgeLoopStore *), \
+ (struct BMEdgeLoopStore *)((LinkData *)el_store)->next)
-#endif /* __BMESH_EDGELOOP_H__ */
+#endif /* __BMESH_EDGELOOP_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_error.h b/source/blender/bmesh/intern/bmesh_error.h
index 0035a43dc1e..b5235c64215 100644
--- a/source/blender/bmesh/intern/bmesh_error.h
+++ b/source/blender/bmesh/intern/bmesh_error.h
@@ -29,11 +29,11 @@ void BMO_error_raise(BMesh *bm, BMOperator *owner, int errcode, const char *msg)
/* gets the topmost error from the stack.
* returns error code or 0 if no error.*/
-int BMO_error_get(BMesh *bm, const char **msg, BMOperator **op);
+int BMO_error_get(BMesh *bm, const char **msg, BMOperator **op);
bool BMO_error_occurred(BMesh *bm);
/* same as geterror, only pops the error off the stack as well */
-int BMO_error_pop(BMesh *bm, const char **msg, BMOperator **op);
+int BMO_error_pop(BMesh *bm, const char **msg, BMOperator **op);
void BMO_error_clear(BMesh *bm);
/* this is meant for handling errors, like self-intersection test failures.
@@ -48,24 +48,24 @@ void BMO_error_clear(BMesh *bm);
*/
#define BM_ELEM_INDEX_VALIDATE(_bm, _msg_a, _msg_b) \
- BM_mesh_elem_index_validate(_bm, __FILE__ ":" STRINGIFY(__LINE__), __func__, _msg_a, _msg_b)
+ BM_mesh_elem_index_validate(_bm, __FILE__ ":" STRINGIFY(__LINE__), __func__, _msg_a, _msg_b)
/*------ error code defines -------*/
/*error messages*/
enum {
- BMERR_SELF_INTERSECTING = 1,
- BMERR_DISSOLVEDISK_FAILED,
- BMERR_CONNECTVERT_FAILED,
- BMERR_WALKER_FAILED,
- BMERR_DISSOLVEFACES_FAILED,
- BMERR_TESSELLATION,
- BMERR_NONMANIFOLD,
- BMERR_INVALID_SELECTION,
- BMERR_MESH_ERROR,
- BMERR_CONVEX_HULL_FAILED,
-
- BMERR_TOTAL,
+ BMERR_SELF_INTERSECTING = 1,
+ BMERR_DISSOLVEDISK_FAILED,
+ BMERR_CONNECTVERT_FAILED,
+ BMERR_WALKER_FAILED,
+ BMERR_DISSOLVEFACES_FAILED,
+ BMERR_TESSELLATION,
+ BMERR_NONMANIFOLD,
+ BMERR_INVALID_SELECTION,
+ BMERR_MESH_ERROR,
+ BMERR_CONVEX_HULL_FAILED,
+
+ BMERR_TOTAL,
};
/* BMESH_ASSERT */
@@ -77,13 +77,15 @@ enum {
/* this is meant to be higher level then BLI_assert(),
* its enabled even when in Release mode*/
-#define BMESH_ASSERT(a) \
- (void)((!(a)) ? ( \
- ( \
- fprintf(stderr, \
- "BMESH_ASSERT failed: %s, %s(), %d at \'%s\'\n", \
- __FILE__, __func__, __LINE__, STRINGIFY(a)), \
- _BMESH_DUMMY_ABORT(), \
- NULL)) : NULL)
+#define BMESH_ASSERT(a) \
+ (void)((!(a)) ? ((fprintf(stderr, \
+ "BMESH_ASSERT failed: %s, %s(), %d at \'%s\'\n", \
+ __FILE__, \
+ __func__, \
+ __LINE__, \
+ STRINGIFY(a)), \
+ _BMESH_DUMMY_ABORT(), \
+ NULL)) : \
+ NULL)
#endif /* __BMESH_ERROR_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_inline.h b/source/blender/bmesh/intern/bmesh_inline.h
index 549fc90fe40..13691776a27 100644
--- a/source/blender/bmesh/intern/bmesh_inline.h
+++ b/source/blender/bmesh/intern/bmesh_inline.h
@@ -24,66 +24,74 @@
#define __BMESH_INLINE_H__
/* stuff for dealing with header flags */
-#define BM_elem_flag_test( ele, hflag) _bm_elem_flag_test (&(ele)->head, hflag)
-#define BM_elem_flag_test_bool(ele, hflag) _bm_elem_flag_test_bool(&(ele)->head, hflag)
-#define BM_elem_flag_enable( ele, hflag) _bm_elem_flag_enable (&(ele)->head, hflag)
-#define BM_elem_flag_disable( ele, hflag) _bm_elem_flag_disable (&(ele)->head, hflag)
-#define BM_elem_flag_set( ele, hflag, val) _bm_elem_flag_set (&(ele)->head, hflag, val)
-#define BM_elem_flag_toggle( ele, hflag) _bm_elem_flag_toggle (&(ele)->head, hflag)
-#define BM_elem_flag_merge( ele_a, ele_b) _bm_elem_flag_merge (&(ele_a)->head, &(ele_b)->head)
-#define BM_elem_flag_merge_ex( ele_a, ele_b, hflag_and)_bm_elem_flag_merge_ex (&(ele_a)->head, &(ele_b)->head, hflag_and)
-#define BM_elem_flag_merge_into(ele, ele_a, ele_b)_bm_elem_flag_merge_into (&(ele)->head, &(ele_a)->head, &(ele_b)->head)
+#define BM_elem_flag_test(ele, hflag) _bm_elem_flag_test(&(ele)->head, hflag)
+#define BM_elem_flag_test_bool(ele, hflag) _bm_elem_flag_test_bool(&(ele)->head, hflag)
+#define BM_elem_flag_enable(ele, hflag) _bm_elem_flag_enable(&(ele)->head, hflag)
+#define BM_elem_flag_disable(ele, hflag) _bm_elem_flag_disable(&(ele)->head, hflag)
+#define BM_elem_flag_set(ele, hflag, val) _bm_elem_flag_set(&(ele)->head, hflag, val)
+#define BM_elem_flag_toggle(ele, hflag) _bm_elem_flag_toggle(&(ele)->head, hflag)
+#define BM_elem_flag_merge(ele_a, ele_b) _bm_elem_flag_merge(&(ele_a)->head, &(ele_b)->head)
+#define BM_elem_flag_merge_ex(ele_a, ele_b, hflag_and) \
+ _bm_elem_flag_merge_ex(&(ele_a)->head, &(ele_b)->head, hflag_and)
+#define BM_elem_flag_merge_into(ele, ele_a, ele_b) \
+ _bm_elem_flag_merge_into(&(ele)->head, &(ele_a)->head, &(ele_b)->head)
ATTR_WARN_UNUSED_RESULT
BLI_INLINE char _bm_elem_flag_test(const BMHeader *head, const char hflag)
{
- return head->hflag & hflag;
+ return head->hflag & hflag;
}
ATTR_WARN_UNUSED_RESULT
BLI_INLINE bool _bm_elem_flag_test_bool(const BMHeader *head, const char hflag)
{
- return (head->hflag & hflag) != 0;
+ return (head->hflag & hflag) != 0;
}
BLI_INLINE void _bm_elem_flag_enable(BMHeader *head, const char hflag)
{
- head->hflag |= hflag;
+ head->hflag |= hflag;
}
BLI_INLINE void _bm_elem_flag_disable(BMHeader *head, const char hflag)
{
- head->hflag &= (char)~hflag;
+ head->hflag &= (char)~hflag;
}
BLI_INLINE void _bm_elem_flag_set(BMHeader *head, const char hflag, const int val)
{
- if (val) { _bm_elem_flag_enable(head, hflag); }
- else { _bm_elem_flag_disable(head, hflag); }
+ if (val) {
+ _bm_elem_flag_enable(head, hflag);
+ }
+ else {
+ _bm_elem_flag_disable(head, hflag);
+ }
}
BLI_INLINE void _bm_elem_flag_toggle(BMHeader *head, const char hflag)
{
- head->hflag ^= hflag;
+ head->hflag ^= hflag;
}
BLI_INLINE void _bm_elem_flag_merge(BMHeader *head_a, BMHeader *head_b)
{
- head_a->hflag = head_b->hflag = head_a->hflag | head_b->hflag;
+ head_a->hflag = head_b->hflag = head_a->hflag | head_b->hflag;
}
BLI_INLINE void _bm_elem_flag_merge_ex(BMHeader *head_a, BMHeader *head_b, const char hflag_and)
{
- if (((head_a->hflag & head_b->hflag) & hflag_and) == 0) {
- head_a->hflag &= ~hflag_and;
- head_b->hflag &= ~hflag_and;
- }
- _bm_elem_flag_merge(head_a, head_b);
+ if (((head_a->hflag & head_b->hflag) & hflag_and) == 0) {
+ head_a->hflag &= ~hflag_and;
+ head_b->hflag &= ~hflag_and;
+ }
+ _bm_elem_flag_merge(head_a, head_b);
}
-BLI_INLINE void _bm_elem_flag_merge_into(BMHeader *head, const BMHeader *head_a, const BMHeader *head_b)
+BLI_INLINE void _bm_elem_flag_merge_into(BMHeader *head,
+ const BMHeader *head_a,
+ const BMHeader *head_b)
{
- head->hflag = head_a->hflag | head_b->hflag;
+ head->hflag = head_a->hflag | head_b->hflag;
}
/**
@@ -114,18 +122,18 @@ BLI_INLINE void _bm_elem_flag_merge_into(BMHeader *head, const BMHeader *head_a,
*
* - campbell */
-#define BM_elem_index_get(ele) _bm_elem_index_get(&(ele)->head)
-#define BM_elem_index_set(ele, index) _bm_elem_index_set(&(ele)->head, index)
+#define BM_elem_index_get(ele) _bm_elem_index_get(&(ele)->head)
+#define BM_elem_index_set(ele, index) _bm_elem_index_set(&(ele)->head, index)
BLI_INLINE void _bm_elem_index_set(BMHeader *head, const int index)
{
- head->index = index;
+ head->index = index;
}
ATTR_WARN_UNUSED_RESULT
BLI_INLINE int _bm_elem_index_get(const BMHeader *head)
{
- return head->index;
+ return head->index;
}
#endif /* __BMESH_INLINE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 11d6df430c3..c58521297dd 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -40,41 +40,45 @@
#include "intern/bmesh_private.h"
/* edge and vertex share, currently theres no need to have different logic */
-static void bm_data_interp_from_elem(
- CustomData *data_layer, const BMElem *ele_src_1, const BMElem *ele_src_2,
- BMElem *ele_dst, const float fac)
+static void bm_data_interp_from_elem(CustomData *data_layer,
+ const BMElem *ele_src_1,
+ const BMElem *ele_src_2,
+ BMElem *ele_dst,
+ const float fac)
{
- if (ele_src_1->head.data && ele_src_2->head.data) {
- /* first see if we can avoid interpolation */
- if (fac <= 0.0f) {
- if (ele_src_1 == ele_dst) {
- /* do nothing */
- }
- else {
- CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
- CustomData_bmesh_copy_data(data_layer, data_layer, ele_src_1->head.data, &ele_dst->head.data);
- }
- }
- else if (fac >= 1.0f) {
- if (ele_src_2 == ele_dst) {
- /* do nothing */
- }
- else {
- CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
- CustomData_bmesh_copy_data(data_layer, data_layer, ele_src_2->head.data, &ele_dst->head.data);
- }
- }
- else {
- const void *src[2];
- float w[2];
-
- src[0] = ele_src_1->head.data;
- src[1] = ele_src_2->head.data;
- w[0] = 1.0f - fac;
- w[1] = fac;
- CustomData_bmesh_interp(data_layer, src, w, NULL, 2, ele_dst->head.data);
- }
- }
+ if (ele_src_1->head.data && ele_src_2->head.data) {
+ /* first see if we can avoid interpolation */
+ if (fac <= 0.0f) {
+ if (ele_src_1 == ele_dst) {
+ /* do nothing */
+ }
+ else {
+ CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
+ CustomData_bmesh_copy_data(
+ data_layer, data_layer, ele_src_1->head.data, &ele_dst->head.data);
+ }
+ }
+ else if (fac >= 1.0f) {
+ if (ele_src_2 == ele_dst) {
+ /* do nothing */
+ }
+ else {
+ CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
+ CustomData_bmesh_copy_data(
+ data_layer, data_layer, ele_src_2->head.data, &ele_dst->head.data);
+ }
+ }
+ else {
+ const void *src[2];
+ float w[2];
+
+ src[0] = ele_src_1->head.data;
+ src[1] = ele_src_2->head.data;
+ w[0] = 1.0f - fac;
+ w[1] = fac;
+ CustomData_bmesh_interp(data_layer, src, w, NULL, 2, ele_dst->head.data);
+ }
+ }
}
/**
@@ -84,9 +88,11 @@ static void bm_data_interp_from_elem(
*
* \note This is an exact match to #BM_data_interp_from_edges
*/
-void BM_data_interp_from_verts(BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v_dst, const float fac)
+void BM_data_interp_from_verts(
+ BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v_dst, const float fac)
{
- bm_data_interp_from_elem(&bm->vdata, (const BMElem *)v_src_1, (const BMElem *)v_src_2, (BMElem *)v_dst, fac);
+ bm_data_interp_from_elem(
+ &bm->vdata, (const BMElem *)v_src_1, (const BMElem *)v_src_2, (BMElem *)v_dst, fac);
}
/**
@@ -96,9 +102,11 @@ void BM_data_interp_from_verts(BMesh *bm, const BMVert *v_src_1, const BMVert *v
*
* \note This is an exact match to #BM_data_interp_from_verts
*/
-void BM_data_interp_from_edges(BMesh *bm, const BMEdge *e_src_1, const BMEdge *e_src_2, BMEdge *e_dst, const float fac)
+void BM_data_interp_from_edges(
+ BMesh *bm, const BMEdge *e_src_1, const BMEdge *e_src_2, BMEdge *e_dst, const float fac)
{
- bm_data_interp_from_elem(&bm->edata, (const BMElem *)e_src_1, (const BMElem *)e_src_2, (BMElem *)e_dst, fac);
+ bm_data_interp_from_elem(
+ &bm->edata, (const BMElem *)e_src_1, (const BMElem *)e_src_2, (BMElem *)e_dst, fac);
}
/**
@@ -109,7 +117,7 @@ void BM_data_interp_from_edges(BMesh *bm, const BMEdge *e_src_1, const BMEdge *e
*/
static void UNUSED_FUNCTION(BM_Data_Vert_Average)(BMesh *UNUSED(bm), BMFace *UNUSED(f))
{
- // BMIter iter;
+ // BMIter iter;
}
/**
@@ -118,44 +126,48 @@ static void UNUSED_FUNCTION(BM_Data_Vert_Average)(BMesh *UNUSED(bm), BMFace *UNU
* Walks around the faces of \a e and interpolates
* the loop data between two sources.
*/
-void BM_data_interp_face_vert_edge(
- BMesh *bm, const BMVert *v_src_1, const BMVert *UNUSED(v_src_2), BMVert *v, BMEdge *e, const float fac)
+void BM_data_interp_face_vert_edge(BMesh *bm,
+ const BMVert *v_src_1,
+ const BMVert *UNUSED(v_src_2),
+ BMVert *v,
+ BMEdge *e,
+ const float fac)
{
- float w[2];
- BMLoop *l_v1 = NULL, *l_v = NULL, *l_v2 = NULL;
- BMLoop *l_iter = NULL;
-
- if (!e->l) {
- return;
- }
-
- w[1] = 1.0f - fac;
- w[0] = fac;
-
- l_iter = e->l;
- do {
- if (l_iter->v == v_src_1) {
- l_v1 = l_iter;
- l_v = l_v1->next;
- l_v2 = l_v->next;
- }
- else if (l_iter->v == v) {
- l_v1 = l_iter->next;
- l_v = l_iter;
- l_v2 = l_iter->prev;
- }
-
- if (!l_v1 || !l_v2) {
- return;
- }
- else {
- const void *src[2];
- src[0] = l_v1->head.data;
- src[1] = l_v2->head.data;
-
- CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_v->head.data);
- }
- } while ((l_iter = l_iter->radial_next) != e->l);
+ float w[2];
+ BMLoop *l_v1 = NULL, *l_v = NULL, *l_v2 = NULL;
+ BMLoop *l_iter = NULL;
+
+ if (!e->l) {
+ return;
+ }
+
+ w[1] = 1.0f - fac;
+ w[0] = fac;
+
+ l_iter = e->l;
+ do {
+ if (l_iter->v == v_src_1) {
+ l_v1 = l_iter;
+ l_v = l_v1->next;
+ l_v2 = l_v->next;
+ }
+ else if (l_iter->v == v) {
+ l_v1 = l_iter->next;
+ l_v = l_iter;
+ l_v2 = l_iter->prev;
+ }
+
+ if (!l_v1 || !l_v2) {
+ return;
+ }
+ else {
+ const void *src[2];
+ src[0] = l_v1->head.data;
+ src[1] = l_v2->head.data;
+
+ CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, l_v->head.data);
+ }
+ } while ((l_iter = l_iter->radial_next) != e->l);
}
/**
@@ -166,61 +178,65 @@ void BM_data_interp_face_vert_edge(
*
* \note Only handles loop customdata. multires is handled.
*/
-void BM_face_interp_from_face_ex(
- BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex,
- const void **blocks_l, const void **blocks_v, float (*cos_2d)[2], float axis_mat[3][3])
+void BM_face_interp_from_face_ex(BMesh *bm,
+ BMFace *f_dst,
+ const BMFace *f_src,
+ const bool do_vertex,
+ const void **blocks_l,
+ const void **blocks_v,
+ float (*cos_2d)[2],
+ float axis_mat[3][3])
{
- BMLoop *l_iter;
- BMLoop *l_first;
-
- float *w = BLI_array_alloca(w, f_src->len);
- float co[2];
- int i;
-
- if (f_src != f_dst) {
- BM_elem_attrs_copy(bm, bm, f_src, f_dst);
- }
-
- /* interpolate */
- i = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst);
- do {
- mul_v2_m3v3(co, axis_mat, l_iter->v->co);
- interp_weights_poly_v2(w, cos_2d, f_src->len, co);
- CustomData_bmesh_interp(&bm->ldata, blocks_l, w, NULL, f_src->len, l_iter->head.data);
- if (do_vertex) {
- CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, f_src->len, l_iter->v->head.data);
- }
- } while ((void)i++, (l_iter = l_iter->next) != l_first);
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ float *w = BLI_array_alloca(w, f_src->len);
+ float co[2];
+ int i;
+
+ if (f_src != f_dst) {
+ BM_elem_attrs_copy(bm, bm, f_src, f_dst);
+ }
+
+ /* interpolate */
+ i = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst);
+ do {
+ mul_v2_m3v3(co, axis_mat, l_iter->v->co);
+ interp_weights_poly_v2(w, cos_2d, f_src->len, co);
+ CustomData_bmesh_interp(&bm->ldata, blocks_l, w, NULL, f_src->len, l_iter->head.data);
+ if (do_vertex) {
+ CustomData_bmesh_interp(&bm->vdata, blocks_v, w, NULL, f_src->len, l_iter->v->head.data);
+ }
+ } while ((void)i++, (l_iter = l_iter->next) != l_first);
}
void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex)
{
- BMLoop *l_iter;
- BMLoop *l_first;
-
- const void **blocks_l = BLI_array_alloca(blocks_l, f_src->len);
- const void **blocks_v = do_vertex ? BLI_array_alloca(blocks_v, f_src->len) : NULL;
- float (*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
- float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
- int i;
-
- /* convert the 3d coords into 2d for projection */
- BLI_assert(BM_face_is_normal_valid(f_src));
- axis_dominant_v3_to_m3(axis_mat, f_src->no);
-
- i = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
- do {
- mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
- blocks_l[i] = l_iter->head.data;
- if (do_vertex) {
- blocks_v[i] = l_iter->v->head.data;
- }
- } while ((void)i++, (l_iter = l_iter->next) != l_first);
-
- BM_face_interp_from_face_ex(bm, f_dst, f_src, do_vertex,
- blocks_l, blocks_v, cos_2d, axis_mat);
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ const void **blocks_l = BLI_array_alloca(blocks_l, f_src->len);
+ const void **blocks_v = do_vertex ? BLI_array_alloca(blocks_v, f_src->len) : NULL;
+ float(*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
+ float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
+ int i;
+
+ /* convert the 3d coords into 2d for projection */
+ BLI_assert(BM_face_is_normal_valid(f_src));
+ axis_dominant_v3_to_m3(axis_mat, f_src->no);
+
+ i = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
+ do {
+ mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
+ blocks_l[i] = l_iter->head.data;
+ if (do_vertex) {
+ blocks_v[i] = l_iter->v->head.data;
+ }
+ } while ((void)i++, (l_iter = l_iter->next) != l_first);
+
+ BM_face_interp_from_face_ex(bm, f_dst, f_src, do_vertex, blocks_l, blocks_v, cos_2d, axis_mat);
}
/**
@@ -237,283 +253,318 @@ void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, con
* y
* </pre>
*/
-static int compute_mdisp_quad(
- const BMLoop *l, const float l_f_center[3],
- float v1[3], float v2[3], float v3[3], float v4[3],
- float e1[3], float e2[3])
+static int compute_mdisp_quad(const BMLoop *l,
+ const float l_f_center[3],
+ float v1[3],
+ float v2[3],
+ float v3[3],
+ float v4[3],
+ float e1[3],
+ float e2[3])
{
- float n[3], p[3];
+ float n[3], p[3];
#ifndef NDEBUG
- {
- float cent[3];
- /* computer center */
- BM_face_calc_center_median(l->f, cent);
- BLI_assert(equals_v3v3(cent, l_f_center));
- }
+ {
+ float cent[3];
+ /* computer center */
+ BM_face_calc_center_median(l->f, cent);
+ BLI_assert(equals_v3v3(cent, l_f_center));
+ }
#endif
- mid_v3_v3v3(p, l->prev->v->co, l->v->co);
- mid_v3_v3v3(n, l->next->v->co, l->v->co);
+ mid_v3_v3v3(p, l->prev->v->co, l->v->co);
+ mid_v3_v3v3(n, l->next->v->co, l->v->co);
- copy_v3_v3(v1, l_f_center);
- copy_v3_v3(v2, p);
- copy_v3_v3(v3, l->v->co);
- copy_v3_v3(v4, n);
+ copy_v3_v3(v1, l_f_center);
+ copy_v3_v3(v2, p);
+ copy_v3_v3(v3, l->v->co);
+ copy_v3_v3(v4, n);
- sub_v3_v3v3(e1, v2, v1);
- sub_v3_v3v3(e2, v3, v4);
+ sub_v3_v3v3(e1, v2, v1);
+ sub_v3_v3v3(e2, v3, v4);
- return 1;
+ return 1;
}
-static bool quad_co(
- const float v1[3], const float v2[3], const float v3[3], const float v4[3],
- const float p[3], const float n[3],
- float r_uv[2])
+static bool quad_co(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float v4[3],
+ const float p[3],
+ const float n[3],
+ float r_uv[2])
{
- float projverts[5][3], n2[3];
- float origin[2] = {0.0f, 0.0f};
- int i;
+ float projverts[5][3], n2[3];
+ float origin[2] = {0.0f, 0.0f};
+ int i;
- /* project points into 2d along normal */
- copy_v3_v3(projverts[0], v1);
- copy_v3_v3(projverts[1], v2);
- copy_v3_v3(projverts[2], v3);
- copy_v3_v3(projverts[3], v4);
- copy_v3_v3(projverts[4], p);
+ /* project points into 2d along normal */
+ copy_v3_v3(projverts[0], v1);
+ copy_v3_v3(projverts[1], v2);
+ copy_v3_v3(projverts[2], v3);
+ copy_v3_v3(projverts[3], v4);
+ copy_v3_v3(projverts[4], p);
- normal_quad_v3(n2, projverts[0], projverts[1], projverts[2], projverts[3]);
+ normal_quad_v3(n2, projverts[0], projverts[1], projverts[2], projverts[3]);
- if (dot_v3v3(n, n2) < -FLT_EPSILON) {
- return false;
- }
+ if (dot_v3v3(n, n2) < -FLT_EPSILON) {
+ return false;
+ }
- /* rotate */
- poly_rotate_plane(n, projverts, 5);
+ /* rotate */
+ poly_rotate_plane(n, projverts, 5);
- /* subtract origin */
- for (i = 0; i < 4; i++) {
- sub_v2_v2(projverts[i], projverts[4]);
- }
+ /* subtract origin */
+ for (i = 0; i < 4; i++) {
+ sub_v2_v2(projverts[i], projverts[4]);
+ }
- if (!isect_point_quad_v2(origin, projverts[0], projverts[1], projverts[2], projverts[3])) {
- return false;
- }
+ if (!isect_point_quad_v2(origin, projverts[0], projverts[1], projverts[2], projverts[3])) {
+ return false;
+ }
- resolve_quad_uv_v2(r_uv, origin, projverts[0], projverts[3], projverts[2], projverts[1]);
+ resolve_quad_uv_v2(r_uv, origin, projverts[0], projverts[3], projverts[2], projverts[1]);
- return true;
+ return true;
}
-static void mdisp_axis_from_quad(
- float v1[3], float v2[3], float UNUSED(v3[3]), float v4[3],
- float r_axis_x[3], float r_axis_y[3])
+static void mdisp_axis_from_quad(float v1[3],
+ float v2[3],
+ float UNUSED(v3[3]),
+ float v4[3],
+ float r_axis_x[3],
+ float r_axis_y[3])
{
- sub_v3_v3v3(r_axis_x, v4, v1);
- sub_v3_v3v3(r_axis_y, v2, v1);
+ sub_v3_v3v3(r_axis_x, v4, v1);
+ sub_v3_v3v3(r_axis_y, v2, v1);
- normalize_v3(r_axis_x);
- normalize_v3(r_axis_y);
+ normalize_v3(r_axis_x);
+ normalize_v3(r_axis_y);
}
/* tl is loop to project onto, l is loop whose internal displacement, co, is being
* projected. x and y are location in loop's mdisps grid of point co. */
-static bool mdisp_in_mdispquad(
- BMLoop *l_src, BMLoop *l_dst, const float l_dst_f_center[3],
- const float p[3], int res,
- float r_axis_x[3], float r_axis_y[3], float r_uv[2])
+static bool mdisp_in_mdispquad(BMLoop *l_src,
+ BMLoop *l_dst,
+ const float l_dst_f_center[3],
+ const float p[3],
+ int res,
+ float r_axis_x[3],
+ float r_axis_y[3],
+ float r_uv[2])
{
- float v1[3], v2[3], c[3], v3[3], v4[3], e1[3], e2[3];
- float eps = FLT_EPSILON * 4000;
-
- if (is_zero_v3(l_src->v->no)) {
- BM_vert_normal_update_all(l_src->v);
- }
- if (is_zero_v3(l_dst->v->no)) {
- BM_vert_normal_update_all(l_dst->v);
- }
-
- compute_mdisp_quad(l_dst, l_dst_f_center, v1, v2, v3, v4, e1, e2);
-
- /* expand quad a bit */
- mid_v3_v3v3v3v3(c, v1, v2, v3, v4);
-
- sub_v3_v3(v1, c); sub_v3_v3(v2, c);
- sub_v3_v3(v3, c); sub_v3_v3(v4, c);
- mul_v3_fl(v1, 1.0f + eps); mul_v3_fl(v2, 1.0f + eps);
- mul_v3_fl(v3, 1.0f + eps); mul_v3_fl(v4, 1.0f + eps);
- add_v3_v3(v1, c); add_v3_v3(v2, c);
- add_v3_v3(v3, c); add_v3_v3(v4, c);
-
- if (!quad_co(v1, v2, v3, v4, p, l_src->v->no, r_uv)) {
- return 0;
- }
-
- mul_v2_fl(r_uv, (float)(res - 1));
-
- mdisp_axis_from_quad(v1, v2, v3, v4, r_axis_x, r_axis_y);
-
- return 1;
+ float v1[3], v2[3], c[3], v3[3], v4[3], e1[3], e2[3];
+ float eps = FLT_EPSILON * 4000;
+
+ if (is_zero_v3(l_src->v->no)) {
+ BM_vert_normal_update_all(l_src->v);
+ }
+ if (is_zero_v3(l_dst->v->no)) {
+ BM_vert_normal_update_all(l_dst->v);
+ }
+
+ compute_mdisp_quad(l_dst, l_dst_f_center, v1, v2, v3, v4, e1, e2);
+
+ /* expand quad a bit */
+ mid_v3_v3v3v3v3(c, v1, v2, v3, v4);
+
+ sub_v3_v3(v1, c);
+ sub_v3_v3(v2, c);
+ sub_v3_v3(v3, c);
+ sub_v3_v3(v4, c);
+ mul_v3_fl(v1, 1.0f + eps);
+ mul_v3_fl(v2, 1.0f + eps);
+ mul_v3_fl(v3, 1.0f + eps);
+ mul_v3_fl(v4, 1.0f + eps);
+ add_v3_v3(v1, c);
+ add_v3_v3(v2, c);
+ add_v3_v3(v3, c);
+ add_v3_v3(v4, c);
+
+ if (!quad_co(v1, v2, v3, v4, p, l_src->v->no, r_uv)) {
+ return 0;
+ }
+
+ mul_v2_fl(r_uv, (float)(res - 1));
+
+ mdisp_axis_from_quad(v1, v2, v3, v4, r_axis_x, r_axis_y);
+
+ return 1;
}
-static float bm_loop_flip_equotion(
- float mat[2][2], float b[2], const float target_axis_x[3], const float target_axis_y[3],
- const float coord[3], int i, int j)
+static float bm_loop_flip_equotion(float mat[2][2],
+ float b[2],
+ const float target_axis_x[3],
+ const float target_axis_y[3],
+ const float coord[3],
+ int i,
+ int j)
{
- mat[0][0] = target_axis_x[i];
- mat[0][1] = target_axis_y[i];
- mat[1][0] = target_axis_x[j];
- mat[1][1] = target_axis_y[j];
- b[0] = coord[i];
- b[1] = coord[j];
-
- return cross_v2v2(mat[0], mat[1]);
+ mat[0][0] = target_axis_x[i];
+ mat[0][1] = target_axis_y[i];
+ mat[1][0] = target_axis_x[j];
+ mat[1][1] = target_axis_y[j];
+ b[0] = coord[i];
+ b[1] = coord[j];
+
+ return cross_v2v2(mat[0], mat[1]);
}
-static void bm_loop_flip_disp(
- const float source_axis_x[3], const float source_axis_y[3],
- const float target_axis_x[3], const float target_axis_y[3], float disp[3])
+static void bm_loop_flip_disp(const float source_axis_x[3],
+ const float source_axis_y[3],
+ const float target_axis_x[3],
+ const float target_axis_y[3],
+ float disp[3])
{
- float vx[3], vy[3], coord[3];
- float n[3], vec[3];
- float b[2], mat[2][2], d;
-
- mul_v3_v3fl(vx, source_axis_x, disp[0]);
- mul_v3_v3fl(vy, source_axis_y, disp[1]);
- add_v3_v3v3(coord, vx, vy);
-
- /* project displacement from source grid plane onto target grid plane */
- cross_v3_v3v3(n, target_axis_x, target_axis_y);
- project_v3_v3v3(vec, coord, n);
- sub_v3_v3v3(coord, coord, vec);
-
- d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 0, 1);
-
- if (fabsf(d) < 1e-4f) {
- d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 0, 2);
- if (fabsf(d) < 1e-4f) {
- d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 1, 2);
- }
- }
-
- disp[0] = (b[0] * mat[1][1] - mat[0][1] * b[1]) / d;
- disp[1] = (mat[0][0] * b[1] - b[0] * mat[1][0]) / d;
+ float vx[3], vy[3], coord[3];
+ float n[3], vec[3];
+ float b[2], mat[2][2], d;
+
+ mul_v3_v3fl(vx, source_axis_x, disp[0]);
+ mul_v3_v3fl(vy, source_axis_y, disp[1]);
+ add_v3_v3v3(coord, vx, vy);
+
+ /* project displacement from source grid plane onto target grid plane */
+ cross_v3_v3v3(n, target_axis_x, target_axis_y);
+ project_v3_v3v3(vec, coord, n);
+ sub_v3_v3v3(coord, coord, vec);
+
+ d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 0, 1);
+
+ if (fabsf(d) < 1e-4f) {
+ d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 0, 2);
+ if (fabsf(d) < 1e-4f) {
+ d = bm_loop_flip_equotion(mat, b, target_axis_x, target_axis_y, coord, 1, 2);
+ }
+ }
+
+ disp[0] = (b[0] * mat[1][1] - mat[0][1] * b[1]) / d;
+ disp[1] = (mat[0][0] * b[1] - b[0] * mat[1][0]) / d;
}
-
typedef struct BMLoopInterpMultiresData {
- BMLoop *l_dst;
- BMLoop *l_src_first;
- int cd_loop_mdisp_offset;
+ BMLoop *l_dst;
+ BMLoop *l_src_first;
+ int cd_loop_mdisp_offset;
- MDisps *md_dst;
- const float *f_src_center;
+ MDisps *md_dst;
+ const float *f_src_center;
- float *axis_x, *axis_y;
- float *v1, *v4;
- float *e1, *e2;
+ float *axis_x, *axis_y;
+ float *v1, *v4;
+ float *e1, *e2;
- int res;
- float d;
+ int res;
+ float d;
} BMLoopInterpMultiresData;
-static void loop_interp_multires_cb(
- void *__restrict userdata,
- const int ix,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void loop_interp_multires_cb(void *__restrict userdata,
+ const int ix,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- BMLoopInterpMultiresData *data = userdata;
+ BMLoopInterpMultiresData *data = userdata;
- BMLoop *l_first = data->l_src_first;
- BMLoop *l_dst = data->l_dst;
- const int cd_loop_mdisp_offset = data->cd_loop_mdisp_offset;
+ BMLoop *l_first = data->l_src_first;
+ BMLoop *l_dst = data->l_dst;
+ const int cd_loop_mdisp_offset = data->cd_loop_mdisp_offset;
- MDisps *md_dst = data->md_dst;
- const float *f_src_center = data->f_src_center;
+ MDisps *md_dst = data->md_dst;
+ const float *f_src_center = data->f_src_center;
- float *axis_x = data->axis_x;
- float *axis_y = data->axis_y;
+ float *axis_x = data->axis_x;
+ float *axis_y = data->axis_y;
- float *v1 = data->v1;
- float *v4 = data->v4;
- float *e1 = data->e1;
- float *e2 = data->e2;
+ float *v1 = data->v1;
+ float *v4 = data->v4;
+ float *e1 = data->e1;
+ float *e2 = data->e2;
- const int res = data->res;
- const float d = data->d;
+ const int res = data->res;
+ const float d = data->d;
- float x = d * ix, y;
- int iy;
- for (y = 0.0f, iy = 0; iy < res; y += d, iy++) {
- BMLoop *l_iter = l_first;
- float co1[3], co2[3], co[3];
+ float x = d * ix, y;
+ int iy;
+ for (y = 0.0f, iy = 0; iy < res; y += d, iy++) {
+ BMLoop *l_iter = l_first;
+ float co1[3], co2[3], co[3];
- madd_v3_v3v3fl(co1, v1, e1, y);
- madd_v3_v3v3fl(co2, v4, e2, y);
- interp_v3_v3v3(co, co1, co2, x);
+ madd_v3_v3v3fl(co1, v1, e1, y);
+ madd_v3_v3v3fl(co2, v4, e2, y);
+ interp_v3_v3v3(co, co1, co2, x);
- do {
- MDisps *md_src;
- float src_axis_x[3], src_axis_y[3];
- float uv[2];
+ do {
+ MDisps *md_src;
+ float src_axis_x[3], src_axis_y[3];
+ float uv[2];
- md_src = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset);
+ md_src = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_mdisp_offset);
- if (mdisp_in_mdispquad(l_dst, l_iter, f_src_center, co, res, src_axis_x, src_axis_y, uv)) {
- old_mdisps_bilinear(md_dst->disps[iy * res + ix], md_src->disps, res, uv[0], uv[1]);
- bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md_dst->disps[iy * res + ix]);
+ if (mdisp_in_mdispquad(l_dst, l_iter, f_src_center, co, res, src_axis_x, src_axis_y, uv)) {
+ old_mdisps_bilinear(md_dst->disps[iy * res + ix], md_src->disps, res, uv[0], uv[1]);
+ bm_loop_flip_disp(src_axis_x, src_axis_y, axis_x, axis_y, md_dst->disps[iy * res + ix]);
- break;
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
}
-void BM_loop_interp_multires_ex(
- BMesh *UNUSED(bm), BMLoop *l_dst, const BMFace *f_src,
- const float f_dst_center[3], const float f_src_center[3], const int cd_loop_mdisp_offset)
+void BM_loop_interp_multires_ex(BMesh *UNUSED(bm),
+ BMLoop *l_dst,
+ const BMFace *f_src,
+ const float f_dst_center[3],
+ const float f_src_center[3],
+ const int cd_loop_mdisp_offset)
{
- MDisps *md_dst;
- float v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3];
- float axis_x[3], axis_y[3];
-
- /* ignore 2-edged faces */
- if (UNLIKELY(l_dst->f->len < 3)) {
- return;
- }
-
- md_dst = BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_mdisp_offset);
- compute_mdisp_quad(l_dst, f_dst_center, v1, v2, v3, v4, e1, e2);
-
- /* if no disps data allocate a new grid, the size of the first grid in f_src. */
- if (!md_dst->totdisp) {
- const MDisps *md_src = BM_ELEM_CD_GET_VOID_P(BM_FACE_FIRST_LOOP(f_src), cd_loop_mdisp_offset);
-
- md_dst->totdisp = md_src->totdisp;
- md_dst->level = md_src->level;
- if (md_dst->totdisp) {
- md_dst->disps = MEM_callocN(sizeof(float) * 3 * md_dst->totdisp, __func__);
- }
- else {
- return;
- }
- }
-
- mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y);
-
- const int res = (int)sqrt(md_dst->totdisp);
- BMLoopInterpMultiresData data = {
- .l_dst = l_dst, .l_src_first = BM_FACE_FIRST_LOOP(f_src),
- .cd_loop_mdisp_offset = cd_loop_mdisp_offset,
- .md_dst = md_dst, .f_src_center = f_src_center,
- .axis_x = axis_x, .axis_y = axis_y, .v1 = v1, .v4 = v4, .e1 = e1, .e2 = e2,
- .res = res, .d = 1.0f / (float)(res - 1),
- };
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (res > 5);
- BLI_task_parallel_range(0, res, &data, loop_interp_multires_cb, &settings);
+ MDisps *md_dst;
+ float v1[3], v2[3], v3[3], v4[3] = {0.0f, 0.0f, 0.0f}, e1[3], e2[3];
+ float axis_x[3], axis_y[3];
+
+ /* ignore 2-edged faces */
+ if (UNLIKELY(l_dst->f->len < 3)) {
+ return;
+ }
+
+ md_dst = BM_ELEM_CD_GET_VOID_P(l_dst, cd_loop_mdisp_offset);
+ compute_mdisp_quad(l_dst, f_dst_center, v1, v2, v3, v4, e1, e2);
+
+ /* if no disps data allocate a new grid, the size of the first grid in f_src. */
+ if (!md_dst->totdisp) {
+ const MDisps *md_src = BM_ELEM_CD_GET_VOID_P(BM_FACE_FIRST_LOOP(f_src), cd_loop_mdisp_offset);
+
+ md_dst->totdisp = md_src->totdisp;
+ md_dst->level = md_src->level;
+ if (md_dst->totdisp) {
+ md_dst->disps = MEM_callocN(sizeof(float) * 3 * md_dst->totdisp, __func__);
+ }
+ else {
+ return;
+ }
+ }
+
+ mdisp_axis_from_quad(v1, v2, v3, v4, axis_x, axis_y);
+
+ const int res = (int)sqrt(md_dst->totdisp);
+ BMLoopInterpMultiresData data = {
+ .l_dst = l_dst,
+ .l_src_first = BM_FACE_FIRST_LOOP(f_src),
+ .cd_loop_mdisp_offset = cd_loop_mdisp_offset,
+ .md_dst = md_dst,
+ .f_src_center = f_src_center,
+ .axis_x = axis_x,
+ .axis_y = axis_y,
+ .v1 = v1,
+ .v4 = v4,
+ .e1 = e1,
+ .e2 = e2,
+ .res = res,
+ .d = 1.0f / (float)(res - 1),
+ };
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = (res > 5);
+ BLI_task_parallel_range(0, res, &data, loop_interp_multires_cb, &settings);
}
/**
@@ -521,45 +572,47 @@ void BM_loop_interp_multires_ex(
*/
void BM_loop_interp_multires(BMesh *bm, BMLoop *l_dst, const BMFace *f_src)
{
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
- if (cd_loop_mdisp_offset != -1) {
- float f_dst_center[3];
- float f_src_center[3];
+ if (cd_loop_mdisp_offset != -1) {
+ float f_dst_center[3];
+ float f_src_center[3];
- BM_face_calc_center_median(l_dst->f, f_dst_center);
- BM_face_calc_center_median(f_src, f_src_center);
+ BM_face_calc_center_median(l_dst->f, f_dst_center);
+ BM_face_calc_center_median(f_src, f_src_center);
- BM_loop_interp_multires_ex(bm, l_dst, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset);
- }
+ BM_loop_interp_multires_ex(bm, l_dst, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset);
+ }
}
-void BM_face_interp_multires_ex(
- BMesh *bm, BMFace *f_dst, const BMFace *f_src,
- const float f_dst_center[3], const float f_src_center[3], const int cd_loop_mdisp_offset)
+void BM_face_interp_multires_ex(BMesh *bm,
+ BMFace *f_dst,
+ const BMFace *f_src,
+ const float f_dst_center[3],
+ const float f_src_center[3],
+ const int cd_loop_mdisp_offset)
{
- BMLoop *l_iter, *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst);
- do {
- BM_loop_interp_multires_ex(
- bm, l_iter, f_src,
- f_dst_center, f_src_center, cd_loop_mdisp_offset);
- } while ((l_iter = l_iter->next) != l_first);
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_dst);
+ do {
+ BM_loop_interp_multires_ex(
+ bm, l_iter, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset);
+ } while ((l_iter = l_iter->next) != l_first);
}
void BM_face_interp_multires(BMesh *bm, BMFace *f_dst, const BMFace *f_src)
{
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
- if (cd_loop_mdisp_offset != -1) {
- float f_dst_center[3];
- float f_src_center[3];
+ if (cd_loop_mdisp_offset != -1) {
+ float f_dst_center[3];
+ float f_src_center[3];
- BM_face_calc_center_median(f_dst, f_dst_center);
- BM_face_calc_center_median(f_src, f_src_center);
+ BM_face_calc_center_median(f_dst, f_dst_center);
+ BM_face_calc_center_median(f_src, f_src_center);
- BM_face_interp_multires_ex(bm, f_dst, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset);
- }
+ BM_face_interp_multires_ex(bm, f_dst, f_src, f_dst_center, f_src_center, cd_loop_mdisp_offset);
+ }
}
/**
@@ -568,110 +621,110 @@ void BM_face_interp_multires(BMesh *bm, BMFace *f_dst, const BMFace *f_src)
*/
void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
{
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
- BMLoop *l;
- BMIter liter;
-
- if (cd_loop_mdisp_offset == -1) {
- return;
- }
-
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- MDisps *mdp = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_mdisp_offset);
- MDisps *mdl = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
- MDisps *mdn = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_mdisp_offset);
- float co1[3];
- int sides;
- int y;
-
- /**
- * mdisps is a grid of displacements, ordered thus:
- * <pre>
- * v4/next
- * |
- * | v1/cent-----mid2 ---> x
- * | | |
- * | | |
- * v2/prev---mid1-----v3/cur
- * |
- * V
- * y
- * </pre>
- */
-
- sides = (int)sqrt(mdp->totdisp);
- for (y = 0; y < sides; y++) {
- mid_v3_v3v3(co1, mdn->disps[y * sides], mdl->disps[y]);
-
- copy_v3_v3(mdn->disps[y * sides], co1);
- copy_v3_v3(mdl->disps[y], co1);
- }
- }
-
- BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
- MDisps *mdl1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
- MDisps *mdl2;
- float co1[3], co2[3], co[3];
- int sides;
- int y;
-
- /**
- * mdisps is a grid of displacements, ordered thus:
- * <pre>
- * v4/next
- * |
- * | v1/cent-----mid2 ---> x
- * | | |
- * | | |
- * v2/prev---mid1-----v3/cur
- * |
- * V
- * y
- * </pre>
- */
-
- if (l->radial_next == l) {
- continue;
- }
-
- if (l->radial_next->v == l->v) {
- mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next, cd_loop_mdisp_offset);
- }
- else {
- mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next->next, cd_loop_mdisp_offset);
- }
-
- sides = (int)sqrt(mdl1->totdisp);
- for (y = 0; y < sides; y++) {
- int a1, a2, o1, o2;
-
- if (l->v != l->radial_next->v) {
- a1 = sides * y + sides - 2;
- a2 = (sides - 2) * sides + y;
-
- o1 = sides * y + sides - 1;
- o2 = (sides - 1) * sides + y;
- }
- else {
- a1 = sides * y + sides - 2;
- a2 = sides * y + sides - 2;
- o1 = sides * y + sides - 1;
- o2 = sides * y + sides - 1;
- }
-
- /* magic blending numbers, hardcoded! */
- add_v3_v3v3(co1, mdl1->disps[a1], mdl2->disps[a2]);
- mul_v3_fl(co1, 0.18);
-
- add_v3_v3v3(co2, mdl1->disps[o1], mdl2->disps[o2]);
- mul_v3_fl(co2, 0.32);
-
- add_v3_v3v3(co, co1, co2);
-
- copy_v3_v3(mdl1->disps[o1], co);
- copy_v3_v3(mdl2->disps[o2], co);
- }
- }
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+ BMLoop *l;
+ BMIter liter;
+
+ if (cd_loop_mdisp_offset == -1) {
+ return;
+ }
+
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ MDisps *mdp = BM_ELEM_CD_GET_VOID_P(l->prev, cd_loop_mdisp_offset);
+ MDisps *mdl = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
+ MDisps *mdn = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_mdisp_offset);
+ float co1[3];
+ int sides;
+ int y;
+
+ /**
+ * mdisps is a grid of displacements, ordered thus:
+ * <pre>
+ * v4/next
+ * |
+ * | v1/cent-----mid2 ---> x
+ * | | |
+ * | | |
+ * v2/prev---mid1-----v3/cur
+ * |
+ * V
+ * y
+ * </pre>
+ */
+
+ sides = (int)sqrt(mdp->totdisp);
+ for (y = 0; y < sides; y++) {
+ mid_v3_v3v3(co1, mdn->disps[y * sides], mdl->disps[y]);
+
+ copy_v3_v3(mdn->disps[y * sides], co1);
+ copy_v3_v3(mdl->disps[y], co1);
+ }
+ }
+
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ MDisps *mdl1 = BM_ELEM_CD_GET_VOID_P(l, cd_loop_mdisp_offset);
+ MDisps *mdl2;
+ float co1[3], co2[3], co[3];
+ int sides;
+ int y;
+
+ /**
+ * mdisps is a grid of displacements, ordered thus:
+ * <pre>
+ * v4/next
+ * |
+ * | v1/cent-----mid2 ---> x
+ * | | |
+ * | | |
+ * v2/prev---mid1-----v3/cur
+ * |
+ * V
+ * y
+ * </pre>
+ */
+
+ if (l->radial_next == l) {
+ continue;
+ }
+
+ if (l->radial_next->v == l->v) {
+ mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next, cd_loop_mdisp_offset);
+ }
+ else {
+ mdl2 = BM_ELEM_CD_GET_VOID_P(l->radial_next->next, cd_loop_mdisp_offset);
+ }
+
+ sides = (int)sqrt(mdl1->totdisp);
+ for (y = 0; y < sides; y++) {
+ int a1, a2, o1, o2;
+
+ if (l->v != l->radial_next->v) {
+ a1 = sides * y + sides - 2;
+ a2 = (sides - 2) * sides + y;
+
+ o1 = sides * y + sides - 1;
+ o2 = (sides - 1) * sides + y;
+ }
+ else {
+ a1 = sides * y + sides - 2;
+ a2 = sides * y + sides - 2;
+ o1 = sides * y + sides - 1;
+ o2 = sides * y + sides - 1;
+ }
+
+ /* magic blending numbers, hardcoded! */
+ add_v3_v3v3(co1, mdl1->disps[a1], mdl2->disps[a2]);
+ mul_v3_fl(co1, 0.18);
+
+ add_v3_v3v3(co2, mdl1->disps[o1], mdl2->disps[o2]);
+ mul_v3_fl(co2, 0.32);
+
+ add_v3_v3v3(co, co1, co2);
+
+ copy_v3_v3(mdl1->disps[o1], co);
+ copy_v3_v3(mdl2->disps[o2], co);
+ }
+ }
}
/**
@@ -679,290 +732,288 @@ void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f)
* if do_vertex is true, target's vert data will also get interpolated.
*/
void BM_loop_interp_from_face(
- BMesh *bm, BMLoop *l_dst, const BMFace *f_src,
- const bool do_vertex, const bool do_multires)
+ BMesh *bm, BMLoop *l_dst, const BMFace *f_src, const bool do_vertex, const bool do_multires)
{
- BMLoop *l_iter;
- BMLoop *l_first;
- const void **vblocks = do_vertex ? BLI_array_alloca(vblocks, f_src->len) : NULL;
- const void **blocks = BLI_array_alloca(blocks, f_src->len);
- float (*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
- float *w = BLI_array_alloca(w, f_src->len);
- float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
- float co[2];
- int i;
-
- /* convert the 3d coords into 2d for projection */
- BLI_assert(BM_face_is_normal_valid(f_src));
- axis_dominant_v3_to_m3(axis_mat, f_src->no);
-
- i = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
- do {
- mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
- blocks[i] = l_iter->head.data;
-
- if (do_vertex) {
- vblocks[i] = l_iter->v->head.data;
- }
- } while ((void)i++, (l_iter = l_iter->next) != l_first);
-
- mul_v2_m3v3(co, axis_mat, l_dst->v->co);
-
- /* interpolate */
- interp_weights_poly_v2(w, cos_2d, f_src->len, co);
- CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, f_src->len, l_dst->head.data);
- if (do_vertex) {
- CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, f_src->len, l_dst->v->head.data);
- }
-
- if (do_multires) {
- BM_loop_interp_multires(bm, l_dst, f_src);
- }
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ const void **vblocks = do_vertex ? BLI_array_alloca(vblocks, f_src->len) : NULL;
+ const void **blocks = BLI_array_alloca(blocks, f_src->len);
+ float(*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
+ float *w = BLI_array_alloca(w, f_src->len);
+ float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
+ float co[2];
+ int i;
+
+ /* convert the 3d coords into 2d for projection */
+ BLI_assert(BM_face_is_normal_valid(f_src));
+ axis_dominant_v3_to_m3(axis_mat, f_src->no);
+
+ i = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
+ do {
+ mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
+ blocks[i] = l_iter->head.data;
+
+ if (do_vertex) {
+ vblocks[i] = l_iter->v->head.data;
+ }
+ } while ((void)i++, (l_iter = l_iter->next) != l_first);
+
+ mul_v2_m3v3(co, axis_mat, l_dst->v->co);
+
+ /* interpolate */
+ interp_weights_poly_v2(w, cos_2d, f_src->len, co);
+ CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, f_src->len, l_dst->head.data);
+ if (do_vertex) {
+ CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, f_src->len, l_dst->v->head.data);
+ }
+
+ if (do_multires) {
+ BM_loop_interp_multires(bm, l_dst, f_src);
+ }
}
-
void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src)
{
- BMLoop *l_iter;
- BMLoop *l_first;
- const void **blocks = BLI_array_alloca(blocks, f_src->len);
- float (*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
- float *w = BLI_array_alloca(w, f_src->len);
- float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
- float co[2];
- int i;
-
- /* convert the 3d coords into 2d for projection */
- BLI_assert(BM_face_is_normal_valid(f_src));
- axis_dominant_v3_to_m3(axis_mat, f_src->no);
-
- i = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
- do {
- mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
- blocks[i] = l_iter->v->head.data;
- } while ((void)i++, (l_iter = l_iter->next) != l_first);
-
- mul_v2_m3v3(co, axis_mat, v_dst->co);
-
- /* interpolate */
- interp_weights_poly_v2(w, cos_2d, f_src->len, co);
- CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, f_src->len, v_dst->head.data);
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ const void **blocks = BLI_array_alloca(blocks, f_src->len);
+ float(*cos_2d)[2] = BLI_array_alloca(cos_2d, f_src->len);
+ float *w = BLI_array_alloca(w, f_src->len);
+ float axis_mat[3][3]; /* use normal to transform into 2d xy coords */
+ float co[2];
+ int i;
+
+ /* convert the 3d coords into 2d for projection */
+ BLI_assert(BM_face_is_normal_valid(f_src));
+ axis_dominant_v3_to_m3(axis_mat, f_src->no);
+
+ i = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_src);
+ do {
+ mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
+ blocks[i] = l_iter->v->head.data;
+ } while ((void)i++, (l_iter = l_iter->next) != l_first);
+
+ mul_v2_m3v3(co, axis_mat, v_dst->co);
+
+ /* interpolate */
+ interp_weights_poly_v2(w, cos_2d, f_src->len, co);
+ CustomData_bmesh_interp(&bm->vdata, blocks, w, NULL, f_src->len, v_dst->head.data);
}
static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
{
- BMIter iter;
- BLI_mempool *oldpool = olddata->pool;
- void *block;
-
- if (data == &bm->vdata) {
- BMVert *eve;
-
- CustomData_bmesh_init_pool(data, bm->totvert, BM_VERT);
-
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- block = NULL;
- CustomData_bmesh_set_default(data, &block);
- CustomData_bmesh_copy_data(olddata, data, eve->head.data, &block);
- CustomData_bmesh_free_block(olddata, &eve->head.data);
- eve->head.data = block;
- }
- }
- else if (data == &bm->edata) {
- BMEdge *eed;
-
- CustomData_bmesh_init_pool(data, bm->totedge, BM_EDGE);
-
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- block = NULL;
- CustomData_bmesh_set_default(data, &block);
- CustomData_bmesh_copy_data(olddata, data, eed->head.data, &block);
- CustomData_bmesh_free_block(olddata, &eed->head.data);
- eed->head.data = block;
- }
- }
- else if (data == &bm->ldata) {
- BMIter liter;
- BMFace *efa;
- BMLoop *l;
-
- CustomData_bmesh_init_pool(data, bm->totloop, BM_LOOP);
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- block = NULL;
- CustomData_bmesh_set_default(data, &block);
- CustomData_bmesh_copy_data(olddata, data, l->head.data, &block);
- CustomData_bmesh_free_block(olddata, &l->head.data);
- l->head.data = block;
- }
- }
- }
- else if (data == &bm->pdata) {
- BMFace *efa;
-
- CustomData_bmesh_init_pool(data, bm->totface, BM_FACE);
-
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- block = NULL;
- CustomData_bmesh_set_default(data, &block);
- CustomData_bmesh_copy_data(olddata, data, efa->head.data, &block);
- CustomData_bmesh_free_block(olddata, &efa->head.data);
- efa->head.data = block;
- }
- }
- else {
- /* should never reach this! */
- BLI_assert(0);
- }
-
- if (oldpool) {
- /* this should never happen but can when dissolve fails - [#28960] */
- BLI_assert(data->pool != oldpool);
-
- BLI_mempool_destroy(oldpool);
- }
+ BMIter iter;
+ BLI_mempool *oldpool = olddata->pool;
+ void *block;
+
+ if (data == &bm->vdata) {
+ BMVert *eve;
+
+ CustomData_bmesh_init_pool(data, bm->totvert, BM_VERT);
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ block = NULL;
+ CustomData_bmesh_set_default(data, &block);
+ CustomData_bmesh_copy_data(olddata, data, eve->head.data, &block);
+ CustomData_bmesh_free_block(olddata, &eve->head.data);
+ eve->head.data = block;
+ }
+ }
+ else if (data == &bm->edata) {
+ BMEdge *eed;
+
+ CustomData_bmesh_init_pool(data, bm->totedge, BM_EDGE);
+
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ block = NULL;
+ CustomData_bmesh_set_default(data, &block);
+ CustomData_bmesh_copy_data(olddata, data, eed->head.data, &block);
+ CustomData_bmesh_free_block(olddata, &eed->head.data);
+ eed->head.data = block;
+ }
+ }
+ else if (data == &bm->ldata) {
+ BMIter liter;
+ BMFace *efa;
+ BMLoop *l;
+
+ CustomData_bmesh_init_pool(data, bm->totloop, BM_LOOP);
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ block = NULL;
+ CustomData_bmesh_set_default(data, &block);
+ CustomData_bmesh_copy_data(olddata, data, l->head.data, &block);
+ CustomData_bmesh_free_block(olddata, &l->head.data);
+ l->head.data = block;
+ }
+ }
+ }
+ else if (data == &bm->pdata) {
+ BMFace *efa;
+
+ CustomData_bmesh_init_pool(data, bm->totface, BM_FACE);
+
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ block = NULL;
+ CustomData_bmesh_set_default(data, &block);
+ CustomData_bmesh_copy_data(olddata, data, efa->head.data, &block);
+ CustomData_bmesh_free_block(olddata, &efa->head.data);
+ efa->head.data = block;
+ }
+ }
+ else {
+ /* should never reach this! */
+ BLI_assert(0);
+ }
+
+ if (oldpool) {
+ /* this should never happen but can when dissolve fails - [#28960] */
+ BLI_assert(data->pool != oldpool);
+
+ BLI_mempool_destroy(oldpool);
+ }
}
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
{
- CustomData olddata;
+ CustomData olddata;
- olddata = *data;
- olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
+ olddata = *data;
+ olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
- /* the pool is now owned by olddata and must not be shared */
- data->pool = NULL;
+ /* the pool is now owned by olddata and must not be shared */
+ data->pool = NULL;
- CustomData_add_layer(data, type, CD_DEFAULT, NULL, 0);
+ CustomData_add_layer(data, type, CD_DEFAULT, NULL, 0);
- update_data_blocks(bm, &olddata, data);
- if (olddata.layers) {
- MEM_freeN(olddata.layers);
- }
+ update_data_blocks(bm, &olddata, data);
+ if (olddata.layers) {
+ MEM_freeN(olddata.layers);
+ }
}
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name)
{
- CustomData olddata;
+ CustomData olddata;
- olddata = *data;
- olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
+ olddata = *data;
+ olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
- /* the pool is now owned by olddata and must not be shared */
- data->pool = NULL;
+ /* the pool is now owned by olddata and must not be shared */
+ data->pool = NULL;
- CustomData_add_layer_named(data, type, CD_DEFAULT, NULL, 0, name);
+ CustomData_add_layer_named(data, type, CD_DEFAULT, NULL, 0, name);
- update_data_blocks(bm, &olddata, data);
- if (olddata.layers) {
- MEM_freeN(olddata.layers);
- }
+ update_data_blocks(bm, &olddata, data);
+ if (olddata.layers) {
+ MEM_freeN(olddata.layers);
+ }
}
void BM_data_layer_free(BMesh *bm, CustomData *data, int type)
{
- CustomData olddata;
- bool has_layer;
+ CustomData olddata;
+ bool has_layer;
- olddata = *data;
- olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
+ olddata = *data;
+ olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
- /* the pool is now owned by olddata and must not be shared */
- data->pool = NULL;
+ /* the pool is now owned by olddata and must not be shared */
+ data->pool = NULL;
- has_layer = CustomData_free_layer_active(data, type, 0);
- /* assert because its expensive to realloc - better not do if layer isnt present */
- BLI_assert(has_layer != false);
- UNUSED_VARS_NDEBUG(has_layer);
+ has_layer = CustomData_free_layer_active(data, type, 0);
+ /* assert because its expensive to realloc - better not do if layer isnt present */
+ BLI_assert(has_layer != false);
+ UNUSED_VARS_NDEBUG(has_layer);
- update_data_blocks(bm, &olddata, data);
- if (olddata.layers) {
- MEM_freeN(olddata.layers);
- }
+ update_data_blocks(bm, &olddata, data);
+ if (olddata.layers) {
+ MEM_freeN(olddata.layers);
+ }
}
void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n)
{
- CustomData olddata;
- bool has_layer;
+ CustomData olddata;
+ bool has_layer;
- olddata = *data;
- olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
+ olddata = *data;
+ olddata.layers = (olddata.layers) ? MEM_dupallocN(olddata.layers) : NULL;
- /* the pool is now owned by olddata and must not be shared */
- data->pool = NULL;
+ /* the pool is now owned by olddata and must not be shared */
+ data->pool = NULL;
- has_layer = CustomData_free_layer(data, type, 0, CustomData_get_layer_index_n(data, type, n));
- /* assert because its expensive to realloc - better not do if layer isnt present */
- BLI_assert(has_layer != false);
- UNUSED_VARS_NDEBUG(has_layer);
+ has_layer = CustomData_free_layer(data, type, 0, CustomData_get_layer_index_n(data, type, n));
+ /* assert because its expensive to realloc - better not do if layer isnt present */
+ BLI_assert(has_layer != false);
+ UNUSED_VARS_NDEBUG(has_layer);
- update_data_blocks(bm, &olddata, data);
- if (olddata.layers) {
- MEM_freeN(olddata.layers);
- }
+ update_data_blocks(bm, &olddata, data);
+ if (olddata.layers) {
+ MEM_freeN(olddata.layers);
+ }
}
void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int dst_n)
{
- BMIter iter;
-
- if (&bm->vdata == data) {
- BMVert *eve;
-
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- void *ptr = CustomData_bmesh_get_n(data, eve->head.data, type, src_n);
- CustomData_bmesh_set_n(data, eve->head.data, type, dst_n, ptr);
- }
- }
- else if (&bm->edata == data) {
- BMEdge *eed;
-
- BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
- void *ptr = CustomData_bmesh_get_n(data, eed->head.data, type, src_n);
- CustomData_bmesh_set_n(data, eed->head.data, type, dst_n, ptr);
- }
- }
- else if (&bm->pdata == data) {
- BMFace *efa;
-
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- void *ptr = CustomData_bmesh_get_n(data, efa->head.data, type, src_n);
- CustomData_bmesh_set_n(data, efa->head.data, type, dst_n, ptr);
- }
- }
- else if (&bm->ldata == data) {
- BMIter liter;
- BMFace *efa;
- BMLoop *l;
-
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- void *ptr = CustomData_bmesh_get_n(data, l->head.data, type, src_n);
- CustomData_bmesh_set_n(data, l->head.data, type, dst_n, ptr);
- }
- }
- }
- else {
- /* should never reach this! */
- BLI_assert(0);
- }
+ BMIter iter;
+
+ if (&bm->vdata == data) {
+ BMVert *eve;
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ void *ptr = CustomData_bmesh_get_n(data, eve->head.data, type, src_n);
+ CustomData_bmesh_set_n(data, eve->head.data, type, dst_n, ptr);
+ }
+ }
+ else if (&bm->edata == data) {
+ BMEdge *eed;
+
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ void *ptr = CustomData_bmesh_get_n(data, eed->head.data, type, src_n);
+ CustomData_bmesh_set_n(data, eed->head.data, type, dst_n, ptr);
+ }
+ }
+ else if (&bm->pdata == data) {
+ BMFace *efa;
+
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ void *ptr = CustomData_bmesh_get_n(data, efa->head.data, type, src_n);
+ CustomData_bmesh_set_n(data, efa->head.data, type, dst_n, ptr);
+ }
+ }
+ else if (&bm->ldata == data) {
+ BMIter liter;
+ BMFace *efa;
+ BMLoop *l;
+
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
+ void *ptr = CustomData_bmesh_get_n(data, l->head.data, type, src_n);
+ CustomData_bmesh_set_n(data, l->head.data, type, dst_n, ptr);
+ }
+ }
+ }
+ else {
+ /* should never reach this! */
+ BLI_assert(0);
+ }
}
float BM_elem_float_data_get(CustomData *cd, void *element, int type)
{
- const float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
- return f ? *f : 0.0f;
+ const float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
+ return f ? *f : 0.0f;
}
void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val)
{
- float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
- if (f) {
- *f = val;
- }
+ float *f = CustomData_bmesh_get(cd, ((BMHeader *)element)->data, type);
+ if (f) {
+ *f = val;
+ }
}
/** \name Loop interpolation functions: BM_vert_loop_groups_data_layer_***
@@ -984,51 +1035,51 @@ void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float
* \{ */
struct LoopWalkCtx {
- /* same for all groups */
- int type;
- int cd_layer_offset;
- const float *loop_weights;
- MemArena *arena;
-
- /* --- Per loop fan vars --- */
-
- /* reference for this contiguous fan */
- const void *data_ref;
- int data_len;
-
- /* accumulate 'LoopGroupCD.weight' to make unit length */
- float weight_accum;
-
- /* both arrays the size of the 'BM_vert_face_count(v)'
- * each contiguous fan gets a slide of these arrays */
- void **data_array;
- int *data_index_array;
- float *weight_array;
+ /* same for all groups */
+ int type;
+ int cd_layer_offset;
+ const float *loop_weights;
+ MemArena *arena;
+
+ /* --- Per loop fan vars --- */
+
+ /* reference for this contiguous fan */
+ const void *data_ref;
+ int data_len;
+
+ /* accumulate 'LoopGroupCD.weight' to make unit length */
+ float weight_accum;
+
+ /* both arrays the size of the 'BM_vert_face_count(v)'
+ * each contiguous fan gets a slide of these arrays */
+ void **data_array;
+ int *data_index_array;
+ float *weight_array;
};
/* Store vars to pass into 'CustomData_bmesh_interp' */
struct LoopGroupCD {
- /* direct customdata pointer array */
- void **data;
- /* weights (aligned with 'data') */
- float *data_weights;
- /* index-in-face */
- int *data_index;
- /* number of loops in the fan */
- int data_len;
+ /* direct customdata pointer array */
+ void **data;
+ /* weights (aligned with 'data') */
+ float *data_weights;
+ /* index-in-face */
+ int *data_index;
+ /* number of loops in the fan */
+ int data_len;
};
static void bm_loop_walk_add(struct LoopWalkCtx *lwc, BMLoop *l)
{
- const int i = BM_elem_index_get(l);
- const float w = lwc->loop_weights[i];
- BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG);
- lwc->data_array[lwc->data_len] = BM_ELEM_CD_GET_VOID_P(l, lwc->cd_layer_offset);
- lwc->data_index_array[lwc->data_len] = i;
- lwc->weight_array[lwc->data_len] = w;
- lwc->weight_accum += w;
-
- lwc->data_len += 1;
+ const int i = BM_elem_index_get(l);
+ const float w = lwc->loop_weights[i];
+ BM_elem_flag_disable(l, BM_ELEM_INTERNAL_TAG);
+ lwc->data_array[lwc->data_len] = BM_ELEM_CD_GET_VOID_P(l, lwc->cd_layer_offset);
+ lwc->data_index_array[lwc->data_len] = i;
+ lwc->weight_array[lwc->data_len] = w;
+ lwc->weight_accum += w;
+
+ lwc->data_len += 1;
}
/**
@@ -1038,146 +1089,145 @@ static void bm_loop_walk_add(struct LoopWalkCtx *lwc, BMLoop *l)
*/
static void bm_loop_walk_data(struct LoopWalkCtx *lwc, BMLoop *l_walk)
{
- int i;
-
- BLI_assert(CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_walk, lwc->cd_layer_offset)));
- BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG));
-
- bm_loop_walk_add(lwc, l_walk);
-
- /* recurse around this loop-fan (in both directions) */
- for (i = 0; i < 2; i++) {
- BMLoop *l_other = ((i == 0) ? l_walk : l_walk->prev)->radial_next;
- if (l_other->radial_next != l_other) {
- if (l_other->v != l_walk->v) {
- l_other = l_other->next;
- }
- BLI_assert(l_other->v == l_walk->v);
- if (BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) {
- if (CustomData_data_equals(lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_other, lwc->cd_layer_offset))) {
- bm_loop_walk_data(lwc, l_other);
- }
- }
- }
- }
+ int i;
+
+ BLI_assert(CustomData_data_equals(
+ lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_walk, lwc->cd_layer_offset)));
+ BLI_assert(BM_elem_flag_test(l_walk, BM_ELEM_INTERNAL_TAG));
+
+ bm_loop_walk_add(lwc, l_walk);
+
+ /* recurse around this loop-fan (in both directions) */
+ for (i = 0; i < 2; i++) {
+ BMLoop *l_other = ((i == 0) ? l_walk : l_walk->prev)->radial_next;
+ if (l_other->radial_next != l_other) {
+ if (l_other->v != l_walk->v) {
+ l_other = l_other->next;
+ }
+ BLI_assert(l_other->v == l_walk->v);
+ if (BM_elem_flag_test(l_other, BM_ELEM_INTERNAL_TAG)) {
+ if (CustomData_data_equals(
+ lwc->type, lwc->data_ref, BM_ELEM_CD_GET_VOID_P(l_other, lwc->cd_layer_offset))) {
+ bm_loop_walk_data(lwc, l_other);
+ }
+ }
+ }
+ }
}
LinkNode *BM_vert_loop_groups_data_layer_create(
- BMesh *bm, BMVert *v, const int layer_n, const float *loop_weights, MemArena *arena)
+ BMesh *bm, BMVert *v, const int layer_n, const float *loop_weights, MemArena *arena)
{
- struct LoopWalkCtx lwc;
- LinkNode *groups = NULL;
- BMLoop *l;
- BMIter liter;
- int loop_num;
-
-
- lwc.type = bm->ldata.layers[layer_n].type;
- lwc.cd_layer_offset = bm->ldata.layers[layer_n].offset;
- lwc.loop_weights = loop_weights;
- lwc.arena = arena;
-
- /* Enable 'BM_ELEM_INTERNAL_TAG', leaving the flag clean on completion. */
- loop_num = 0;
- BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
- BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG);
- BM_elem_index_set(l, loop_num); /* set_dirty! */
- loop_num++;
- }
- bm->elem_index_dirty |= BM_LOOP;
-
- lwc.data_len = 0;
- lwc.data_array = BLI_memarena_alloc(lwc.arena, sizeof(void *) * loop_num);
- lwc.data_index_array = BLI_memarena_alloc(lwc.arena, sizeof(int) * loop_num);
- lwc.weight_array = BLI_memarena_alloc(lwc.arena, sizeof(float) * loop_num);
-
- BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
- if (BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) {
- struct LoopGroupCD *lf = BLI_memarena_alloc(lwc.arena, sizeof(*lf));
- int len_prev = lwc.data_len;
-
- lwc.data_ref = BM_ELEM_CD_GET_VOID_P(l, lwc.cd_layer_offset);
-
- /* assign len-last */
- lf->data = &lwc.data_array[lwc.data_len];
- lf->data_index = &lwc.data_index_array[lwc.data_len];
- lf->data_weights = &lwc.weight_array[lwc.data_len];
- lwc.weight_accum = 0.0f;
-
- /* new group */
- bm_loop_walk_data(&lwc, l);
- lf->data_len = lwc.data_len - len_prev;
-
- if (LIKELY(lwc.weight_accum != 0.0f)) {
- mul_vn_fl(lf->data_weights, lf->data_len, 1.0f / lwc.weight_accum);
- }
- else {
- copy_vn_fl(lf->data_weights, lf->data_len, 1.0f / (float)lf->data_len);
- }
-
- BLI_linklist_prepend_arena(&groups, lf, lwc.arena);
- }
- }
-
- BLI_assert(lwc.data_len == loop_num);
-
- return groups;
+ struct LoopWalkCtx lwc;
+ LinkNode *groups = NULL;
+ BMLoop *l;
+ BMIter liter;
+ int loop_num;
+
+ lwc.type = bm->ldata.layers[layer_n].type;
+ lwc.cd_layer_offset = bm->ldata.layers[layer_n].offset;
+ lwc.loop_weights = loop_weights;
+ lwc.arena = arena;
+
+ /* Enable 'BM_ELEM_INTERNAL_TAG', leaving the flag clean on completion. */
+ loop_num = 0;
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ BM_elem_flag_enable(l, BM_ELEM_INTERNAL_TAG);
+ BM_elem_index_set(l, loop_num); /* set_dirty! */
+ loop_num++;
+ }
+ bm->elem_index_dirty |= BM_LOOP;
+
+ lwc.data_len = 0;
+ lwc.data_array = BLI_memarena_alloc(lwc.arena, sizeof(void *) * loop_num);
+ lwc.data_index_array = BLI_memarena_alloc(lwc.arena, sizeof(int) * loop_num);
+ lwc.weight_array = BLI_memarena_alloc(lwc.arena, sizeof(float) * loop_num);
+
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ if (BM_elem_flag_test(l, BM_ELEM_INTERNAL_TAG)) {
+ struct LoopGroupCD *lf = BLI_memarena_alloc(lwc.arena, sizeof(*lf));
+ int len_prev = lwc.data_len;
+
+ lwc.data_ref = BM_ELEM_CD_GET_VOID_P(l, lwc.cd_layer_offset);
+
+ /* assign len-last */
+ lf->data = &lwc.data_array[lwc.data_len];
+ lf->data_index = &lwc.data_index_array[lwc.data_len];
+ lf->data_weights = &lwc.weight_array[lwc.data_len];
+ lwc.weight_accum = 0.0f;
+
+ /* new group */
+ bm_loop_walk_data(&lwc, l);
+ lf->data_len = lwc.data_len - len_prev;
+
+ if (LIKELY(lwc.weight_accum != 0.0f)) {
+ mul_vn_fl(lf->data_weights, lf->data_len, 1.0f / lwc.weight_accum);
+ }
+ else {
+ copy_vn_fl(lf->data_weights, lf->data_len, 1.0f / (float)lf->data_len);
+ }
+
+ BLI_linklist_prepend_arena(&groups, lf, lwc.arena);
+ }
+ }
+
+ BLI_assert(lwc.data_len == loop_num);
+
+ return groups;
}
-static void bm_vert_loop_groups_data_layer_merge__single(
- BMesh *bm, void *lf_p, int layer_n,
- void *data_tmp)
+static void bm_vert_loop_groups_data_layer_merge__single(BMesh *bm,
+ void *lf_p,
+ int layer_n,
+ void *data_tmp)
{
- struct LoopGroupCD *lf = lf_p;
- const int type = bm->ldata.layers[layer_n].type;
- int i;
- const float *data_weights;
+ struct LoopGroupCD *lf = lf_p;
+ const int type = bm->ldata.layers[layer_n].type;
+ int i;
+ const float *data_weights;
- data_weights = lf->data_weights;
+ data_weights = lf->data_weights;
- CustomData_bmesh_interp_n(
- &bm->ldata, (const void **)lf->data,
- data_weights, NULL, lf->data_len, data_tmp, layer_n);
+ CustomData_bmesh_interp_n(
+ &bm->ldata, (const void **)lf->data, data_weights, NULL, lf->data_len, data_tmp, layer_n);
- for (i = 0; i < lf->data_len; i++) {
- CustomData_copy_elements(type, data_tmp, lf->data[i], 1);
- }
+ for (i = 0; i < lf->data_len; i++) {
+ CustomData_copy_elements(type, data_tmp, lf->data[i], 1);
+ }
}
static void bm_vert_loop_groups_data_layer_merge_weights__single(
- BMesh *bm, void *lf_p, const int layer_n, void *data_tmp,
- const float *loop_weights)
+ BMesh *bm, void *lf_p, const int layer_n, void *data_tmp, const float *loop_weights)
{
- struct LoopGroupCD *lf = lf_p;
- const int type = bm->ldata.layers[layer_n].type;
- int i;
- const float *data_weights;
-
- /* re-weight */
- float *temp_weights = BLI_array_alloca(temp_weights, lf->data_len);
- float weight_accum = 0.0f;
-
- for (i = 0; i < lf->data_len; i++) {
- float w = loop_weights[lf->data_index[i]] * lf->data_weights[i];
- temp_weights[i] = w;
- weight_accum += w;
- }
-
- if (LIKELY(weight_accum != 0.0f)) {
- mul_vn_fl(temp_weights, lf->data_len, 1.0f / weight_accum);
- data_weights = temp_weights;
- }
- else {
- data_weights = lf->data_weights;
- }
-
- CustomData_bmesh_interp_n(
- &bm->ldata, (const void **)lf->data,
- data_weights, NULL, lf->data_len, data_tmp, layer_n);
-
- for (i = 0; i < lf->data_len; i++) {
- CustomData_copy_elements(type, data_tmp, lf->data[i], 1);
- }
+ struct LoopGroupCD *lf = lf_p;
+ const int type = bm->ldata.layers[layer_n].type;
+ int i;
+ const float *data_weights;
+
+ /* re-weight */
+ float *temp_weights = BLI_array_alloca(temp_weights, lf->data_len);
+ float weight_accum = 0.0f;
+
+ for (i = 0; i < lf->data_len; i++) {
+ float w = loop_weights[lf->data_index[i]] * lf->data_weights[i];
+ temp_weights[i] = w;
+ weight_accum += w;
+ }
+
+ if (LIKELY(weight_accum != 0.0f)) {
+ mul_vn_fl(temp_weights, lf->data_len, 1.0f / weight_accum);
+ data_weights = temp_weights;
+ }
+ else {
+ data_weights = lf->data_weights;
+ }
+
+ CustomData_bmesh_interp_n(
+ &bm->ldata, (const void **)lf->data, data_weights, NULL, lf->data_len, data_tmp, layer_n);
+
+ for (i = 0; i < lf->data_len; i++) {
+ CustomData_copy_elements(type, data_tmp, lf->data[i], 1);
+ }
}
/**
@@ -1185,29 +1235,32 @@ static void bm_vert_loop_groups_data_layer_merge_weights__single(
*/
void BM_vert_loop_groups_data_layer_merge(BMesh *bm, LinkNode *groups, const int layer_n)
{
- const int type = bm->ldata.layers[layer_n].type;
- const int size = CustomData_sizeof(type);
- void *data_tmp = alloca(size);
+ const int type = bm->ldata.layers[layer_n].type;
+ const int size = CustomData_sizeof(type);
+ void *data_tmp = alloca(size);
- do {
- bm_vert_loop_groups_data_layer_merge__single(bm, groups->link, layer_n, data_tmp);
- } while ((groups = groups->next));
+ do {
+ bm_vert_loop_groups_data_layer_merge__single(bm, groups->link, layer_n, data_tmp);
+ } while ((groups = groups->next));
}
/**
* A version of #BM_vert_loop_groups_data_layer_merge
* that takes an array of loop-weights (aligned with #BM_LOOPS_OF_VERT iterator)
*/
-void BM_vert_loop_groups_data_layer_merge_weights(
- BMesh *bm, LinkNode *groups, const int layer_n, const float *loop_weights)
+void BM_vert_loop_groups_data_layer_merge_weights(BMesh *bm,
+ LinkNode *groups,
+ const int layer_n,
+ const float *loop_weights)
{
- const int type = bm->ldata.layers[layer_n].type;
- const int size = CustomData_sizeof(type);
- void *data_tmp = alloca(size);
-
- do {
- bm_vert_loop_groups_data_layer_merge_weights__single(bm, groups->link, layer_n, data_tmp, loop_weights);
- } while ((groups = groups->next));
+ const int type = bm->ldata.layers[layer_n].type;
+ const int size = CustomData_sizeof(type);
+ void *data_tmp = alloca(size);
+
+ do {
+ bm_vert_loop_groups_data_layer_merge_weights__single(
+ bm, groups->link, layer_n, data_tmp, loop_weights);
+ } while ((groups = groups->next));
}
/** \} */
diff --git a/source/blender/bmesh/intern/bmesh_interp.h b/source/blender/bmesh/intern/bmesh_interp.h
index ce6eb2186c5..bd3824ed3fd 100644
--- a/source/blender/bmesh/intern/bmesh_interp.h
+++ b/source/blender/bmesh/intern/bmesh_interp.h
@@ -24,51 +24,63 @@
struct LinkNode;
struct MemArena;
-void BM_loop_interp_multires_ex(
- BMesh *bm, BMLoop *l_dst, const BMFace *f_src,
- const float f_dst_center[3], const float f_src_center[3], const int cd_loop_mdisp_offset);
-void BM_loop_interp_multires(
- BMesh *bm, BMLoop *l_dst, const BMFace *f_src);
+void BM_loop_interp_multires_ex(BMesh *bm,
+ BMLoop *l_dst,
+ const BMFace *f_src,
+ const float f_dst_center[3],
+ const float f_src_center[3],
+ const int cd_loop_mdisp_offset);
+void BM_loop_interp_multires(BMesh *bm, BMLoop *l_dst, const BMFace *f_src);
-void BM_face_interp_multires_ex(
- BMesh *UNUSED(bm), BMFace *f_dst, const BMFace *f_src,
- const float f_dst_center[3], const float f_src_center[3], const int cd_loop_mdisp_offset);
+void BM_face_interp_multires_ex(BMesh *UNUSED(bm),
+ BMFace *f_dst,
+ const BMFace *f_src,
+ const float f_dst_center[3],
+ const float f_src_center[3],
+ const int cd_loop_mdisp_offset);
void BM_face_interp_multires(BMesh *bm, BMFace *f_dst, const BMFace *f_src);
-void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src);
+void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src);
-void BM_data_interp_from_verts(BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v_dst, const float fac);
-void BM_data_interp_from_edges(BMesh *bm, const BMEdge *e_src_1, const BMEdge *e_src_2, BMEdge *e_dst, const float fac);
-void BM_data_interp_face_vert_edge(BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v, BMEdge *e, const float fac);
-void BM_data_layer_add(BMesh *bm, CustomData *data, int type);
-void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name);
-void BM_data_layer_free(BMesh *bm, CustomData *data, int type);
-void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n);
-void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int dst_n);
+void BM_data_interp_from_verts(
+ BMesh *bm, const BMVert *v_src_1, const BMVert *v_src_2, BMVert *v_dst, const float fac);
+void BM_data_interp_from_edges(
+ BMesh *bm, const BMEdge *e_src_1, const BMEdge *e_src_2, BMEdge *e_dst, const float fac);
+void BM_data_interp_face_vert_edge(BMesh *bm,
+ const BMVert *v_src_1,
+ const BMVert *v_src_2,
+ BMVert *v,
+ BMEdge *e,
+ const float fac);
+void BM_data_layer_add(BMesh *bm, CustomData *data, int type);
+void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name);
+void BM_data_layer_free(BMesh *bm, CustomData *data, int type);
+void BM_data_layer_free_n(BMesh *bm, CustomData *data, int type, int n);
+void BM_data_layer_copy(BMesh *bm, CustomData *data, int type, int src_n, int dst_n);
float BM_elem_float_data_get(CustomData *cd, void *element, int type);
-void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val);
+void BM_elem_float_data_set(CustomData *cd, void *element, int type, const float val);
-void BM_face_interp_from_face_ex(
- BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex,
- const void **blocks, const void **blocks_v,
- float (*cos_2d)[2], float axis_mat[3][3]);
-void BM_face_interp_from_face(
- BMesh *bm, BMFace *f_dst, const BMFace *f_src,
- const bool do_vertex);
-void BM_loop_interp_from_face(
- BMesh *bm, BMLoop *l_dst, const BMFace *f_src,
- const bool do_vertex, const bool do_multires);
+void BM_face_interp_from_face_ex(BMesh *bm,
+ BMFace *f_dst,
+ const BMFace *f_src,
+ const bool do_vertex,
+ const void **blocks,
+ const void **blocks_v,
+ float (*cos_2d)[2],
+ float axis_mat[3][3]);
+void BM_face_interp_from_face(BMesh *bm, BMFace *f_dst, const BMFace *f_src, const bool do_vertex);
+void BM_loop_interp_from_face(
+ BMesh *bm, BMLoop *l_dst, const BMFace *f_src, const bool do_vertex, const bool do_multires);
-void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f);
+void BM_face_multires_bounds_smooth(BMesh *bm, BMFace *f);
struct LinkNode *BM_vert_loop_groups_data_layer_create(
- BMesh *bm, BMVert *v, const int layer_n,
- const float *loop_weights, struct MemArena *arena);
-void BM_vert_loop_groups_data_layer_merge(
- BMesh *bm, struct LinkNode *groups, const int layer_n);
-void BM_vert_loop_groups_data_layer_merge_weights(
- BMesh *bm, struct LinkNode *groups, const int layer_n,
- const float *loop_weights);
+ BMesh *bm, BMVert *v, const int layer_n, const float *loop_weights, struct MemArena *arena);
+void BM_vert_loop_groups_data_layer_merge(BMesh *bm, struct LinkNode *groups, const int layer_n);
+void BM_vert_loop_groups_data_layer_merge_weights(BMesh *bm,
+ struct LinkNode *groups,
+ const int layer_n,
+ const float *loop_weights);
#endif /* __BMESH_INTERP_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c
index 31e0fc00f59..b1e20dd6058 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.c
+++ b/source/blender/bmesh/intern/bmesh_iterators.c
@@ -31,20 +31,20 @@
#include "intern/bmesh_private.h"
const char bm_iter_itype_htype_map[BM_ITYPE_MAX] = {
- '\0',
- BM_VERT, /* BM_VERTS_OF_MESH */
- BM_EDGE, /* BM_EDGES_OF_MESH */
- BM_FACE, /* BM_FACES_OF_MESH */
- BM_EDGE, /* BM_EDGES_OF_VERT */
- BM_FACE, /* BM_FACES_OF_VERT */
- BM_LOOP, /* BM_LOOPS_OF_VERT */
- BM_VERT, /* BM_VERTS_OF_EDGE */
- BM_FACE, /* BM_FACES_OF_EDGE */
- BM_VERT, /* BM_VERTS_OF_FACE */
- BM_EDGE, /* BM_EDGES_OF_FACE */
- BM_LOOP, /* BM_LOOPS_OF_FACE */
- BM_LOOP, /* BM_LOOPS_OF_LOOP */
- BM_LOOP, /* BM_LOOPS_OF_EDGE */
+ '\0',
+ BM_VERT, /* BM_VERTS_OF_MESH */
+ BM_EDGE, /* BM_EDGES_OF_MESH */
+ BM_FACE, /* BM_FACES_OF_MESH */
+ BM_EDGE, /* BM_EDGES_OF_VERT */
+ BM_FACE, /* BM_FACES_OF_VERT */
+ BM_LOOP, /* BM_LOOPS_OF_VERT */
+ BM_VERT, /* BM_VERTS_OF_EDGE */
+ BM_FACE, /* BM_FACES_OF_EDGE */
+ BM_VERT, /* BM_VERTS_OF_FACE */
+ BM_EDGE, /* BM_EDGES_OF_FACE */
+ BM_LOOP, /* BM_LOOPS_OF_FACE */
+ BM_LOOP, /* BM_LOOPS_OF_LOOP */
+ BM_LOOP, /* BM_LOOPS_OF_EDGE */
};
/**
@@ -52,25 +52,25 @@ const char bm_iter_itype_htype_map[BM_ITYPE_MAX] = {
*/
int BM_iter_mesh_count(const char itype, BMesh *bm)
{
- int count;
+ int count;
- switch (itype) {
- case BM_VERTS_OF_MESH:
- count = bm->totvert;
- break;
- case BM_EDGES_OF_MESH:
- count = bm->totedge;
- break;
- case BM_FACES_OF_MESH:
- count = bm->totface;
- break;
- default:
- count = 0;
- BLI_assert(0);
- break;
- }
+ switch (itype) {
+ case BM_VERTS_OF_MESH:
+ count = bm->totvert;
+ break;
+ case BM_EDGES_OF_MESH:
+ count = bm->totedge;
+ break;
+ case BM_FACES_OF_MESH:
+ count = bm->totface;
+ break;
+ default:
+ count = 0;
+ BLI_assert(0);
+ break;
+ }
- return count;
+ return count;
}
/**
@@ -78,27 +78,26 @@ int BM_iter_mesh_count(const char itype, BMesh *bm)
*/
void *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index)
{
- BMIter iter;
- void *val;
- int i;
+ BMIter iter;
+ void *val;
+ int i;
- /* sanity check */
- if (index < 0) {
- return NULL;
- }
+ /* sanity check */
+ if (index < 0) {
+ return NULL;
+ }
- val = BM_iter_new(&iter, bm, itype, data);
+ val = BM_iter_new(&iter, bm, itype, data);
- i = 0;
- while (i < index) {
- val = BM_iter_step(&iter);
- i++;
- }
+ i = 0;
+ while (i < index) {
+ val = BM_iter_step(&iter);
+ i++;
+ }
- return val;
+ return val;
}
-
/**
* \brief Iterator as Array
*
@@ -107,53 +106,55 @@ 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 i = 0;
+ int i = 0;
- /* sanity check */
- if (len > 0) {
- BMIter iter;
- void *ele;
+ /* sanity check */
+ if (len > 0) {
+ BMIter iter;
+ void *ele;
- for (ele = BM_iter_new(&iter, bm, itype, data); ele; ele = BM_iter_step(&iter)) {
- array[i] = ele;
- i++;
- if (i == len) {
- return len;
- }
- }
- }
+ for (ele = BM_iter_new(&iter, bm, itype, data); ele; ele = BM_iter_step(&iter)) {
+ array[i] = ele;
+ i++;
+ if (i == len) {
+ return len;
+ }
+ }
+ }
- return i;
+ return i;
}
/**
* \brief Operator Iterator as Array
*
* Sometimes its convenient to get the iterator as an array.
*/
-int BMO_iter_as_array(
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask,
- void **array, const int len)
+int BMO_iter_as_array(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char restrictmask,
+ void **array,
+ const int len)
{
- int i = 0;
+ int i = 0;
- /* sanity check */
- if (len > 0) {
- BMOIter oiter;
- void *ele;
+ /* sanity check */
+ if (len > 0) {
+ BMOIter oiter;
+ void *ele;
- for (ele = BMO_iter_new(&oiter, slot_args, slot_name, restrictmask); ele; ele = BMO_iter_step(&oiter)) {
- array[i] = ele;
- i++;
- if (i == len) {
- return len;
- }
- }
- }
+ for (ele = BMO_iter_new(&oiter, slot_args, slot_name, restrictmask); ele;
+ ele = BMO_iter_step(&oiter)) {
+ array[i] = ele;
+ i++;
+ if (i == len) {
+ return len;
+ }
+ }
+ }
- return i;
+ return i;
}
-
/**
* \brief Iterator as Array
*
@@ -164,143 +165,146 @@ int BMO_iter_as_array(
*
* Caller needs to free the array.
*/
-void *BM_iter_as_arrayN(
- BMesh *bm, const char itype, void *data, int *r_len,
- /* optional args to avoid an alloc (normally stack array) */
- void **stack_array, int stack_array_size)
-{
- BMIter iter;
-
- BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
-
- /* we can't rely on coun't being set */
- switch (itype) {
- case BM_VERTS_OF_MESH:
- iter.count = bm->totvert;
- break;
- case BM_EDGES_OF_MESH:
- iter.count = bm->totedge;
- break;
- case BM_FACES_OF_MESH:
- iter.count = bm->totface;
- break;
- default:
- break;
- }
-
- if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) {
- BMElem *ele;
- BMElem **array = iter.count > stack_array_size ?
- MEM_mallocN(sizeof(ele) * iter.count, __func__) :
- stack_array;
- 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;
- }
-}
-
-void *BMO_iter_as_arrayN(
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask,
- int *r_len,
- /* optional args to avoid an alloc (normally stack array) */
- void **stack_array, int stack_array_size)
-{
- BMOIter iter;
- BMElem *ele;
- int count = BMO_slot_buffer_count(slot_args, slot_name);
-
- BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
-
- if ((ele = BMO_iter_new(&iter, slot_args, slot_name, restrictmask)) && count > 0) {
- BMElem **array = count > stack_array_size ?
- MEM_mallocN(sizeof(ele) * count, __func__) :
- stack_array;
- int i = 0;
-
- do {
- array[i++] = ele;
- } while ((ele = BMO_iter_step(&iter)));
- BLI_assert(i <= count);
-
- if (i != count) {
- if ((void **)array != stack_array) {
- array = MEM_reallocN(array, sizeof(ele) * i);
- }
- }
- *r_len = i;
- return array;
- }
- else {
- *r_len = 0;
- return NULL;
- }
-}
-
-int BM_iter_mesh_bitmap_from_filter(
- const char itype, BMesh *bm,
- BLI_bitmap *bitmap,
- bool (*test_fn)(BMElem *, void *user_data),
- void *user_data)
-{
- BMIter iter;
- BMElem *ele;
- int i;
- int bitmap_enabled = 0;
-
- BM_ITER_MESH_INDEX (ele, &iter, bm, itype, i) {
- if (test_fn(ele, user_data)) {
- BLI_BITMAP_ENABLE(bitmap, i);
- bitmap_enabled++;
- }
- else {
- BLI_BITMAP_DISABLE(bitmap, i);
- }
- }
-
- return bitmap_enabled;
+void *BM_iter_as_arrayN(BMesh *bm,
+ const char itype,
+ void *data,
+ int *r_len,
+ /* optional args to avoid an alloc (normally stack array) */
+ void **stack_array,
+ int stack_array_size)
+{
+ BMIter iter;
+
+ BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
+
+ /* we can't rely on coun't being set */
+ switch (itype) {
+ case BM_VERTS_OF_MESH:
+ iter.count = bm->totvert;
+ break;
+ case BM_EDGES_OF_MESH:
+ iter.count = bm->totedge;
+ break;
+ case BM_FACES_OF_MESH:
+ iter.count = bm->totface;
+ break;
+ default:
+ break;
+ }
+
+ if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) {
+ BMElem *ele;
+ BMElem **array = iter.count > stack_array_size ?
+ MEM_mallocN(sizeof(ele) * iter.count, __func__) :
+ stack_array;
+ 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;
+ }
+}
+
+void *BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char restrictmask,
+ int *r_len,
+ /* optional args to avoid an alloc (normally stack array) */
+ void **stack_array,
+ int stack_array_size)
+{
+ BMOIter iter;
+ BMElem *ele;
+ int count = BMO_slot_buffer_count(slot_args, slot_name);
+
+ BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
+
+ if ((ele = BMO_iter_new(&iter, slot_args, slot_name, restrictmask)) && count > 0) {
+ BMElem **array = count > stack_array_size ? MEM_mallocN(sizeof(ele) * count, __func__) :
+ stack_array;
+ int i = 0;
+
+ do {
+ array[i++] = ele;
+ } while ((ele = BMO_iter_step(&iter)));
+ BLI_assert(i <= count);
+
+ if (i != count) {
+ if ((void **)array != stack_array) {
+ array = MEM_reallocN(array, sizeof(ele) * i);
+ }
+ }
+ *r_len = i;
+ return array;
+ }
+ else {
+ *r_len = 0;
+ return NULL;
+ }
+}
+
+int BM_iter_mesh_bitmap_from_filter(const char itype,
+ BMesh *bm,
+ BLI_bitmap *bitmap,
+ bool (*test_fn)(BMElem *, void *user_data),
+ void *user_data)
+{
+ BMIter iter;
+ BMElem *ele;
+ int i;
+ int bitmap_enabled = 0;
+
+ BM_ITER_MESH_INDEX (ele, &iter, bm, itype, i) {
+ if (test_fn(ele, user_data)) {
+ BLI_BITMAP_ENABLE(bitmap, i);
+ bitmap_enabled++;
+ }
+ else {
+ BLI_BITMAP_DISABLE(bitmap, i);
+ }
+ }
+
+ return bitmap_enabled;
}
/**
* Needed when we want to check faces, but return a loop aligned array.
*/
-int BM_iter_mesh_bitmap_from_filter_tessface(
- BMesh *bm,
- BLI_bitmap *bitmap,
- bool (*test_fn)(BMFace *, void *user_data),
- void *user_data)
-{
- BMIter iter;
- BMFace *f;
- int i;
- int j = 0;
- int bitmap_enabled = 0;
-
- BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
- if (test_fn(f, user_data)) {
- for (int tri = 2; tri < f->len; tri++) {
- BLI_BITMAP_ENABLE(bitmap, j);
- bitmap_enabled++;
- j++;
- }
- }
- else {
- for (int tri = 2; tri < f->len; tri++) {
- BLI_BITMAP_DISABLE(bitmap, j);
- j++;
- }
- }
- }
-
- return bitmap_enabled;
+int BM_iter_mesh_bitmap_from_filter_tessface(BMesh *bm,
+ BLI_bitmap *bitmap,
+ bool (*test_fn)(BMFace *, void *user_data),
+ void *user_data)
+{
+ BMIter iter;
+ BMFace *f;
+ int i;
+ int j = 0;
+ int bitmap_enabled = 0;
+
+ BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
+ if (test_fn(f, user_data)) {
+ for (int tri = 2; tri < f->len; tri++) {
+ BLI_BITMAP_ENABLE(bitmap, j);
+ bitmap_enabled++;
+ j++;
+ }
+ }
+ else {
+ for (int tri = 2; tri < f->len; tri++) {
+ BLI_BITMAP_DISABLE(bitmap, j);
+ j++;
+ }
+ }
+ }
+
+ return bitmap_enabled;
}
/**
@@ -310,17 +314,17 @@ int BM_iter_mesh_bitmap_from_filter_tessface(
*/
int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value)
{
- BMIter iter;
- BMElem *ele;
- int count = 0;
+ BMIter iter;
+ BMElem *ele;
+ int count = 0;
- BM_ITER_ELEM (ele, &iter, data, itype) {
- if (BM_elem_flag_test_bool(ele, hflag) == value) {
- count++;
- }
- }
+ BM_ITER_ELEM (ele, &iter, data, itype) {
+ if (BM_elem_flag_test_bool(ele, hflag) == value) {
+ count++;
+ }
+ }
- return count;
+ return count;
}
/**
@@ -329,52 +333,46 @@ int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, cons
* Counts how many flagged / unflagged items are found in this element.
*/
int BMO_iter_elem_count_flag(
- BMesh *bm, const char itype, void *data,
- const short oflag, const bool value)
-{
- BMIter iter;
- int count = 0;
-
- /* loops have no header flags */
- BLI_assert(bm_iter_itype_htype_map[itype] != BM_LOOP);
-
- switch (bm_iter_itype_htype_map[itype]) {
- case BM_VERT:
- {
- BMVert *ele;
- BM_ITER_ELEM (ele, &iter, data, itype) {
- if (BMO_vert_flag_test_bool(bm, ele, oflag) == value) {
- count++;
- }
- }
- break;
- }
- case BM_EDGE:
- {
- BMEdge *ele;
- BM_ITER_ELEM (ele, &iter, data, itype) {
- if (BMO_edge_flag_test_bool(bm, ele, oflag) == value) {
- count++;
- }
- }
- break;
- }
- case BM_FACE:
- {
- BMFace *ele;
- BM_ITER_ELEM (ele, &iter, data, itype) {
- if (BMO_face_flag_test_bool(bm, ele, oflag) == value) {
- count++;
- }
- }
- break;
- }
-
- }
- return count;
+ BMesh *bm, const char itype, void *data, const short oflag, const bool value)
+{
+ BMIter iter;
+ int count = 0;
+
+ /* loops have no header flags */
+ BLI_assert(bm_iter_itype_htype_map[itype] != BM_LOOP);
+
+ switch (bm_iter_itype_htype_map[itype]) {
+ case BM_VERT: {
+ BMVert *ele;
+ BM_ITER_ELEM (ele, &iter, data, itype) {
+ if (BMO_vert_flag_test_bool(bm, ele, oflag) == value) {
+ count++;
+ }
+ }
+ break;
+ }
+ case BM_EDGE: {
+ BMEdge *ele;
+ BM_ITER_ELEM (ele, &iter, data, itype) {
+ if (BMO_edge_flag_test_bool(bm, ele, oflag) == value) {
+ count++;
+ }
+ }
+ break;
+ }
+ case BM_FACE: {
+ BMFace *ele;
+ BM_ITER_ELEM (ele, &iter, data, itype) {
+ if (BMO_face_flag_test_bool(bm, ele, oflag) == value) {
+ count++;
+ }
+ }
+ break;
+ }
+ }
+ return count;
}
-
/**
* \brief Mesh Iter Flag Count
*
@@ -382,17 +380,17 @@ int BMO_iter_elem_count_flag(
*/
int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value)
{
- BMIter iter;
- BMElem *ele;
- int count = 0;
+ BMIter iter;
+ BMElem *ele;
+ int count = 0;
- BM_ITER_MESH (ele, &iter, bm, itype) {
- if (BM_elem_flag_test_bool(ele, hflag) == value) {
- count++;
- }
- }
+ BM_ITER_MESH (ele, &iter, bm, itype) {
+ if (BM_elem_flag_test_bool(ele, hflag) == value) {
+ count++;
+ }
+ }
- return count;
+ return count;
}
/**
@@ -424,17 +422,17 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const
void bmiter__elem_of_mesh_begin(struct BMIter__elem_of_mesh *iter)
{
#ifdef USE_IMMUTABLE_ASSERT
- ((BMIter *)iter)->count = BLI_mempool_len(iter->pooliter.pool);
+ ((BMIter *)iter)->count = BLI_mempool_len(iter->pooliter.pool);
#endif
- BLI_mempool_iternew(iter->pooliter.pool, &iter->pooliter);
+ BLI_mempool_iternew(iter->pooliter.pool, &iter->pooliter);
}
void *bmiter__elem_of_mesh_step(struct BMIter__elem_of_mesh *iter)
{
#ifdef USE_IMMUTABLE_ASSERT
- BLI_assert(((BMIter *)iter)->count <= BLI_mempool_len(iter->pooliter.pool));
+ BLI_assert(((BMIter *)iter)->count <= BLI_mempool_len(iter->pooliter.pool));
#endif
- return BLI_mempool_iterstep(&iter->pooliter);
+ return BLI_mempool_iterstep(&iter->pooliter);
}
#ifdef USE_IMMUTABLE_ASSERT
@@ -445,274 +443,273 @@ void *bmiter__elem_of_mesh_step(struct BMIter__elem_of_mesh *iter)
* EDGE OF VERT CALLBACKS
*/
-void bmiter__edge_of_vert_begin(struct BMIter__edge_of_vert *iter)
+void bmiter__edge_of_vert_begin(struct BMIter__edge_of_vert *iter)
{
- if (iter->vdata->e) {
- iter->e_first = iter->vdata->e;
- iter->e_next = iter->vdata->e;
- }
- else {
- iter->e_first = NULL;
- iter->e_next = NULL;
- }
+ if (iter->vdata->e) {
+ iter->e_first = iter->vdata->e;
+ iter->e_next = iter->vdata->e;
+ }
+ else {
+ iter->e_first = NULL;
+ iter->e_next = NULL;
+ }
}
-void *bmiter__edge_of_vert_step(struct BMIter__edge_of_vert *iter)
+void *bmiter__edge_of_vert_step(struct BMIter__edge_of_vert *iter)
{
- BMEdge *e_curr = iter->e_next;
+ BMEdge *e_curr = iter->e_next;
- if (iter->e_next) {
- iter->e_next = bmesh_disk_edge_next(iter->e_next, iter->vdata);
- if (iter->e_next == iter->e_first) {
- iter->e_next = NULL;
- }
- }
+ if (iter->e_next) {
+ iter->e_next = bmesh_disk_edge_next(iter->e_next, iter->vdata);
+ if (iter->e_next == iter->e_first) {
+ iter->e_next = NULL;
+ }
+ }
- return e_curr;
+ return e_curr;
}
/*
* FACE OF VERT CALLBACKS
*/
-void bmiter__face_of_vert_begin(struct BMIter__face_of_vert *iter)
+void bmiter__face_of_vert_begin(struct BMIter__face_of_vert *iter)
{
- ((BMIter *)iter)->count = bmesh_disk_facevert_count(iter->vdata);
- if (((BMIter *)iter)->count) {
- iter->l_first = bmesh_disk_faceloop_find_first(iter->vdata->e, iter->vdata);
- iter->e_first = iter->l_first->e;
- iter->e_next = iter->e_first;
- iter->l_next = iter->l_first;
- }
- else {
- iter->l_first = iter->l_next = NULL;
- iter->e_first = iter->e_next = NULL;
- }
+ ((BMIter *)iter)->count = bmesh_disk_facevert_count(iter->vdata);
+ if (((BMIter *)iter)->count) {
+ iter->l_first = bmesh_disk_faceloop_find_first(iter->vdata->e, iter->vdata);
+ iter->e_first = iter->l_first->e;
+ iter->e_next = iter->e_first;
+ iter->l_next = iter->l_first;
+ }
+ else {
+ iter->l_first = iter->l_next = NULL;
+ iter->e_first = iter->e_next = NULL;
+ }
}
-void *bmiter__face_of_vert_step(struct BMIter__face_of_vert *iter)
+void *bmiter__face_of_vert_step(struct BMIter__face_of_vert *iter)
{
- BMLoop *l_curr = iter->l_next;
+ BMLoop *l_curr = iter->l_next;
- if (((BMIter *)iter)->count && iter->l_next) {
- ((BMIter *)iter)->count--;
- iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata);
- if (iter->l_next == iter->l_first) {
- iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata);
- iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata);
- iter->l_next = iter->l_first;
- }
- }
+ if (((BMIter *)iter)->count && iter->l_next) {
+ ((BMIter *)iter)->count--;
+ iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata);
+ if (iter->l_next == iter->l_first) {
+ iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata);
+ iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata);
+ iter->l_next = iter->l_first;
+ }
+ }
- if (!((BMIter *)iter)->count) {
- iter->l_next = NULL;
- }
+ if (!((BMIter *)iter)->count) {
+ iter->l_next = NULL;
+ }
- return l_curr ? l_curr->f : NULL;
+ return l_curr ? l_curr->f : NULL;
}
-
/*
* LOOP OF VERT CALLBACKS
*/
-void bmiter__loop_of_vert_begin(struct BMIter__loop_of_vert *iter)
+void bmiter__loop_of_vert_begin(struct BMIter__loop_of_vert *iter)
{
- ((BMIter *)iter)->count = bmesh_disk_facevert_count(iter->vdata);
- if (((BMIter *)iter)->count) {
- iter->l_first = bmesh_disk_faceloop_find_first(iter->vdata->e, iter->vdata);
- iter->e_first = iter->l_first->e;
- iter->e_next = iter->e_first;
- iter->l_next = iter->l_first;
- }
- else {
- iter->l_first = iter->l_next = NULL;
- iter->e_first = iter->e_next = NULL;
- }
+ ((BMIter *)iter)->count = bmesh_disk_facevert_count(iter->vdata);
+ if (((BMIter *)iter)->count) {
+ iter->l_first = bmesh_disk_faceloop_find_first(iter->vdata->e, iter->vdata);
+ iter->e_first = iter->l_first->e;
+ iter->e_next = iter->e_first;
+ iter->l_next = iter->l_first;
+ }
+ else {
+ iter->l_first = iter->l_next = NULL;
+ iter->e_first = iter->e_next = NULL;
+ }
}
-void *bmiter__loop_of_vert_step(struct BMIter__loop_of_vert *iter)
+void *bmiter__loop_of_vert_step(struct BMIter__loop_of_vert *iter)
{
- BMLoop *l_curr = iter->l_next;
+ BMLoop *l_curr = iter->l_next;
- if (((BMIter *)iter)->count) {
- ((BMIter *)iter)->count--;
- iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata);
- if (iter->l_next == iter->l_first) {
- iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata);
- iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata);
- iter->l_next = iter->l_first;
- }
- }
+ if (((BMIter *)iter)->count) {
+ ((BMIter *)iter)->count--;
+ iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata);
+ if (iter->l_next == iter->l_first) {
+ iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata);
+ iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata);
+ iter->l_next = iter->l_first;
+ }
+ }
- if (!((BMIter *)iter)->count) {
- iter->l_next = NULL;
- }
+ if (!((BMIter *)iter)->count) {
+ iter->l_next = NULL;
+ }
- /* NULL on finish */
- return l_curr;
+ /* NULL on finish */
+ return l_curr;
}
/*
* LOOP OF EDGE CALLBACKS
*/
-void bmiter__loop_of_edge_begin(struct BMIter__loop_of_edge *iter)
+void bmiter__loop_of_edge_begin(struct BMIter__loop_of_edge *iter)
{
- iter->l_first = iter->l_next = iter->edata->l;
+ iter->l_first = iter->l_next = iter->edata->l;
}
-void *bmiter__loop_of_edge_step(struct BMIter__loop_of_edge *iter)
+void *bmiter__loop_of_edge_step(struct BMIter__loop_of_edge *iter)
{
- BMLoop *l_curr = iter->l_next;
+ BMLoop *l_curr = iter->l_next;
- if (iter->l_next) {
- iter->l_next = iter->l_next->radial_next;
- if (iter->l_next == iter->l_first) {
- iter->l_next = NULL;
- }
- }
+ if (iter->l_next) {
+ iter->l_next = iter->l_next->radial_next;
+ if (iter->l_next == iter->l_first) {
+ iter->l_next = NULL;
+ }
+ }
- /* NULL on finish */
- return l_curr;
+ /* NULL on finish */
+ return l_curr;
}
/*
* LOOP OF LOOP CALLBACKS
*/
-void bmiter__loop_of_loop_begin(struct BMIter__loop_of_loop *iter)
+void bmiter__loop_of_loop_begin(struct BMIter__loop_of_loop *iter)
{
- iter->l_first = iter->ldata;
- iter->l_next = iter->l_first->radial_next;
+ iter->l_first = iter->ldata;
+ iter->l_next = iter->l_first->radial_next;
- if (iter->l_next == iter->l_first) {
- iter->l_next = NULL;
- }
+ if (iter->l_next == iter->l_first) {
+ iter->l_next = NULL;
+ }
}
-void *bmiter__loop_of_loop_step(struct BMIter__loop_of_loop *iter)
+void *bmiter__loop_of_loop_step(struct BMIter__loop_of_loop *iter)
{
- BMLoop *l_curr = iter->l_next;
+ BMLoop *l_curr = iter->l_next;
- if (iter->l_next) {
- iter->l_next = iter->l_next->radial_next;
- if (iter->l_next == iter->l_first) {
- iter->l_next = NULL;
- }
- }
+ if (iter->l_next) {
+ iter->l_next = iter->l_next->radial_next;
+ if (iter->l_next == iter->l_first) {
+ iter->l_next = NULL;
+ }
+ }
- /* NULL on finish */
- return l_curr;
+ /* NULL on finish */
+ return l_curr;
}
/*
* FACE OF EDGE CALLBACKS
*/
-void bmiter__face_of_edge_begin(struct BMIter__face_of_edge *iter)
+void bmiter__face_of_edge_begin(struct BMIter__face_of_edge *iter)
{
- iter->l_first = iter->l_next = iter->edata->l;
+ iter->l_first = iter->l_next = iter->edata->l;
}
-void *bmiter__face_of_edge_step(struct BMIter__face_of_edge *iter)
+void *bmiter__face_of_edge_step(struct BMIter__face_of_edge *iter)
{
- BMLoop *current = iter->l_next;
+ BMLoop *current = iter->l_next;
- if (iter->l_next) {
- iter->l_next = iter->l_next->radial_next;
- if (iter->l_next == iter->l_first) {
- iter->l_next = NULL;
- }
- }
+ if (iter->l_next) {
+ iter->l_next = iter->l_next->radial_next;
+ if (iter->l_next == iter->l_first) {
+ iter->l_next = NULL;
+ }
+ }
- return current ? current->f : NULL;
+ return current ? current->f : NULL;
}
/*
* VERTS OF EDGE CALLBACKS
*/
-void bmiter__vert_of_edge_begin(struct BMIter__vert_of_edge *iter)
+void bmiter__vert_of_edge_begin(struct BMIter__vert_of_edge *iter)
{
- ((BMIter *)iter)->count = 0;
+ ((BMIter *)iter)->count = 0;
}
-void *bmiter__vert_of_edge_step(struct BMIter__vert_of_edge *iter)
+void *bmiter__vert_of_edge_step(struct BMIter__vert_of_edge *iter)
{
- switch (((BMIter *)iter)->count++) {
- case 0:
- return iter->edata->v1;
- case 1:
- return iter->edata->v2;
- default:
- return NULL;
- }
+ switch (((BMIter *)iter)->count++) {
+ case 0:
+ return iter->edata->v1;
+ case 1:
+ return iter->edata->v2;
+ default:
+ return NULL;
+ }
}
/*
* VERT OF FACE CALLBACKS
*/
-void bmiter__vert_of_face_begin(struct BMIter__vert_of_face *iter)
+void bmiter__vert_of_face_begin(struct BMIter__vert_of_face *iter)
{
- iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata);
+ iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata);
}
-void *bmiter__vert_of_face_step(struct BMIter__vert_of_face *iter)
+void *bmiter__vert_of_face_step(struct BMIter__vert_of_face *iter)
{
- BMLoop *l_curr = iter->l_next;
+ BMLoop *l_curr = iter->l_next;
- if (iter->l_next) {
- iter->l_next = iter->l_next->next;
- if (iter->l_next == iter->l_first) {
- iter->l_next = NULL;
- }
- }
+ if (iter->l_next) {
+ iter->l_next = iter->l_next->next;
+ if (iter->l_next == iter->l_first) {
+ iter->l_next = NULL;
+ }
+ }
- return l_curr ? l_curr->v : NULL;
+ return l_curr ? l_curr->v : NULL;
}
/*
* EDGE OF FACE CALLBACKS
*/
-void bmiter__edge_of_face_begin(struct BMIter__edge_of_face *iter)
+void bmiter__edge_of_face_begin(struct BMIter__edge_of_face *iter)
{
- iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata);
+ iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata);
}
-void *bmiter__edge_of_face_step(struct BMIter__edge_of_face *iter)
+void *bmiter__edge_of_face_step(struct BMIter__edge_of_face *iter)
{
- BMLoop *l_curr = iter->l_next;
+ BMLoop *l_curr = iter->l_next;
- if (iter->l_next) {
- iter->l_next = iter->l_next->next;
- if (iter->l_next == iter->l_first) {
- iter->l_next = NULL;
- }
- }
+ if (iter->l_next) {
+ iter->l_next = iter->l_next->next;
+ if (iter->l_next == iter->l_first) {
+ iter->l_next = NULL;
+ }
+ }
- return l_curr ? l_curr->e : NULL;
+ return l_curr ? l_curr->e : NULL;
}
/*
* LOOP OF FACE CALLBACKS
*/
-void bmiter__loop_of_face_begin(struct BMIter__loop_of_face *iter)
+void bmiter__loop_of_face_begin(struct BMIter__loop_of_face *iter)
{
- iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata);
+ iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata);
}
-void *bmiter__loop_of_face_step(struct BMIter__loop_of_face *iter)
+void *bmiter__loop_of_face_step(struct BMIter__loop_of_face *iter)
{
- BMLoop *l_curr = iter->l_next;
+ BMLoop *l_curr = iter->l_next;
- if (iter->l_next) {
- iter->l_next = iter->l_next->next;
- if (iter->l_next == iter->l_first) {
- iter->l_next = NULL;
- }
- }
+ if (iter->l_next) {
+ iter->l_next = iter->l_next->next;
+ if (iter->l_next == iter->l_first) {
+ iter->l_next = NULL;
+ }
+ }
- return l_curr;
+ return l_curr;
}
diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h
index 73784dabea8..a809c9a3d32 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.h
+++ b/source/blender/bmesh/intern/bmesh_iterators.h
@@ -48,27 +48,27 @@
* be sure to keep 'bm_iter_itype_htype_map' in sync with any changes
*/
typedef enum BMIterType {
- BM_VERTS_OF_MESH = 1,
- BM_EDGES_OF_MESH = 2,
- BM_FACES_OF_MESH = 3,
- /* these are topological iterators. */
- BM_EDGES_OF_VERT = 4,
- BM_FACES_OF_VERT = 5,
- BM_LOOPS_OF_VERT = 6,
- BM_VERTS_OF_EDGE = 7, /* just v1, v2: added so py can use generalized sequencer wrapper */
- BM_FACES_OF_EDGE = 8,
- BM_VERTS_OF_FACE = 9,
- BM_EDGES_OF_FACE = 10,
- BM_LOOPS_OF_FACE = 11,
- /* returns elements from all boundaries, and returns
- * the first element at the end to flag that we're entering
- * a different face hole boundary*/
- // BM_ALL_LOOPS_OF_FACE = 12,
- /* iterate through loops around this loop, which are fetched
- * from the other faces in the radial cycle surrounding the
- * input loop's edge.*/
- BM_LOOPS_OF_LOOP = 12,
- BM_LOOPS_OF_EDGE = 13,
+ BM_VERTS_OF_MESH = 1,
+ BM_EDGES_OF_MESH = 2,
+ BM_FACES_OF_MESH = 3,
+ /* these are topological iterators. */
+ BM_EDGES_OF_VERT = 4,
+ BM_FACES_OF_VERT = 5,
+ BM_LOOPS_OF_VERT = 6,
+ BM_VERTS_OF_EDGE = 7, /* just v1, v2: added so py can use generalized sequencer wrapper */
+ BM_FACES_OF_EDGE = 8,
+ BM_VERTS_OF_FACE = 9,
+ BM_EDGES_OF_FACE = 10,
+ BM_LOOPS_OF_FACE = 11,
+ /* returns elements from all boundaries, and returns
+ * the first element at the end to flag that we're entering
+ * a different face hole boundary*/
+ // BM_ALL_LOOPS_OF_FACE = 12,
+ /* iterate through loops around this loop, which are fetched
+ * from the other faces in the radial cycle surrounding the
+ * input loop's edge.*/
+ BM_LOOPS_OF_LOOP = 12,
+ BM_LOOPS_OF_EDGE = 13,
} BMIterType;
#define BM_ITYPE_MAX 14
@@ -77,153 +77,157 @@ typedef enum BMIterType {
extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX];
#define BM_ITER_MESH(ele, iter, bm, itype) \
- for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
- ele; \
- BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar) \
- for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL), indexvar = 0; \
- ele; \
- BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++)
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL), indexvar = 0; ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++)
/* a version of BM_ITER_MESH which keeps the next item in storage
* so we can delete the current item, see bug [#36923] */
#ifdef DEBUG
# define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \
- for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
- ele ? ((void)((iter)->count = BM_iter_mesh_count(itype, bm)), \
- (void)(ele_next = BM_iter_step(iter)), 1) : 0; \
- BM_CHECK_TYPE_ELEM_ASSIGN(ele) = ele_next)
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
+ ele ? ((void)((iter)->count = BM_iter_mesh_count(itype, bm)), \
+ (void)(ele_next = BM_iter_step(iter)), \
+ 1) : \
+ 0; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = ele_next)
#else
# define BM_ITER_MESH_MUTABLE(ele, ele_next, iter, bm, itype) \
- for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
- ele ? ((BM_CHECK_TYPE_ELEM_ASSIGN(ele_next) = BM_iter_step(iter)), 1) : 0; \
- ele = ele_next)
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, bm, itype, NULL); \
+ ele ? ((BM_CHECK_TYPE_ELEM_ASSIGN(ele_next) = BM_iter_step(iter)), 1) : 0; \
+ ele = ele_next)
#endif
-
#define BM_ITER_ELEM(ele, iter, data, itype) \
- for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data); \
- ele; \
- BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data); ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter))
#define BM_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar) \
- for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data), indexvar = 0; \
- ele; \
- BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++)
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_new(iter, NULL, itype, data), indexvar = 0; ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BM_iter_step(iter), (indexvar)++)
/* iterator type structs */
struct BMIter__elem_of_mesh {
- BLI_mempool_iter pooliter;
+ BLI_mempool_iter pooliter;
};
struct BMIter__edge_of_vert {
- BMVert *vdata;
- BMEdge *e_first, *e_next;
+ BMVert *vdata;
+ BMEdge *e_first, *e_next;
};
struct BMIter__face_of_vert {
- BMVert *vdata;
- BMLoop *l_first, *l_next;
- BMEdge *e_first, *e_next;
+ BMVert *vdata;
+ BMLoop *l_first, *l_next;
+ BMEdge *e_first, *e_next;
};
struct BMIter__loop_of_vert {
- BMVert *vdata;
- BMLoop *l_first, *l_next;
- BMEdge *e_first, *e_next;
+ BMVert *vdata;
+ BMLoop *l_first, *l_next;
+ BMEdge *e_first, *e_next;
};
struct BMIter__loop_of_edge {
- BMEdge *edata;
- BMLoop *l_first, *l_next;
+ BMEdge *edata;
+ BMLoop *l_first, *l_next;
};
struct BMIter__loop_of_loop {
- BMLoop *ldata;
- BMLoop *l_first, *l_next;
+ BMLoop *ldata;
+ BMLoop *l_first, *l_next;
};
struct BMIter__face_of_edge {
- BMEdge *edata;
- BMLoop *l_first, *l_next;
+ BMEdge *edata;
+ BMLoop *l_first, *l_next;
};
struct BMIter__vert_of_edge {
- BMEdge *edata;
+ BMEdge *edata;
};
struct BMIter__vert_of_face {
- BMFace *pdata;
- BMLoop *l_first, *l_next;
+ BMFace *pdata;
+ BMLoop *l_first, *l_next;
};
struct BMIter__edge_of_face {
- BMFace *pdata;
- BMLoop *l_first, *l_next;
+ BMFace *pdata;
+ BMLoop *l_first, *l_next;
};
struct BMIter__loop_of_face {
- BMFace *pdata;
- BMLoop *l_first, *l_next;
+ BMFace *pdata;
+ BMLoop *l_first, *l_next;
};
-typedef void (*BMIter__begin_cb) (void *);
-typedef void *(*BMIter__step_cb) (void *);
+typedef void (*BMIter__begin_cb)(void *);
+typedef void *(*BMIter__step_cb)(void *);
/* Iterator Structure */
/* note: some of these vars are not used,
* so they have been commented to save stack space since this struct is used all over */
typedef struct BMIter {
- /* keep union first */
- union {
- struct BMIter__elem_of_mesh elem_of_mesh;
-
- struct BMIter__edge_of_vert edge_of_vert;
- struct BMIter__face_of_vert face_of_vert;
- struct BMIter__loop_of_vert loop_of_vert;
- struct BMIter__loop_of_edge loop_of_edge;
- struct BMIter__loop_of_loop loop_of_loop;
- struct BMIter__face_of_edge face_of_edge;
- struct BMIter__vert_of_edge vert_of_edge;
- struct BMIter__vert_of_face vert_of_face;
- struct BMIter__edge_of_face edge_of_face;
- struct BMIter__loop_of_face loop_of_face;
- } data;
-
- BMIter__begin_cb begin;
- BMIter__step_cb step;
-
- int count; /* note, only some iterators set this, don't rely on it */
- char itype;
+ /* keep union first */
+ union {
+ struct BMIter__elem_of_mesh elem_of_mesh;
+
+ struct BMIter__edge_of_vert edge_of_vert;
+ struct BMIter__face_of_vert face_of_vert;
+ struct BMIter__loop_of_vert loop_of_vert;
+ struct BMIter__loop_of_edge loop_of_edge;
+ struct BMIter__loop_of_loop loop_of_loop;
+ struct BMIter__face_of_edge face_of_edge;
+ struct BMIter__vert_of_edge vert_of_edge;
+ struct BMIter__vert_of_face vert_of_face;
+ struct BMIter__edge_of_face edge_of_face;
+ struct BMIter__loop_of_face loop_of_face;
+ } data;
+
+ BMIter__begin_cb begin;
+ BMIter__step_cb step;
+
+ int count; /* note, only some iterators set this, don't rely on it */
+ char itype;
} BMIter;
-void *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index) ATTR_WARN_UNUSED_RESULT;
-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,
- void **stack_array, int stack_array_size) ATTR_WARN_UNUSED_RESULT;
-int BMO_iter_as_array(
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask,
- void **array, const int len);
-void *BMO_iter_as_arrayN(
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask,
- int *r_len,
- /* optional args to avoid an alloc (normally stack array) */
- void **stack_array, int stack_array_size);
-
-int BM_iter_mesh_bitmap_from_filter(
- const char itype, BMesh *bm,
- uint *bitmap,
- bool (*test_fn)(BMElem *, void *user_data),
- void *user_data);
-int BM_iter_mesh_bitmap_from_filter_tessface(
- BMesh *bm,
- uint *bitmap,
- bool (*test_fn)(BMFace *, void *user_data),
- void *user_data);
-
-int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value);
-int BMO_iter_elem_count_flag(BMesh *bm, const char itype, void *data, const short oflag, const bool value);
-int BM_iter_mesh_count(const char itype, BMesh *bm);
-int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value);
+void *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index) ATTR_WARN_UNUSED_RESULT;
+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,
+ void **stack_array,
+ int stack_array_size) ATTR_WARN_UNUSED_RESULT;
+int BMO_iter_as_array(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char restrictmask,
+ void **array,
+ const int len);
+void *BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char restrictmask,
+ int *r_len,
+ /* optional args to avoid an alloc (normally stack array) */
+ void **stack_array,
+ int stack_array_size);
+
+int BM_iter_mesh_bitmap_from_filter(const char itype,
+ BMesh *bm,
+ uint *bitmap,
+ bool (*test_fn)(BMElem *, void *user_data),
+ void *user_data);
+int BM_iter_mesh_bitmap_from_filter_tessface(BMesh *bm,
+ uint *bitmap,
+ bool (*test_fn)(BMFace *, void *user_data),
+ void *user_data);
+
+int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value);
+int BMO_iter_elem_count_flag(
+ BMesh *bm, const char itype, void *data, const short oflag, const bool value);
+int BM_iter_mesh_count(const char itype, BMesh *bm);
+int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value);
/* private for bmesh_iterators_inline.c */
#define BMITER_CB_DEF(name) \
- struct BMIter__##name; \
- void bmiter__##name##_begin(struct BMIter__##name *iter); \
- void *bmiter__##name##_step(struct BMIter__##name *iter)
+ struct BMIter__##name; \
+ void bmiter__##name##_begin(struct BMIter__##name *iter); \
+ void *bmiter__##name##_step(struct BMIter__##name *iter)
BMITER_CB_DEF(elem_of_mesh);
BMITER_CB_DEF(edge_of_vert);
@@ -242,11 +246,11 @@ BMITER_CB_DEF(loop_of_face);
#include "intern/bmesh_iterators_inline.h"
#define BM_ITER_CHECK_TYPE_DATA(data) \
- CHECK_TYPE_ANY(data, void *, BMFace *, BMEdge *, BMVert *, BMLoop *, BMElem *)
+ CHECK_TYPE_ANY(data, void *, BMFace *, BMEdge *, BMVert *, BMLoop *, BMElem *)
#define BM_iter_new(iter, bm, itype, data) \
- (BM_ITER_CHECK_TYPE_DATA(data), BM_iter_new(iter, bm, itype, data))
+ (BM_ITER_CHECK_TYPE_DATA(data), BM_iter_new(iter, bm, itype, data))
#define BM_iter_init(iter, bm, itype, data) \
- (BM_ITER_CHECK_TYPE_DATA(data), BM_iter_init(iter, bm, itype, data))
+ (BM_ITER_CHECK_TYPE_DATA(data), BM_iter_init(iter, bm, itype, data))
#endif /* __BMESH_ITERATORS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_iterators_inline.h b/source/blender/bmesh/intern/bmesh_iterators_inline.h
index 30740a1bc90..ed3a9a5be09 100644
--- a/source/blender/bmesh/intern/bmesh_iterators_inline.h
+++ b/source/blender/bmesh/intern/bmesh_iterators_inline.h
@@ -31,13 +31,11 @@
*
* Calls an iterators step function to return the next element.
*/
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE void *BM_iter_step(BMIter *iter)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE void *BM_iter_step(BMIter *iter)
{
- return iter->step(iter);
+ return iter->step(iter);
}
-
/**
* \brief Iterator Init
*
@@ -48,112 +46,112 @@ BLI_INLINE void *BM_iter_step(BMIter *iter)
ATTR_NONNULL(1)
BLI_INLINE bool BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *data)
{
- /* int argtype; */
- iter->itype = itype;
+ /* int argtype; */
+ iter->itype = itype;
- /* inlining optimizes out this switch when called with the defined type */
- switch ((BMIterType)itype) {
- case BM_VERTS_OF_MESH:
- BLI_assert(bm != NULL);
- BLI_assert(data == NULL);
- iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
- iter->step = (BMIter__step_cb)bmiter__elem_of_mesh_step;
- iter->data.elem_of_mesh.pooliter.pool = bm->vpool;
- break;
- case BM_EDGES_OF_MESH:
- BLI_assert(bm != NULL);
- BLI_assert(data == NULL);
- iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
- iter->step = (BMIter__step_cb)bmiter__elem_of_mesh_step;
- iter->data.elem_of_mesh.pooliter.pool = bm->epool;
- break;
- case BM_FACES_OF_MESH:
- BLI_assert(bm != NULL);
- BLI_assert(data == NULL);
- iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
- iter->step = (BMIter__step_cb)bmiter__elem_of_mesh_step;
- iter->data.elem_of_mesh.pooliter.pool = bm->fpool;
- break;
- case BM_EDGES_OF_VERT:
- BLI_assert(data != NULL);
- BLI_assert(((BMElem *)data)->head.htype == BM_VERT);
- iter->begin = (BMIter__begin_cb)bmiter__edge_of_vert_begin;
- iter->step = (BMIter__step_cb)bmiter__edge_of_vert_step;
- iter->data.edge_of_vert.vdata = (BMVert *)data;
- break;
- case BM_FACES_OF_VERT:
- BLI_assert(data != NULL);
- BLI_assert(((BMElem *)data)->head.htype == BM_VERT);
- iter->begin = (BMIter__begin_cb)bmiter__face_of_vert_begin;
- iter->step = (BMIter__step_cb)bmiter__face_of_vert_step;
- iter->data.face_of_vert.vdata = (BMVert *)data;
- break;
- case BM_LOOPS_OF_VERT:
- BLI_assert(data != NULL);
- BLI_assert(((BMElem *)data)->head.htype == BM_VERT);
- iter->begin = (BMIter__begin_cb)bmiter__loop_of_vert_begin;
- iter->step = (BMIter__step_cb)bmiter__loop_of_vert_step;
- iter->data.loop_of_vert.vdata = (BMVert *)data;
- break;
- case BM_VERTS_OF_EDGE:
- BLI_assert(data != NULL);
- BLI_assert(((BMElem *)data)->head.htype == BM_EDGE);
- iter->begin = (BMIter__begin_cb)bmiter__vert_of_edge_begin;
- iter->step = (BMIter__step_cb)bmiter__vert_of_edge_step;
- iter->data.vert_of_edge.edata = (BMEdge *)data;
- break;
- case BM_FACES_OF_EDGE:
- BLI_assert(data != NULL);
- BLI_assert(((BMElem *)data)->head.htype == BM_EDGE);
- iter->begin = (BMIter__begin_cb)bmiter__face_of_edge_begin;
- iter->step = (BMIter__step_cb)bmiter__face_of_edge_step;
- iter->data.face_of_edge.edata = (BMEdge *)data;
- break;
- case BM_VERTS_OF_FACE:
- BLI_assert(data != NULL);
- BLI_assert(((BMElem *)data)->head.htype == BM_FACE);
- iter->begin = (BMIter__begin_cb)bmiter__vert_of_face_begin;
- iter->step = (BMIter__step_cb)bmiter__vert_of_face_step;
- iter->data.vert_of_face.pdata = (BMFace *)data;
- break;
- case BM_EDGES_OF_FACE:
- BLI_assert(data != NULL);
- BLI_assert(((BMElem *)data)->head.htype == BM_FACE);
- iter->begin = (BMIter__begin_cb)bmiter__edge_of_face_begin;
- iter->step = (BMIter__step_cb)bmiter__edge_of_face_step;
- iter->data.edge_of_face.pdata = (BMFace *)data;
- break;
- case BM_LOOPS_OF_FACE:
- BLI_assert(data != NULL);
- BLI_assert(((BMElem *)data)->head.htype == BM_FACE);
- iter->begin = (BMIter__begin_cb)bmiter__loop_of_face_begin;
- iter->step = (BMIter__step_cb)bmiter__loop_of_face_step;
- iter->data.loop_of_face.pdata = (BMFace *)data;
- break;
- case BM_LOOPS_OF_LOOP:
- BLI_assert(data != NULL);
- BLI_assert(((BMElem *)data)->head.htype == BM_LOOP);
- iter->begin = (BMIter__begin_cb)bmiter__loop_of_loop_begin;
- iter->step = (BMIter__step_cb)bmiter__loop_of_loop_step;
- iter->data.loop_of_loop.ldata = (BMLoop *)data;
- break;
- case BM_LOOPS_OF_EDGE:
- BLI_assert(data != NULL);
- BLI_assert(((BMElem *)data)->head.htype == BM_EDGE);
- iter->begin = (BMIter__begin_cb)bmiter__loop_of_edge_begin;
- iter->step = (BMIter__step_cb)bmiter__loop_of_edge_step;
- iter->data.loop_of_edge.edata = (BMEdge *)data;
- break;
- default:
- /* should never happen */
- BLI_assert(0);
- return false;
- break;
- }
+ /* inlining optimizes out this switch when called with the defined type */
+ switch ((BMIterType)itype) {
+ case BM_VERTS_OF_MESH:
+ BLI_assert(bm != NULL);
+ BLI_assert(data == NULL);
+ iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
+ iter->step = (BMIter__step_cb)bmiter__elem_of_mesh_step;
+ iter->data.elem_of_mesh.pooliter.pool = bm->vpool;
+ break;
+ case BM_EDGES_OF_MESH:
+ BLI_assert(bm != NULL);
+ BLI_assert(data == NULL);
+ iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
+ iter->step = (BMIter__step_cb)bmiter__elem_of_mesh_step;
+ iter->data.elem_of_mesh.pooliter.pool = bm->epool;
+ break;
+ case BM_FACES_OF_MESH:
+ BLI_assert(bm != NULL);
+ BLI_assert(data == NULL);
+ iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
+ iter->step = (BMIter__step_cb)bmiter__elem_of_mesh_step;
+ iter->data.elem_of_mesh.pooliter.pool = bm->fpool;
+ break;
+ case BM_EDGES_OF_VERT:
+ BLI_assert(data != NULL);
+ BLI_assert(((BMElem *)data)->head.htype == BM_VERT);
+ iter->begin = (BMIter__begin_cb)bmiter__edge_of_vert_begin;
+ iter->step = (BMIter__step_cb)bmiter__edge_of_vert_step;
+ iter->data.edge_of_vert.vdata = (BMVert *)data;
+ break;
+ case BM_FACES_OF_VERT:
+ BLI_assert(data != NULL);
+ BLI_assert(((BMElem *)data)->head.htype == BM_VERT);
+ iter->begin = (BMIter__begin_cb)bmiter__face_of_vert_begin;
+ iter->step = (BMIter__step_cb)bmiter__face_of_vert_step;
+ iter->data.face_of_vert.vdata = (BMVert *)data;
+ break;
+ case BM_LOOPS_OF_VERT:
+ BLI_assert(data != NULL);
+ BLI_assert(((BMElem *)data)->head.htype == BM_VERT);
+ iter->begin = (BMIter__begin_cb)bmiter__loop_of_vert_begin;
+ iter->step = (BMIter__step_cb)bmiter__loop_of_vert_step;
+ iter->data.loop_of_vert.vdata = (BMVert *)data;
+ break;
+ case BM_VERTS_OF_EDGE:
+ BLI_assert(data != NULL);
+ BLI_assert(((BMElem *)data)->head.htype == BM_EDGE);
+ iter->begin = (BMIter__begin_cb)bmiter__vert_of_edge_begin;
+ iter->step = (BMIter__step_cb)bmiter__vert_of_edge_step;
+ iter->data.vert_of_edge.edata = (BMEdge *)data;
+ break;
+ case BM_FACES_OF_EDGE:
+ BLI_assert(data != NULL);
+ BLI_assert(((BMElem *)data)->head.htype == BM_EDGE);
+ iter->begin = (BMIter__begin_cb)bmiter__face_of_edge_begin;
+ iter->step = (BMIter__step_cb)bmiter__face_of_edge_step;
+ iter->data.face_of_edge.edata = (BMEdge *)data;
+ break;
+ case BM_VERTS_OF_FACE:
+ BLI_assert(data != NULL);
+ BLI_assert(((BMElem *)data)->head.htype == BM_FACE);
+ iter->begin = (BMIter__begin_cb)bmiter__vert_of_face_begin;
+ iter->step = (BMIter__step_cb)bmiter__vert_of_face_step;
+ iter->data.vert_of_face.pdata = (BMFace *)data;
+ break;
+ case BM_EDGES_OF_FACE:
+ BLI_assert(data != NULL);
+ BLI_assert(((BMElem *)data)->head.htype == BM_FACE);
+ iter->begin = (BMIter__begin_cb)bmiter__edge_of_face_begin;
+ iter->step = (BMIter__step_cb)bmiter__edge_of_face_step;
+ iter->data.edge_of_face.pdata = (BMFace *)data;
+ break;
+ case BM_LOOPS_OF_FACE:
+ BLI_assert(data != NULL);
+ BLI_assert(((BMElem *)data)->head.htype == BM_FACE);
+ iter->begin = (BMIter__begin_cb)bmiter__loop_of_face_begin;
+ iter->step = (BMIter__step_cb)bmiter__loop_of_face_step;
+ iter->data.loop_of_face.pdata = (BMFace *)data;
+ break;
+ case BM_LOOPS_OF_LOOP:
+ BLI_assert(data != NULL);
+ BLI_assert(((BMElem *)data)->head.htype == BM_LOOP);
+ iter->begin = (BMIter__begin_cb)bmiter__loop_of_loop_begin;
+ iter->step = (BMIter__step_cb)bmiter__loop_of_loop_step;
+ iter->data.loop_of_loop.ldata = (BMLoop *)data;
+ break;
+ case BM_LOOPS_OF_EDGE:
+ BLI_assert(data != NULL);
+ BLI_assert(((BMElem *)data)->head.htype == BM_EDGE);
+ iter->begin = (BMIter__begin_cb)bmiter__loop_of_edge_begin;
+ iter->step = (BMIter__step_cb)bmiter__loop_of_edge_step;
+ iter->data.loop_of_edge.edata = (BMEdge *)data;
+ break;
+ default:
+ /* should never happen */
+ BLI_assert(0);
+ return false;
+ break;
+ }
- iter->begin(iter);
+ iter->begin(iter);
- return true;
+ return true;
}
/**
@@ -164,15 +162,15 @@ BLI_INLINE bool BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *da
* upon its type and then calls BMeshIter_step()
* to return the first element of the iterator.
*/
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *data)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
+ void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *data)
{
- if (LIKELY(BM_iter_init(iter, bm, itype, data))) {
- return BM_iter_step(iter);
- }
- else {
- return NULL;
- }
+ if (LIKELY(BM_iter_init(iter, bm, itype, data))) {
+ return BM_iter_step(iter);
+ }
+ else {
+ return NULL;
+ }
}
/**
@@ -186,27 +184,30 @@ BLI_INLINE void *BM_iter_new(BMIter *iter, BMesh *bm, const char itype, void *da
#ifdef __BLI_TASK_H__
ATTR_NONNULL(1)
-BLI_INLINE void BM_iter_parallel(
- BMesh *bm, const char itype, TaskParallelMempoolFunc func, void *userdata, const bool use_threading)
+BLI_INLINE void BM_iter_parallel(BMesh *bm,
+ const char itype,
+ TaskParallelMempoolFunc func,
+ void *userdata,
+ const bool use_threading)
{
- /* inlining optimizes out this switch when called with the defined type */
- switch ((BMIterType)itype) {
- case BM_VERTS_OF_MESH:
- BLI_task_parallel_mempool(bm->vpool, userdata, func, use_threading);
- break;
- case BM_EDGES_OF_MESH:
- BLI_task_parallel_mempool(bm->epool, userdata, func, use_threading);
- break;
- case BM_FACES_OF_MESH:
- BLI_task_parallel_mempool(bm->fpool, userdata, func, use_threading);
- break;
- default:
- /* should never happen */
- BLI_assert(0);
- break;
- }
+ /* inlining optimizes out this switch when called with the defined type */
+ switch ((BMIterType)itype) {
+ case BM_VERTS_OF_MESH:
+ BLI_task_parallel_mempool(bm->vpool, userdata, func, use_threading);
+ break;
+ case BM_EDGES_OF_MESH:
+ BLI_task_parallel_mempool(bm->epool, userdata, func, use_threading);
+ break;
+ case BM_FACES_OF_MESH:
+ BLI_task_parallel_mempool(bm->fpool, userdata, func, use_threading);
+ break;
+ default:
+ /* should never happen */
+ BLI_assert(0);
+ break;
+ }
}
-#endif /* __BLI_TASK_H__ */
+#endif /* __BLI_TASK_H__ */
#endif /* __BMESH_ITERATORS_INLINE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 3b2e43b89ad..16a534b5e56 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -45,79 +45,78 @@
#include "BLI_strict_flags.h"
-
struct BMLogEntry {
- struct BMLogEntry *next, *prev;
-
- /* The following GHashes map from an element ID to one of the log
- * types above */
-
- /* Elements that were in the previous entry, but have been
- * deleted */
- GHash *deleted_verts;
- GHash *deleted_faces;
- /* Elements that were not in the previous entry, but are in the
- * result of this entry */
- GHash *added_verts;
- GHash *added_faces;
-
- /* Vertices whose coordinates, mask value, or hflag have changed */
- GHash *modified_verts;
- GHash *modified_faces;
-
- BLI_mempool *pool_verts;
- BLI_mempool *pool_faces;
-
- /* This is only needed for dropping BMLogEntries while still in
- * dynamic-topology mode, as that should release vert/face IDs
- * back to the BMLog but no BMLog pointer is available at that
- * time.
- *
- * This field is not guaranteed to be valid, any use of it should
- * check for NULL. */
- BMLog *log;
+ struct BMLogEntry *next, *prev;
+
+ /* The following GHashes map from an element ID to one of the log
+ * types above */
+
+ /* Elements that were in the previous entry, but have been
+ * deleted */
+ GHash *deleted_verts;
+ GHash *deleted_faces;
+ /* Elements that were not in the previous entry, but are in the
+ * result of this entry */
+ GHash *added_verts;
+ GHash *added_faces;
+
+ /* Vertices whose coordinates, mask value, or hflag have changed */
+ GHash *modified_verts;
+ GHash *modified_faces;
+
+ BLI_mempool *pool_verts;
+ BLI_mempool *pool_faces;
+
+ /* This is only needed for dropping BMLogEntries while still in
+ * dynamic-topology mode, as that should release vert/face IDs
+ * back to the BMLog but no BMLog pointer is available at that
+ * time.
+ *
+ * This field is not guaranteed to be valid, any use of it should
+ * check for NULL. */
+ BMLog *log;
};
struct BMLog {
- /* Tree of free IDs */
- struct RangeTreeUInt *unused_ids;
-
- /* Mapping from unique IDs to vertices and faces
- *
- * Each vertex and face in the log gets a unique uinteger
- * assigned. That ID is taken from the set managed by the
- * unused_ids range tree.
- *
- * The ID is needed because element pointers will change as they
- * are created and deleted.
- */
- GHash *id_to_elem;
- GHash *elem_to_id;
-
- /* All BMLogEntrys, ordered from earliest to most recent */
- ListBase entries;
-
- /* The current log entry from entries list
- *
- * If null, then the original mesh from before any of the log
- * entries is current (i.e. there is nothing left to undo.)
- *
- * If equal to the last entry in the entries list, then all log
- * entries have been applied (i.e. there is nothing left to redo.)
- */
- BMLogEntry *current_entry;
+ /* Tree of free IDs */
+ struct RangeTreeUInt *unused_ids;
+
+ /* Mapping from unique IDs to vertices and faces
+ *
+ * Each vertex and face in the log gets a unique uinteger
+ * assigned. That ID is taken from the set managed by the
+ * unused_ids range tree.
+ *
+ * The ID is needed because element pointers will change as they
+ * are created and deleted.
+ */
+ GHash *id_to_elem;
+ GHash *elem_to_id;
+
+ /* All BMLogEntrys, ordered from earliest to most recent */
+ ListBase entries;
+
+ /* The current log entry from entries list
+ *
+ * If null, then the original mesh from before any of the log
+ * entries is current (i.e. there is nothing left to undo.)
+ *
+ * If equal to the last entry in the entries list, then all log
+ * entries have been applied (i.e. there is nothing left to redo.)
+ */
+ BMLogEntry *current_entry;
};
typedef struct {
- float co[3];
- short no[3];
- char hflag;
- float mask;
+ float co[3];
+ short no[3];
+ char hflag;
+ float mask;
} BMLogVert;
typedef struct {
- uint v_ids[3];
- char hflag;
+ uint v_ids[3];
+ char hflag;
} BMLogFace;
/************************* Get/set element IDs ************************/
@@ -129,52 +128,51 @@ typedef struct {
/* Get the vertex's unique ID from the log */
static uint bm_log_vert_id_get(BMLog *log, BMVert *v)
{
- BLI_assert(BLI_ghash_haskey(log->elem_to_id, v));
- return POINTER_AS_UINT(BLI_ghash_lookup(log->elem_to_id, v));
+ BLI_assert(BLI_ghash_haskey(log->elem_to_id, v));
+ return POINTER_AS_UINT(BLI_ghash_lookup(log->elem_to_id, v));
}
/* Set the vertex's unique ID in the log */
static void bm_log_vert_id_set(BMLog *log, BMVert *v, uint id)
{
- void *vid = POINTER_FROM_UINT(id);
+ void *vid = POINTER_FROM_UINT(id);
- BLI_ghash_reinsert(log->id_to_elem, vid, v, NULL, NULL);
- BLI_ghash_reinsert(log->elem_to_id, v, vid, NULL, NULL);
+ BLI_ghash_reinsert(log->id_to_elem, vid, v, NULL, NULL);
+ BLI_ghash_reinsert(log->elem_to_id, v, vid, NULL, NULL);
}
/* Get a vertex from its unique ID */
static BMVert *bm_log_vert_from_id(BMLog *log, uint id)
{
- void *key = POINTER_FROM_UINT(id);
- BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
- return BLI_ghash_lookup(log->id_to_elem, key);
+ void *key = POINTER_FROM_UINT(id);
+ BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
+ return BLI_ghash_lookup(log->id_to_elem, key);
}
/* Get the face's unique ID from the log */
static uint bm_log_face_id_get(BMLog *log, BMFace *f)
{
- BLI_assert(BLI_ghash_haskey(log->elem_to_id, f));
- return POINTER_AS_UINT(BLI_ghash_lookup(log->elem_to_id, f));
+ BLI_assert(BLI_ghash_haskey(log->elem_to_id, f));
+ return POINTER_AS_UINT(BLI_ghash_lookup(log->elem_to_id, f));
}
/* Set the face's unique ID in the log */
static void bm_log_face_id_set(BMLog *log, BMFace *f, uint id)
{
- void *fid = POINTER_FROM_UINT(id);
+ void *fid = POINTER_FROM_UINT(id);
- BLI_ghash_reinsert(log->id_to_elem, fid, f, NULL, NULL);
- BLI_ghash_reinsert(log->elem_to_id, f, fid, NULL, NULL);
+ BLI_ghash_reinsert(log->id_to_elem, fid, f, NULL, NULL);
+ BLI_ghash_reinsert(log->elem_to_id, f, fid, NULL, NULL);
}
/* Get a face from its unique ID */
static BMFace *bm_log_face_from_id(BMLog *log, uint id)
{
- void *key = POINTER_FROM_UINT(id);
- BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
- return BLI_ghash_lookup(log->id_to_elem, key);
+ void *key = POINTER_FROM_UINT(id);
+ BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
+ return BLI_ghash_lookup(log->id_to_elem, key);
}
-
/************************ BMLogVert / BMLogFace ***********************/
/* Get a vertex's paint-mask value
@@ -182,12 +180,12 @@ static BMFace *bm_log_face_from_id(BMLog *log, uint id)
* Returns zero if no paint-mask layer is present */
static float vert_mask_get(BMVert *v, const int cd_vert_mask_offset)
{
- if (cd_vert_mask_offset != -1) {
- return BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
- }
- else {
- return 0.0f;
- }
+ if (cd_vert_mask_offset != -1) {
+ return BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset);
+ }
+ else {
+ return 0.0f;
+ }
}
/* Set a vertex's paint-mask value
@@ -195,208 +193,206 @@ static float vert_mask_get(BMVert *v, const int cd_vert_mask_offset)
* Has no effect is no paint-mask layer is present */
static void vert_mask_set(BMVert *v, const float new_mask, const int cd_vert_mask_offset)
{
- if (cd_vert_mask_offset != -1) {
- BM_ELEM_CD_SET_FLOAT(v, cd_vert_mask_offset, new_mask);
- }
+ if (cd_vert_mask_offset != -1) {
+ BM_ELEM_CD_SET_FLOAT(v, cd_vert_mask_offset, new_mask);
+ }
}
/* Update a BMLogVert with data from a BMVert */
static void bm_log_vert_bmvert_copy(BMLogVert *lv, BMVert *v, const int cd_vert_mask_offset)
{
- copy_v3_v3(lv->co, v->co);
- normal_float_to_short_v3(lv->no, v->no);
- lv->mask = vert_mask_get(v, cd_vert_mask_offset);
- lv->hflag = v->head.hflag;
+ copy_v3_v3(lv->co, v->co);
+ normal_float_to_short_v3(lv->no, v->no);
+ lv->mask = vert_mask_get(v, cd_vert_mask_offset);
+ lv->hflag = v->head.hflag;
}
/* Allocate and initialize a BMLogVert */
static BMLogVert *bm_log_vert_alloc(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
- BMLogEntry *entry = log->current_entry;
- BMLogVert *lv = BLI_mempool_alloc(entry->pool_verts);
+ BMLogEntry *entry = log->current_entry;
+ BMLogVert *lv = BLI_mempool_alloc(entry->pool_verts);
- bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
+ bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
- return lv;
+ return lv;
}
/* Allocate and initialize a BMLogFace */
static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f)
{
- BMLogEntry *entry = log->current_entry;
- BMLogFace *lf = BLI_mempool_alloc(entry->pool_faces);
- BMVert *v[3];
+ BMLogEntry *entry = log->current_entry;
+ BMLogFace *lf = BLI_mempool_alloc(entry->pool_faces);
+ BMVert *v[3];
- BLI_assert(f->len == 3);
+ BLI_assert(f->len == 3);
- // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
- BM_face_as_array_vert_tri(f, v);
+ // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3);
+ BM_face_as_array_vert_tri(f, v);
- lf->v_ids[0] = bm_log_vert_id_get(log, v[0]);
- lf->v_ids[1] = bm_log_vert_id_get(log, v[1]);
- lf->v_ids[2] = bm_log_vert_id_get(log, v[2]);
+ lf->v_ids[0] = bm_log_vert_id_get(log, v[0]);
+ lf->v_ids[1] = bm_log_vert_id_get(log, v[1]);
+ lf->v_ids[2] = bm_log_vert_id_get(log, v[2]);
- lf->hflag = f->head.hflag;
- return lf;
+ lf->hflag = f->head.hflag;
+ return lf;
}
-
/************************ Helpers for undo/redo ***********************/
static void bm_log_verts_unmake(BMesh *bm, BMLog *log, GHash *verts)
{
- const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
- GHashIterator gh_iter;
- GHASH_ITER (gh_iter, verts) {
- void *key = BLI_ghashIterator_getKey(&gh_iter);
- BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
- uint id = POINTER_AS_UINT(key);
- BMVert *v = bm_log_vert_from_id(log, id);
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, verts) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
+ uint id = POINTER_AS_UINT(key);
+ BMVert *v = bm_log_vert_from_id(log, id);
- /* Ensure the log has the final values of the vertex before
- * deleting it */
- bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
+ /* Ensure the log has the final values of the vertex before
+ * deleting it */
+ bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
- BM_vert_kill(bm, v);
- }
+ BM_vert_kill(bm, v);
+ }
}
static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces)
{
- GHashIterator gh_iter;
- GHASH_ITER (gh_iter, faces) {
- void *key = BLI_ghashIterator_getKey(&gh_iter);
- uint id = POINTER_AS_UINT(key);
- BMFace *f = bm_log_face_from_id(log, id);
- BMEdge *e_tri[3];
- BMLoop *l_iter;
- int i;
-
- l_iter = BM_FACE_FIRST_LOOP(f);
- for (i = 0; i < 3; i++, l_iter = l_iter->next) {
- e_tri[i] = l_iter->e;
- }
-
- /* Remove any unused edges */
- BM_face_kill(bm, f);
- for (i = 0; i < 3; i++) {
- if (BM_edge_is_wire(e_tri[i])) {
- BM_edge_kill(bm, e_tri[i]);
- }
- }
- }
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, faces) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ uint id = POINTER_AS_UINT(key);
+ BMFace *f = bm_log_face_from_id(log, id);
+ BMEdge *e_tri[3];
+ BMLoop *l_iter;
+ int i;
+
+ l_iter = BM_FACE_FIRST_LOOP(f);
+ for (i = 0; i < 3; i++, l_iter = l_iter->next) {
+ e_tri[i] = l_iter->e;
+ }
+
+ /* Remove any unused edges */
+ BM_face_kill(bm, f);
+ for (i = 0; i < 3; i++) {
+ if (BM_edge_is_wire(e_tri[i])) {
+ BM_edge_kill(bm, e_tri[i]);
+ }
+ }
+ }
}
static void bm_log_verts_restore(BMesh *bm, BMLog *log, GHash *verts)
{
- const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
-
- GHashIterator gh_iter;
- GHASH_ITER (gh_iter, verts) {
- void *key = BLI_ghashIterator_getKey(&gh_iter);
- BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
- BMVert *v = BM_vert_create(bm, lv->co, NULL, BM_CREATE_NOP);
- vert_mask_set(v, lv->mask, cd_vert_mask_offset);
- v->head.hflag = lv->hflag;
- normal_short_to_float_v3(v->no, lv->no);
- bm_log_vert_id_set(log, v, POINTER_AS_UINT(key));
- }
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, verts) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
+ BMVert *v = BM_vert_create(bm, lv->co, NULL, BM_CREATE_NOP);
+ vert_mask_set(v, lv->mask, cd_vert_mask_offset);
+ v->head.hflag = lv->hflag;
+ normal_short_to_float_v3(v->no, lv->no);
+ bm_log_vert_id_set(log, v, POINTER_AS_UINT(key));
+ }
}
static void bm_log_faces_restore(BMesh *bm, BMLog *log, GHash *faces)
{
- GHashIterator gh_iter;
- GHASH_ITER (gh_iter, faces) {
- void *key = BLI_ghashIterator_getKey(&gh_iter);
- BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
- BMVert *v[3] = {bm_log_vert_from_id(log, lf->v_ids[0]),
- bm_log_vert_from_id(log, lf->v_ids[1]),
- bm_log_vert_from_id(log, lf->v_ids[2])};
- BMFace *f;
-
- f = BM_face_create_verts(bm, v, 3, NULL, BM_CREATE_NOP, true);
- f->head.hflag = lf->hflag;
- bm_log_face_id_set(log, f, POINTER_AS_UINT(key));
- }
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, faces) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
+ BMVert *v[3] = {bm_log_vert_from_id(log, lf->v_ids[0]),
+ bm_log_vert_from_id(log, lf->v_ids[1]),
+ bm_log_vert_from_id(log, lf->v_ids[2])};
+ BMFace *f;
+
+ f = BM_face_create_verts(bm, v, 3, NULL, BM_CREATE_NOP, true);
+ f->head.hflag = lf->hflag;
+ bm_log_face_id_set(log, f, POINTER_AS_UINT(key));
+ }
}
static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts)
{
- const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
-
- GHashIterator gh_iter;
- GHASH_ITER (gh_iter, verts) {
- void *key = BLI_ghashIterator_getKey(&gh_iter);
- BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
- uint id = POINTER_AS_UINT(key);
- BMVert *v = bm_log_vert_from_id(log, id);
- float mask;
- short normal[3];
-
- swap_v3_v3(v->co, lv->co);
- copy_v3_v3_short(normal, lv->no);
- normal_float_to_short_v3(lv->no, v->no);
- normal_short_to_float_v3(v->no, normal);
- SWAP(char, v->head.hflag, lv->hflag);
- mask = lv->mask;
- lv->mask = vert_mask_get(v, cd_vert_mask_offset);
- vert_mask_set(v, mask, cd_vert_mask_offset);
- }
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, verts) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
+ uint id = POINTER_AS_UINT(key);
+ BMVert *v = bm_log_vert_from_id(log, id);
+ float mask;
+ short normal[3];
+
+ swap_v3_v3(v->co, lv->co);
+ copy_v3_v3_short(normal, lv->no);
+ normal_float_to_short_v3(lv->no, v->no);
+ normal_short_to_float_v3(v->no, normal);
+ SWAP(char, v->head.hflag, lv->hflag);
+ mask = lv->mask;
+ lv->mask = vert_mask_get(v, cd_vert_mask_offset);
+ vert_mask_set(v, mask, cd_vert_mask_offset);
+ }
}
static void bm_log_face_values_swap(BMLog *log, GHash *faces)
{
- GHashIterator gh_iter;
- GHASH_ITER (gh_iter, faces) {
- void *key = BLI_ghashIterator_getKey(&gh_iter);
- BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
- uint id = POINTER_AS_UINT(key);
- BMFace *f = bm_log_face_from_id(log, id);
-
- SWAP(char, f->head.hflag, lf->hflag);
- }
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, faces) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
+ uint id = POINTER_AS_UINT(key);
+ BMFace *f = bm_log_face_from_id(log, id);
+
+ SWAP(char, f->head.hflag, lf->hflag);
+ }
}
-
/**********************************************************************/
/* Assign unique IDs to all vertices and faces already in the BMesh */
static void bm_log_assign_ids(BMesh *bm, BMLog *log)
{
- BMIter iter;
- BMVert *v;
- BMFace *f;
-
- /* Generate vertex IDs */
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- uint id = range_tree_uint_take_any(log->unused_ids);
- bm_log_vert_id_set(log, v, id);
- }
-
- /* Generate face IDs */
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- uint id = range_tree_uint_take_any(log->unused_ids);
- bm_log_face_id_set(log, f, id);
- }
+ BMIter iter;
+ BMVert *v;
+ BMFace *f;
+
+ /* Generate vertex IDs */
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ uint id = range_tree_uint_take_any(log->unused_ids);
+ bm_log_vert_id_set(log, v, id);
+ }
+
+ /* Generate face IDs */
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ uint id = range_tree_uint_take_any(log->unused_ids);
+ bm_log_face_id_set(log, f, id);
+ }
}
/* Allocate an empty log entry */
static BMLogEntry *bm_log_entry_create(void)
{
- BMLogEntry *entry = MEM_callocN(sizeof(BMLogEntry), __func__);
+ BMLogEntry *entry = MEM_callocN(sizeof(BMLogEntry), __func__);
- entry->deleted_verts = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
- entry->deleted_faces = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
- entry->added_verts = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
- entry->added_faces = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
- entry->modified_verts = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
- entry->modified_faces = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
+ entry->deleted_verts = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
+ entry->deleted_faces = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
+ entry->added_verts = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
+ entry->added_faces = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
+ entry->modified_verts = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
+ entry->modified_faces = BLI_ghash_new(logkey_hash, logkey_cmp, __func__);
- entry->pool_verts = BLI_mempool_create(sizeof(BMLogVert), 0, 64, BLI_MEMPOOL_NOP);
- entry->pool_faces = BLI_mempool_create(sizeof(BMLogFace), 0, 64, BLI_MEMPOOL_NOP);
+ entry->pool_verts = BLI_mempool_create(sizeof(BMLogVert), 0, 64, BLI_MEMPOOL_NOP);
+ entry->pool_faces = BLI_mempool_create(sizeof(BMLogFace), 0, 64, BLI_MEMPOOL_NOP);
- return entry;
+ return entry;
}
/* Free the data in a log entry
@@ -404,34 +400,34 @@ static BMLogEntry *bm_log_entry_create(void)
* Note: does not free the log entry itself */
static void bm_log_entry_free(BMLogEntry *entry)
{
- BLI_ghash_free(entry->deleted_verts, NULL, NULL);
- BLI_ghash_free(entry->deleted_faces, NULL, NULL);
- BLI_ghash_free(entry->added_verts, NULL, NULL);
- BLI_ghash_free(entry->added_faces, NULL, NULL);
- BLI_ghash_free(entry->modified_verts, NULL, NULL);
- BLI_ghash_free(entry->modified_faces, NULL, NULL);
-
- BLI_mempool_destroy(entry->pool_verts);
- BLI_mempool_destroy(entry->pool_faces);
+ BLI_ghash_free(entry->deleted_verts, NULL, NULL);
+ BLI_ghash_free(entry->deleted_faces, NULL, NULL);
+ BLI_ghash_free(entry->added_verts, NULL, NULL);
+ BLI_ghash_free(entry->added_faces, NULL, NULL);
+ BLI_ghash_free(entry->modified_verts, NULL, NULL);
+ BLI_ghash_free(entry->modified_faces, NULL, NULL);
+
+ BLI_mempool_destroy(entry->pool_verts);
+ BLI_mempool_destroy(entry->pool_faces);
}
static void bm_log_id_ghash_retake(RangeTreeUInt *unused_ids, GHash *id_ghash)
{
- GHashIterator gh_iter;
+ GHashIterator gh_iter;
- GHASH_ITER (gh_iter, id_ghash) {
- void *key = BLI_ghashIterator_getKey(&gh_iter);
- uint id = POINTER_AS_UINT(key);
+ GHASH_ITER (gh_iter, id_ghash) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ uint id = POINTER_AS_UINT(key);
- range_tree_uint_retake(unused_ids, id);
- }
+ range_tree_uint_retake(unused_ids, id);
+ }
}
static int uint_compare(const void *a_v, const void *b_v)
{
- const uint *a = a_v;
- const uint *b = b_v;
- return (*a) < (*b);
+ const uint *a = a_v;
+ const uint *b = b_v;
+ return (*a) < (*b);
}
/* Remap IDs to contiguous indices
@@ -444,30 +440,30 @@ static int uint_compare(const void *a_v, const void *b_v)
*/
static GHash *bm_log_compress_ids_to_indices(uint *ids, uint totid)
{
- GHash *map = BLI_ghash_int_new_ex(__func__, totid);
- uint i;
+ GHash *map = BLI_ghash_int_new_ex(__func__, totid);
+ uint i;
- qsort(ids, totid, sizeof(*ids), uint_compare);
+ qsort(ids, totid, sizeof(*ids), uint_compare);
- for (i = 0; i < totid; i++) {
- void *key = POINTER_FROM_UINT(ids[i]);
- void *val = POINTER_FROM_UINT(i);
- BLI_ghash_insert(map, key, val);
- }
+ for (i = 0; i < totid; i++) {
+ void *key = POINTER_FROM_UINT(ids[i]);
+ void *val = POINTER_FROM_UINT(i);
+ BLI_ghash_insert(map, key, val);
+ }
- return map;
+ return map;
}
/* Release all ID keys in id_ghash */
static void bm_log_id_ghash_release(BMLog *log, GHash *id_ghash)
{
- GHashIterator gh_iter;
+ GHashIterator gh_iter;
- GHASH_ITER (gh_iter, id_ghash) {
- void *key = BLI_ghashIterator_getKey(&gh_iter);
- uint id = POINTER_AS_UINT(key);
- range_tree_uint_release(log->unused_ids, id);
- }
+ GHASH_ITER (gh_iter, id_ghash) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ uint id = POINTER_AS_UINT(key);
+ range_tree_uint_release(log->unused_ids, id);
+ }
}
/***************************** Public API *****************************/
@@ -475,42 +471,41 @@ static void bm_log_id_ghash_release(BMLog *log, GHash *id_ghash)
/* Allocate, initialize, and assign a new BMLog */
BMLog *BM_log_create(BMesh *bm)
{
- BMLog *log = MEM_callocN(sizeof(*log), __func__);
- const uint reserve_num = (uint)(bm->totvert + bm->totface);
+ BMLog *log = MEM_callocN(sizeof(*log), __func__);
+ const uint reserve_num = (uint)(bm->totvert + bm->totface);
- log->unused_ids = range_tree_uint_alloc(0, (unsigned)-1);
- log->id_to_elem = BLI_ghash_new_ex(logkey_hash, logkey_cmp, __func__, reserve_num);
- log->elem_to_id = BLI_ghash_ptr_new_ex(__func__, reserve_num);
+ log->unused_ids = range_tree_uint_alloc(0, (unsigned)-1);
+ log->id_to_elem = BLI_ghash_new_ex(logkey_hash, logkey_cmp, __func__, reserve_num);
+ log->elem_to_id = BLI_ghash_ptr_new_ex(__func__, reserve_num);
- /* Assign IDs to all existing vertices and faces */
- bm_log_assign_ids(bm, log);
+ /* Assign IDs to all existing vertices and faces */
+ bm_log_assign_ids(bm, log);
- return log;
+ return log;
}
void BM_log_cleanup_entry(BMLogEntry *entry)
{
- BMLog *log = entry->log;
-
- if (log) {
- /* Take all used IDs */
- bm_log_id_ghash_retake(log->unused_ids, entry->deleted_verts);
- bm_log_id_ghash_retake(log->unused_ids, entry->deleted_faces);
- bm_log_id_ghash_retake(log->unused_ids, entry->added_verts);
- bm_log_id_ghash_retake(log->unused_ids, entry->added_faces);
- bm_log_id_ghash_retake(log->unused_ids, entry->modified_verts);
- bm_log_id_ghash_retake(log->unused_ids, entry->modified_faces);
-
- /* delete entries to avoid releasing ids in node cleanup */
- BLI_ghash_clear(entry->deleted_verts, NULL, NULL);
- BLI_ghash_clear(entry->deleted_faces, NULL, NULL);
- BLI_ghash_clear(entry->added_verts, NULL, NULL);
- BLI_ghash_clear(entry->added_faces, NULL, NULL);
- BLI_ghash_clear(entry->modified_verts, NULL, NULL);
- }
+ BMLog *log = entry->log;
+
+ if (log) {
+ /* Take all used IDs */
+ bm_log_id_ghash_retake(log->unused_ids, entry->deleted_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->deleted_faces);
+ bm_log_id_ghash_retake(log->unused_ids, entry->added_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->added_faces);
+ bm_log_id_ghash_retake(log->unused_ids, entry->modified_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->modified_faces);
+
+ /* delete entries to avoid releasing ids in node cleanup */
+ BLI_ghash_clear(entry->deleted_verts, NULL, NULL);
+ BLI_ghash_clear(entry->deleted_faces, NULL, NULL);
+ BLI_ghash_clear(entry->added_verts, NULL, NULL);
+ BLI_ghash_clear(entry->added_faces, NULL, NULL);
+ BLI_ghash_clear(entry->modified_verts, NULL, NULL);
+ }
}
-
/* Allocate and initialize a new BMLog using existing BMLogEntries
*
* The 'entry' should be the last entry in the BMLog. Its prev pointer
@@ -521,127 +516,127 @@ void BM_log_cleanup_entry(BMLogEntry *entry)
*/
BMLog *BM_log_from_existing_entries_create(BMesh *bm, BMLogEntry *entry)
{
- BMLog *log = BM_log_create(bm);
-
- if (entry->prev) {
- log->current_entry = entry;
- }
- else {
- log->current_entry = NULL;
- }
-
- /* Let BMLog manage the entry list again */
- log->entries.first = log->entries.last = entry;
-
- {
- while (entry->prev) {
- entry = entry->prev;
- log->entries.first = entry;
- }
- entry = log->entries.last;
- while (entry->next) {
- entry = entry->next;
- log->entries.last = entry;
- }
- }
-
- for (entry = log->entries.first; entry; entry = entry->next) {
- entry->log = log;
-
- /* Take all used IDs */
- bm_log_id_ghash_retake(log->unused_ids, entry->deleted_verts);
- bm_log_id_ghash_retake(log->unused_ids, entry->deleted_faces);
- bm_log_id_ghash_retake(log->unused_ids, entry->added_verts);
- bm_log_id_ghash_retake(log->unused_ids, entry->added_faces);
- bm_log_id_ghash_retake(log->unused_ids, entry->modified_verts);
- bm_log_id_ghash_retake(log->unused_ids, entry->modified_faces);
- }
-
- return log;
+ BMLog *log = BM_log_create(bm);
+
+ if (entry->prev) {
+ log->current_entry = entry;
+ }
+ else {
+ log->current_entry = NULL;
+ }
+
+ /* Let BMLog manage the entry list again */
+ log->entries.first = log->entries.last = entry;
+
+ {
+ while (entry->prev) {
+ entry = entry->prev;
+ log->entries.first = entry;
+ }
+ entry = log->entries.last;
+ while (entry->next) {
+ entry = entry->next;
+ log->entries.last = entry;
+ }
+ }
+
+ for (entry = log->entries.first; entry; entry = entry->next) {
+ entry->log = log;
+
+ /* Take all used IDs */
+ bm_log_id_ghash_retake(log->unused_ids, entry->deleted_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->deleted_faces);
+ bm_log_id_ghash_retake(log->unused_ids, entry->added_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->added_faces);
+ bm_log_id_ghash_retake(log->unused_ids, entry->modified_verts);
+ bm_log_id_ghash_retake(log->unused_ids, entry->modified_faces);
+ }
+
+ return log;
}
/* Free all the data in a BMLog including the log itself */
void BM_log_free(BMLog *log)
{
- BMLogEntry *entry;
+ BMLogEntry *entry;
- if (log->unused_ids) {
- range_tree_uint_free(log->unused_ids);
- }
+ if (log->unused_ids) {
+ range_tree_uint_free(log->unused_ids);
+ }
- if (log->id_to_elem) {
- BLI_ghash_free(log->id_to_elem, NULL, NULL);
- }
+ if (log->id_to_elem) {
+ BLI_ghash_free(log->id_to_elem, NULL, NULL);
+ }
- if (log->elem_to_id) {
- BLI_ghash_free(log->elem_to_id, NULL, NULL);
- }
+ if (log->elem_to_id) {
+ BLI_ghash_free(log->elem_to_id, NULL, NULL);
+ }
- /* Clear the BMLog references within each entry, but do not free
- * the entries themselves */
- for (entry = log->entries.first; entry; entry = entry->next) {
- entry->log = NULL;
- }
+ /* Clear the BMLog references within each entry, but do not free
+ * the entries themselves */
+ for (entry = log->entries.first; entry; entry = entry->next) {
+ entry->log = NULL;
+ }
- MEM_freeN(log);
+ MEM_freeN(log);
}
/* Get the number of log entries */
int BM_log_length(const BMLog *log)
{
- return BLI_listbase_count(&log->entries);
+ return BLI_listbase_count(&log->entries);
}
/* Apply a consistent ordering to BMesh vertices */
void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
{
- uint *varr;
- uint *farr;
-
- GHash *id_to_idx;
-
- BMIter bm_iter;
- BMVert *v;
- BMFace *f;
-
- uint i;
-
- /* Put all vertex IDs into an array */
- varr = MEM_mallocN(sizeof(int) * (size_t)bm->totvert, __func__);
- BM_ITER_MESH_INDEX (v, &bm_iter, bm, BM_VERTS_OF_MESH, i) {
- varr[i] = bm_log_vert_id_get(log, v);
- }
-
- /* Put all face IDs into an array */
- farr = MEM_mallocN(sizeof(int) * (size_t)bm->totface, __func__);
- BM_ITER_MESH_INDEX (f, &bm_iter, bm, BM_FACES_OF_MESH, i) {
- farr[i] = bm_log_face_id_get(log, f);
- }
-
- /* Create BMVert index remap array */
- id_to_idx = bm_log_compress_ids_to_indices(varr, (uint)bm->totvert);
- BM_ITER_MESH_INDEX (v, &bm_iter, bm, BM_VERTS_OF_MESH, i) {
- const unsigned id = bm_log_vert_id_get(log, v);
- const void *key = POINTER_FROM_UINT(id);
- const void *val = BLI_ghash_lookup(id_to_idx, key);
- varr[i] = POINTER_AS_UINT(val);
- }
- BLI_ghash_free(id_to_idx, NULL, NULL);
-
- /* Create BMFace index remap array */
- id_to_idx = bm_log_compress_ids_to_indices(farr, (uint)bm->totface);
- BM_ITER_MESH_INDEX (f, &bm_iter, bm, BM_FACES_OF_MESH, i) {
- const unsigned id = bm_log_face_id_get(log, f);
- const void *key = POINTER_FROM_UINT(id);
- const void *val = BLI_ghash_lookup(id_to_idx, key);
- farr[i] = POINTER_AS_UINT(val);
- }
- BLI_ghash_free(id_to_idx, NULL, NULL);
-
- BM_mesh_remap(bm, varr, NULL, farr);
-
- MEM_freeN(varr);
- MEM_freeN(farr);
+ uint *varr;
+ uint *farr;
+
+ GHash *id_to_idx;
+
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f;
+
+ uint i;
+
+ /* Put all vertex IDs into an array */
+ varr = MEM_mallocN(sizeof(int) * (size_t)bm->totvert, __func__);
+ BM_ITER_MESH_INDEX (v, &bm_iter, bm, BM_VERTS_OF_MESH, i) {
+ varr[i] = bm_log_vert_id_get(log, v);
+ }
+
+ /* Put all face IDs into an array */
+ farr = MEM_mallocN(sizeof(int) * (size_t)bm->totface, __func__);
+ BM_ITER_MESH_INDEX (f, &bm_iter, bm, BM_FACES_OF_MESH, i) {
+ farr[i] = bm_log_face_id_get(log, f);
+ }
+
+ /* Create BMVert index remap array */
+ id_to_idx = bm_log_compress_ids_to_indices(varr, (uint)bm->totvert);
+ BM_ITER_MESH_INDEX (v, &bm_iter, bm, BM_VERTS_OF_MESH, i) {
+ const unsigned id = bm_log_vert_id_get(log, v);
+ const void *key = POINTER_FROM_UINT(id);
+ const void *val = BLI_ghash_lookup(id_to_idx, key);
+ varr[i] = POINTER_AS_UINT(val);
+ }
+ BLI_ghash_free(id_to_idx, NULL, NULL);
+
+ /* Create BMFace index remap array */
+ id_to_idx = bm_log_compress_ids_to_indices(farr, (uint)bm->totface);
+ BM_ITER_MESH_INDEX (f, &bm_iter, bm, BM_FACES_OF_MESH, i) {
+ const unsigned id = bm_log_face_id_get(log, f);
+ const void *key = POINTER_FROM_UINT(id);
+ const void *val = BLI_ghash_lookup(id_to_idx, key);
+ farr[i] = POINTER_AS_UINT(val);
+ }
+ BLI_ghash_free(id_to_idx, NULL, NULL);
+
+ BM_mesh_remap(bm, varr, NULL, farr);
+
+ MEM_freeN(varr);
+ MEM_freeN(farr);
}
/* Start a new log entry and update the log entry list
@@ -656,29 +651,29 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
*/
BMLogEntry *BM_log_entry_add(BMLog *log)
{
- /* WARNING: this is now handled by the UndoSystem: BKE_UNDOSYS_TYPE_SCULPT
- * freeing here causes unnecessary complications. */
- BMLogEntry *entry;
+ /* WARNING: this is now handled by the UndoSystem: BKE_UNDOSYS_TYPE_SCULPT
+ * freeing here causes unnecessary complications. */
+ BMLogEntry *entry;
#if 0
- /* Delete any entries after the current one */
- entry = log->current_entry;
- if (entry) {
- BMLogEntry *next;
- for (entry = entry->next; entry; entry = next) {
- next = entry->next;
- bm_log_entry_free(entry);
- BLI_freelinkN(&log->entries, entry);
- }
- }
+ /* Delete any entries after the current one */
+ entry = log->current_entry;
+ if (entry) {
+ BMLogEntry *next;
+ for (entry = entry->next; entry; entry = next) {
+ next = entry->next;
+ bm_log_entry_free(entry);
+ BLI_freelinkN(&log->entries, entry);
+ }
+ }
#endif
- /* Create and append the new entry */
- entry = bm_log_entry_create();
- BLI_addtail(&log->entries, entry);
- entry->log = log;
- log->current_entry = entry;
+ /* Create and append the new entry */
+ entry = bm_log_entry_create();
+ BLI_addtail(&log->entries, entry);
+ entry->log = log;
+ log->current_entry = entry;
- return entry;
+ return entry;
}
/* Remove an entry from the log
@@ -692,68 +687,68 @@ BMLogEntry *BM_log_entry_add(BMLog *log)
*/
void BM_log_entry_drop(BMLogEntry *entry)
{
- BMLog *log = entry->log;
-
- if (!log) {
- /* Unlink */
- BLI_assert(!(entry->prev && entry->next));
- if (entry->prev) {
- entry->prev->next = NULL;
- }
- else if (entry->next) {
- entry->next->prev = NULL;
- }
-
- bm_log_entry_free(entry);
- MEM_freeN(entry);
- return;
- }
-
- if (!entry->prev) {
- /* Release IDs of elements that are deleted by this
- * entry. Since the entry is at the beginning of the undo
- * stack, and it's being deleted, those elements can never be
- * restored. Their IDs can go back into the pool. */
-
- /* This would never happen usually since first entry of log is
- * usually dyntopo enable, which, when reverted will free the log
- * completely. However, it is possible have a stroke instead of
- * dyntopo enable as first entry if nodes have been cleaned up
- * after sculpting on a different object than A, B.
- *
- * The steps are:
- * A dyntopo enable - sculpt
- * B dyntopo enable - sculpt - undo (A objects operators get cleaned up)
- * A sculpt (now A's log has a sculpt operator as first entry)
- *
- * Causing a cleanup at this point will call the code below, however
- * this will invalidate the state of the log since the deleted vertices
- * have been reclaimed already on step 2 (see BM_log_cleanup_entry)
- *
- * Also, design wise, a first entry should not have any deleted vertices since it
- * should not have anything to delete them -from-
- */
- //bm_log_id_ghash_release(log, entry->deleted_faces);
- //bm_log_id_ghash_release(log, entry->deleted_verts);
- }
- else if (!entry->next) {
- /* Release IDs of elements that are added by this entry. Since
- * the entry is at the end of the undo stack, and it's being
- * deleted, those elements can never be restored. Their IDs
- * can go back into the pool. */
- bm_log_id_ghash_release(log, entry->added_faces);
- bm_log_id_ghash_release(log, entry->added_verts);
- }
- else {
- BLI_assert(!"Cannot drop BMLogEntry from middle");
- }
-
- if (log->current_entry == entry) {
- log->current_entry = entry->prev;
- }
-
- bm_log_entry_free(entry);
- BLI_freelinkN(&log->entries, entry);
+ BMLog *log = entry->log;
+
+ if (!log) {
+ /* Unlink */
+ BLI_assert(!(entry->prev && entry->next));
+ if (entry->prev) {
+ entry->prev->next = NULL;
+ }
+ else if (entry->next) {
+ entry->next->prev = NULL;
+ }
+
+ bm_log_entry_free(entry);
+ MEM_freeN(entry);
+ return;
+ }
+
+ if (!entry->prev) {
+ /* Release IDs of elements that are deleted by this
+ * entry. Since the entry is at the beginning of the undo
+ * stack, and it's being deleted, those elements can never be
+ * restored. Their IDs can go back into the pool. */
+
+ /* This would never happen usually since first entry of log is
+ * usually dyntopo enable, which, when reverted will free the log
+ * completely. However, it is possible have a stroke instead of
+ * dyntopo enable as first entry if nodes have been cleaned up
+ * after sculpting on a different object than A, B.
+ *
+ * The steps are:
+ * A dyntopo enable - sculpt
+ * B dyntopo enable - sculpt - undo (A objects operators get cleaned up)
+ * A sculpt (now A's log has a sculpt operator as first entry)
+ *
+ * Causing a cleanup at this point will call the code below, however
+ * this will invalidate the state of the log since the deleted vertices
+ * have been reclaimed already on step 2 (see BM_log_cleanup_entry)
+ *
+ * Also, design wise, a first entry should not have any deleted vertices since it
+ * should not have anything to delete them -from-
+ */
+ //bm_log_id_ghash_release(log, entry->deleted_faces);
+ //bm_log_id_ghash_release(log, entry->deleted_verts);
+ }
+ else if (!entry->next) {
+ /* Release IDs of elements that are added by this entry. Since
+ * the entry is at the end of the undo stack, and it's being
+ * deleted, those elements can never be restored. Their IDs
+ * can go back into the pool. */
+ bm_log_id_ghash_release(log, entry->added_faces);
+ bm_log_id_ghash_release(log, entry->added_verts);
+ }
+ else {
+ BLI_assert(!"Cannot drop BMLogEntry from middle");
+ }
+
+ if (log->current_entry == entry) {
+ log->current_entry = entry->prev;
+ }
+
+ bm_log_entry_free(entry);
+ BLI_freelinkN(&log->entries, entry);
}
/* Undo one BMLogEntry
@@ -761,23 +756,23 @@ void BM_log_entry_drop(BMLogEntry *entry)
* Has no effect if there's nothing left to undo */
void BM_log_undo(BMesh *bm, BMLog *log)
{
- BMLogEntry *entry = log->current_entry;
+ BMLogEntry *entry = log->current_entry;
- if (entry) {
- log->current_entry = entry->prev;
+ if (entry) {
+ log->current_entry = entry->prev;
- /* Delete added faces and verts */
- bm_log_faces_unmake(bm, log, entry->added_faces);
- bm_log_verts_unmake(bm, log, entry->added_verts);
+ /* Delete added faces and verts */
+ bm_log_faces_unmake(bm, log, entry->added_faces);
+ bm_log_verts_unmake(bm, log, entry->added_verts);
- /* Restore deleted verts and faces */
- bm_log_verts_restore(bm, log, entry->deleted_verts);
- bm_log_faces_restore(bm, log, entry->deleted_faces);
+ /* Restore deleted verts and faces */
+ bm_log_verts_restore(bm, log, entry->deleted_verts);
+ bm_log_faces_restore(bm, log, entry->deleted_faces);
- /* Restore vertex coordinates, mask, and hflag */
- bm_log_vert_values_swap(bm, log, entry->modified_verts);
- bm_log_face_values_swap(log, entry->modified_faces);
- }
+ /* Restore vertex coordinates, mask, and hflag */
+ bm_log_vert_values_swap(bm, log, entry->modified_verts);
+ bm_log_face_values_swap(log, entry->modified_faces);
+ }
}
/* Redo one BMLogEntry
@@ -785,36 +780,36 @@ void BM_log_undo(BMesh *bm, BMLog *log)
* Has no effect if there's nothing left to redo */
void BM_log_redo(BMesh *bm, BMLog *log)
{
- BMLogEntry *entry = log->current_entry;
-
- if (!entry) {
- /* Currently at the beginning of the undo stack, move to first entry */
- entry = log->entries.first;
- }
- else if (entry && entry->next) {
- /* Move to next undo entry */
- entry = entry->next;
- }
- else {
- /* Currently at the end of the undo stack, nothing left to redo */
- return;
- }
-
- log->current_entry = entry;
-
- if (entry) {
- /* Re-delete previously deleted faces and verts */
- bm_log_faces_unmake(bm, log, entry->deleted_faces);
- bm_log_verts_unmake(bm, log, entry->deleted_verts);
-
- /* Restore previously added verts and faces */
- bm_log_verts_restore(bm, log, entry->added_verts);
- bm_log_faces_restore(bm, log, entry->added_faces);
-
- /* Restore vertex coordinates, mask, and hflag */
- bm_log_vert_values_swap(bm, log, entry->modified_verts);
- bm_log_face_values_swap(log, entry->modified_faces);
- }
+ BMLogEntry *entry = log->current_entry;
+
+ if (!entry) {
+ /* Currently at the beginning of the undo stack, move to first entry */
+ entry = log->entries.first;
+ }
+ else if (entry && entry->next) {
+ /* Move to next undo entry */
+ entry = entry->next;
+ }
+ else {
+ /* Currently at the end of the undo stack, nothing left to redo */
+ return;
+ }
+
+ log->current_entry = entry;
+
+ if (entry) {
+ /* Re-delete previously deleted faces and verts */
+ bm_log_faces_unmake(bm, log, entry->deleted_faces);
+ bm_log_verts_unmake(bm, log, entry->deleted_verts);
+
+ /* Restore previously added verts and faces */
+ bm_log_verts_restore(bm, log, entry->added_verts);
+ bm_log_faces_restore(bm, log, entry->added_faces);
+
+ /* Restore vertex coordinates, mask, and hflag */
+ bm_log_vert_values_swap(bm, log, entry->modified_verts);
+ bm_log_face_values_swap(log, entry->modified_faces);
+ }
}
/* Log a vertex before it is modified
@@ -842,23 +837,22 @@ void BM_log_redo(BMesh *bm, BMLog *log)
*/
void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
- BMLogEntry *entry = log->current_entry;
- BMLogVert *lv;
- uint v_id = bm_log_vert_id_get(log, v);
- void *key = POINTER_FROM_UINT(v_id);
- void **val_p;
-
- /* Find or create the BMLogVert entry */
- if ((lv = BLI_ghash_lookup(entry->added_verts, key))) {
- bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
- }
- else if (!BLI_ghash_ensure_p(entry->modified_verts, key, &val_p)) {
- lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
- *val_p = lv;
- }
+ BMLogEntry *entry = log->current_entry;
+ BMLogVert *lv;
+ uint v_id = bm_log_vert_id_get(log, v);
+ void *key = POINTER_FROM_UINT(v_id);
+ void **val_p;
+
+ /* Find or create the BMLogVert entry */
+ if ((lv = BLI_ghash_lookup(entry->added_verts, key))) {
+ bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);
+ }
+ else if (!BLI_ghash_ensure_p(entry->modified_verts, key, &val_p)) {
+ lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
+ *val_p = lv;
+ }
}
-
/* Log a new vertex as added to the BMesh
*
* The new vertex gets a unique ID assigned. It is then added to a map
@@ -867,16 +861,15 @@ void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_o
*/
void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
- BMLogVert *lv;
- uint v_id = range_tree_uint_take_any(log->unused_ids);
- void *key = POINTER_FROM_UINT(v_id);
+ BMLogVert *lv;
+ uint v_id = range_tree_uint_take_any(log->unused_ids);
+ void *key = POINTER_FROM_UINT(v_id);
- bm_log_vert_id_set(log, v, v_id);
- lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
- BLI_ghash_insert(log->current_entry->added_verts, key, lv);
+ bm_log_vert_id_set(log, v, v_id);
+ lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
+ BLI_ghash_insert(log->current_entry->added_verts, key, lv);
}
-
/* Log a face before it is modified
*
* This is intended to handle only header flags and we always
@@ -884,12 +877,12 @@ void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
*/
void BM_log_face_modified(BMLog *log, BMFace *f)
{
- BMLogFace *lf;
- uint f_id = bm_log_face_id_get(log, f);
- void *key = POINTER_FROM_UINT(f_id);
+ BMLogFace *lf;
+ uint f_id = bm_log_face_id_get(log, f);
+ void *key = POINTER_FROM_UINT(f_id);
- lf = bm_log_face_alloc(log, f);
- BLI_ghash_insert(log->current_entry->modified_faces, key, lf);
+ lf = bm_log_face_alloc(log, f);
+ BLI_ghash_insert(log->current_entry->modified_faces, key, lf);
}
/* Log a new face as added to the BMesh
@@ -900,16 +893,16 @@ void BM_log_face_modified(BMLog *log, BMFace *f)
*/
void BM_log_face_added(BMLog *log, BMFace *f)
{
- BMLogFace *lf;
- uint f_id = range_tree_uint_take_any(log->unused_ids);
- void *key = POINTER_FROM_UINT(f_id);
+ BMLogFace *lf;
+ uint f_id = range_tree_uint_take_any(log->unused_ids);
+ void *key = POINTER_FROM_UINT(f_id);
- /* Only triangles are supported for now */
- BLI_assert(f->len == 3);
+ /* Only triangles are supported for now */
+ BLI_assert(f->len == 3);
- bm_log_face_id_set(log, f, f_id);
- lf = bm_log_face_alloc(log, f);
- BLI_ghash_insert(log->current_entry->added_faces, key, lf);
+ bm_log_face_id_set(log, f, f_id);
+ lf = bm_log_face_alloc(log, f);
+ BLI_ghash_insert(log->current_entry->added_faces, key, lf);
}
/* Log a vertex as removed from the BMesh
@@ -930,30 +923,30 @@ void BM_log_face_added(BMLog *log, BMFace *f)
*/
void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
- BMLogEntry *entry = log->current_entry;
- uint v_id = bm_log_vert_id_get(log, v);
- void *key = POINTER_FROM_UINT(v_id);
-
- /* if it has a key, it shouldn't be NULL */
- BLI_assert(!!BLI_ghash_lookup(entry->added_verts, key) ==
- !!BLI_ghash_haskey(entry->added_verts, key));
-
- if (BLI_ghash_remove(entry->added_verts, key, NULL, NULL)) {
- range_tree_uint_release(log->unused_ids, v_id);
- }
- else {
- BMLogVert *lv, *lv_mod;
-
- lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
- BLI_ghash_insert(entry->deleted_verts, key, lv);
-
- /* If the vertex was modified before deletion, ensure that the
- * original vertex values are stored */
- if ((lv_mod = BLI_ghash_lookup(entry->modified_verts, key))) {
- (*lv) = (*lv_mod);
- BLI_ghash_remove(entry->modified_verts, key, NULL, NULL);
- }
- }
+ BMLogEntry *entry = log->current_entry;
+ uint v_id = bm_log_vert_id_get(log, v);
+ void *key = POINTER_FROM_UINT(v_id);
+
+ /* if it has a key, it shouldn't be NULL */
+ BLI_assert(!!BLI_ghash_lookup(entry->added_verts, key) ==
+ !!BLI_ghash_haskey(entry->added_verts, key));
+
+ if (BLI_ghash_remove(entry->added_verts, key, NULL, NULL)) {
+ range_tree_uint_release(log->unused_ids, v_id);
+ }
+ else {
+ BMLogVert *lv, *lv_mod;
+
+ lv = bm_log_vert_alloc(log, v, cd_vert_mask_offset);
+ BLI_ghash_insert(entry->deleted_verts, key, lv);
+
+ /* If the vertex was modified before deletion, ensure that the
+ * original vertex values are stored */
+ if ((lv_mod = BLI_ghash_lookup(entry->modified_verts, key))) {
+ (*lv) = (*lv_mod);
+ BLI_ghash_remove(entry->modified_verts, key, NULL, NULL);
+ }
+ }
}
/* Log a face as removed from the BMesh
@@ -971,70 +964,70 @@ void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
*/
void BM_log_face_removed(BMLog *log, BMFace *f)
{
- BMLogEntry *entry = log->current_entry;
- uint f_id = bm_log_face_id_get(log, f);
- void *key = POINTER_FROM_UINT(f_id);
-
- /* if it has a key, it shouldn't be NULL */
- BLI_assert(!!BLI_ghash_lookup(entry->added_faces, key) ==
- !!BLI_ghash_haskey(entry->added_faces, key));
-
- if (BLI_ghash_remove(entry->added_faces, key, NULL, NULL)) {
- range_tree_uint_release(log->unused_ids, f_id);
- }
- else {
- BMLogFace *lf;
-
- lf = bm_log_face_alloc(log, f);
- BLI_ghash_insert(entry->deleted_faces, key, lf);
- }
+ BMLogEntry *entry = log->current_entry;
+ uint f_id = bm_log_face_id_get(log, f);
+ void *key = POINTER_FROM_UINT(f_id);
+
+ /* if it has a key, it shouldn't be NULL */
+ BLI_assert(!!BLI_ghash_lookup(entry->added_faces, key) ==
+ !!BLI_ghash_haskey(entry->added_faces, key));
+
+ if (BLI_ghash_remove(entry->added_faces, key, NULL, NULL)) {
+ range_tree_uint_release(log->unused_ids, f_id);
+ }
+ else {
+ BMLogFace *lf;
+
+ lf = bm_log_face_alloc(log, f);
+ BLI_ghash_insert(entry->deleted_faces, key, lf);
+ }
}
/* Log all vertices/faces in the BMesh as added */
void BM_log_all_added(BMesh *bm, BMLog *log)
{
- const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
- BMIter bm_iter;
- BMVert *v;
- BMFace *f;
-
- /* avoid unnecessary resizing on initialization */
- if (BLI_ghash_len(log->current_entry->added_verts) == 0) {
- BLI_ghash_reserve(log->current_entry->added_verts, (uint)bm->totvert);
- }
-
- if (BLI_ghash_len(log->current_entry->added_faces) == 0) {
- BLI_ghash_reserve(log->current_entry->added_faces, (uint)bm->totface);
- }
-
- /* Log all vertices as newly created */
- BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
- BM_log_vert_added(log, v, cd_vert_mask_offset);
- }
-
- /* Log all faces as newly created */
- BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
- BM_log_face_added(log, f);
- }
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f;
+
+ /* avoid unnecessary resizing on initialization */
+ if (BLI_ghash_len(log->current_entry->added_verts) == 0) {
+ BLI_ghash_reserve(log->current_entry->added_verts, (uint)bm->totvert);
+ }
+
+ if (BLI_ghash_len(log->current_entry->added_faces) == 0) {
+ BLI_ghash_reserve(log->current_entry->added_faces, (uint)bm->totface);
+ }
+
+ /* Log all vertices as newly created */
+ BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ BM_log_vert_added(log, v, cd_vert_mask_offset);
+ }
+
+ /* Log all faces as newly created */
+ BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
+ BM_log_face_added(log, f);
+ }
}
/* Log all vertices/faces in the BMesh as removed */
void BM_log_before_all_removed(BMesh *bm, BMLog *log)
{
- const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
- BMIter bm_iter;
- BMVert *v;
- BMFace *f;
-
- /* Log deletion of all faces */
- BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
- BM_log_face_removed(log, f);
- }
-
- /* Log deletion of all vertices */
- BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
- BM_log_vert_removed(log, v, cd_vert_mask_offset);
- }
+ const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
+ BMIter bm_iter;
+ BMVert *v;
+ BMFace *f;
+
+ /* Log deletion of all faces */
+ BM_ITER_MESH (f, &bm_iter, bm, BM_FACES_OF_MESH) {
+ BM_log_face_removed(log, f);
+ }
+
+ /* Log deletion of all vertices */
+ BM_ITER_MESH (v, &bm_iter, bm, BM_VERTS_OF_MESH) {
+ BM_log_vert_removed(log, v, cd_vert_mask_offset);
+ }
}
/* Get the logged coordinates of a vertex
@@ -1042,17 +1035,17 @@ void BM_log_before_all_removed(BMesh *bm, BMLog *log)
* Does not modify the log or the vertex */
const float *BM_log_original_vert_co(BMLog *log, BMVert *v)
{
- BMLogEntry *entry = log->current_entry;
- const BMLogVert *lv;
- unsigned v_id = bm_log_vert_id_get(log, v);
- void *key = POINTER_FROM_UINT(v_id);
+ BMLogEntry *entry = log->current_entry;
+ const BMLogVert *lv;
+ unsigned v_id = bm_log_vert_id_get(log, v);
+ void *key = POINTER_FROM_UINT(v_id);
- BLI_assert(entry);
+ BLI_assert(entry);
- BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
+ BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
- lv = BLI_ghash_lookup(entry->modified_verts, key);
- return lv->co;
+ lv = BLI_ghash_lookup(entry->modified_verts, key);
+ return lv->co;
}
/* Get the logged normal of a vertex
@@ -1060,17 +1053,17 @@ const float *BM_log_original_vert_co(BMLog *log, BMVert *v)
* Does not modify the log or the vertex */
const short *BM_log_original_vert_no(BMLog *log, BMVert *v)
{
- BMLogEntry *entry = log->current_entry;
- const BMLogVert *lv;
- unsigned v_id = bm_log_vert_id_get(log, v);
- void *key = POINTER_FROM_UINT(v_id);
+ BMLogEntry *entry = log->current_entry;
+ const BMLogVert *lv;
+ unsigned v_id = bm_log_vert_id_get(log, v);
+ void *key = POINTER_FROM_UINT(v_id);
- BLI_assert(entry);
+ BLI_assert(entry);
- BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
+ BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
- lv = BLI_ghash_lookup(entry->modified_verts, key);
- return lv->no;
+ lv = BLI_ghash_lookup(entry->modified_verts, key);
+ return lv->no;
}
/* Get the logged mask of a vertex
@@ -1078,35 +1071,33 @@ const short *BM_log_original_vert_no(BMLog *log, BMVert *v)
* Does not modify the log or the vertex */
float BM_log_original_mask(BMLog *log, BMVert *v)
{
- BMLogEntry *entry = log->current_entry;
- const BMLogVert *lv;
- unsigned v_id = bm_log_vert_id_get(log, v);
- void *key = POINTER_FROM_UINT(v_id);
+ BMLogEntry *entry = log->current_entry;
+ const BMLogVert *lv;
+ unsigned v_id = bm_log_vert_id_get(log, v);
+ void *key = POINTER_FROM_UINT(v_id);
- BLI_assert(entry);
+ BLI_assert(entry);
- BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
+ BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
- lv = BLI_ghash_lookup(entry->modified_verts, key);
- return lv->mask;
+ lv = BLI_ghash_lookup(entry->modified_verts, key);
+ return lv->mask;
}
-void BM_log_original_vert_data(
- BMLog *log, BMVert *v,
- const float **r_co, const short **r_no)
+void BM_log_original_vert_data(BMLog *log, BMVert *v, const float **r_co, const short **r_no)
{
- BMLogEntry *entry = log->current_entry;
- const BMLogVert *lv;
- unsigned v_id = bm_log_vert_id_get(log, v);
- void *key = POINTER_FROM_UINT(v_id);
+ BMLogEntry *entry = log->current_entry;
+ const BMLogVert *lv;
+ unsigned v_id = bm_log_vert_id_get(log, v);
+ void *key = POINTER_FROM_UINT(v_id);
- BLI_assert(entry);
+ BLI_assert(entry);
- BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
+ BLI_assert(BLI_ghash_haskey(entry->modified_verts, key));
- lv = BLI_ghash_lookup(entry->modified_verts, key);
- *r_co = lv->co;
- *r_no = lv->no;
+ lv = BLI_ghash_lookup(entry->modified_verts, key);
+ *r_co = lv->co;
+ *r_no = lv->no;
}
/************************ Debugging and Testing ***********************/
@@ -1114,13 +1105,13 @@ void BM_log_original_vert_data(
/* For internal use only (unit testing) */
BMLogEntry *BM_log_current_entry(BMLog *log)
{
- return log->current_entry;
+ return log->current_entry;
}
/* For internal use only (unit testing) */
RangeTreeUInt *BM_log_unused_ids(BMLog *log)
{
- return log->unused_ids;
+ return log->unused_ids;
}
#if 0
@@ -1129,16 +1120,16 @@ RangeTreeUInt *BM_log_unused_ids(BMLog *log)
* Keep around for debugging */
void bm_log_print(const BMLog *log, const char *description)
{
- const BMLogEntry *entry;
- const char *current = " <-- current";
- int i;
-
- printf("%s:\n", description);
- printf(" % 2d: [ initial ]%s\n", 0,
- (!log->current_entry) ? current : "");
- for (entry = log->entries.first, i = 1; entry; entry = entry->next, i++) {
- printf(" % 2d: [%p]%s\n", i, entry,
- (entry == log->current_entry) ? current : "");
- }
+ const BMLogEntry *entry;
+ const char *current = " <-- current";
+ int i;
+
+ printf("%s:\n", description);
+ printf(" % 2d: [ initial ]%s\n", 0,
+ (!log->current_entry) ? current : "");
+ for (entry = log->entries.first, i = 1; entry; entry = entry->next, i++) {
+ printf(" % 2d: [%p]%s\n", i, entry,
+ (entry == log->current_entry) ? current : "");
+ }
}
#endif
diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h
index 8643e07c622..25c58132802 100644
--- a/source/blender/bmesh/intern/bmesh_log.h
+++ b/source/blender/bmesh/intern/bmesh_log.h
@@ -93,9 +93,7 @@ const short *BM_log_original_vert_no(BMLog *log, BMVert *v);
float BM_log_original_mask(BMLog *log, BMVert *v);
/* Get the logged data of a vertex (avoid multiple lookups) */
-void BM_log_original_vert_data(
- BMLog *log, BMVert *v,
- const float **r_co, const short **r_no);
+void BM_log_original_vert_data(BMLog *log, BMVert *v, const float **r_co, const short **r_no);
/* For internal use only (unit testing) */
BMLogEntry *BM_log_current_entry(BMLog *log);
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 53d9b4b1b56..f8ec69b6fe9 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -42,30 +42,28 @@
static void recount_totsels(BMesh *bm)
{
- const char iter_types[3] = {BM_VERTS_OF_MESH,
- BM_EDGES_OF_MESH,
- BM_FACES_OF_MESH};
- int *tots[3];
- int i;
-
- /* recount (tot * sel) variables */
- bm->totvertsel = bm->totedgesel = bm->totfacesel = 0;
- tots[0] = &bm->totvertsel;
- tots[1] = &bm->totedgesel;
- tots[2] = &bm->totfacesel;
-
- for (i = 0; i < 3; i++) {
- BMIter iter;
- BMElem *ele;
- int count = 0;
-
- BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- count += 1;
- }
- }
- *tots[i] = count;
- }
+ const char iter_types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
+ int *tots[3];
+ int i;
+
+ /* recount (tot * sel) variables */
+ bm->totvertsel = bm->totedgesel = bm->totfacesel = 0;
+ tots[0] = &bm->totvertsel;
+ tots[1] = &bm->totedgesel;
+ tots[2] = &bm->totfacesel;
+
+ for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+ int count = 0;
+
+ BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
+ count += 1;
+ }
+ }
+ *tots[i] = count;
+ }
}
/** \name BMesh helper functions for selection & hide flushing.
@@ -73,88 +71,88 @@ static void recount_totsels(BMesh *bm)
static bool bm_vert_is_edge_select_any_other(const BMVert *v, const BMEdge *e_first)
{
- const BMEdge *e_iter = e_first;
-
- /* start by stepping over the current edge */
- while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first) {
- if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT)) {
- return true;
- }
- }
- return false;
+ const BMEdge *e_iter = e_first;
+
+ /* start by stepping over the current edge */
+ while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first) {
+ if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT)) {
+ return true;
+ }
+ }
+ return false;
}
#if 0
static bool bm_vert_is_edge_select_any(const BMVert *v)
{
- if (v->e) {
- const BMEdge *e_iter, *e_first;
- e_iter = e_first = v->e;
- do {
- if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT)) {
- return true;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- }
- return false;
+ if (v->e) {
+ const BMEdge *e_iter, *e_first;
+ e_iter = e_first = v->e;
+ do {
+ if (BM_elem_flag_test(e_iter, BM_ELEM_SELECT)) {
+ return true;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return false;
}
#endif
static bool bm_vert_is_edge_visible_any(const BMVert *v)
{
- if (v->e) {
- const BMEdge *e_iter, *e_first;
- e_iter = e_first = v->e;
- do {
- if (!BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN)) {
- return true;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- }
- return false;
+ if (v->e) {
+ const BMEdge *e_iter, *e_first;
+ e_iter = e_first = v->e;
+ do {
+ if (!BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN)) {
+ return true;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return false;
}
static bool bm_edge_is_face_select_any_other(BMLoop *l_first)
{
- const BMLoop *l_iter = l_first;
-
- /* start by stepping over the current face */
- while ((l_iter = l_iter->radial_next) != l_first) {
- if (BM_elem_flag_test(l_iter->f, BM_ELEM_SELECT)) {
- return true;
- }
- }
- return false;
+ const BMLoop *l_iter = l_first;
+
+ /* start by stepping over the current face */
+ while ((l_iter = l_iter->radial_next) != l_first) {
+ if (BM_elem_flag_test(l_iter->f, BM_ELEM_SELECT)) {
+ return true;
+ }
+ }
+ return false;
}
#if 0
static bool bm_edge_is_face_select_any(const BMEdge *e)
{
- if (e->l) {
- const BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- if (BM_elem_flag_test(l_iter->f, BM_ELEM_SELECT)) {
- return true;
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
- return false;
+ if (e->l) {
+ const BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ if (BM_elem_flag_test(l_iter->f, BM_ELEM_SELECT)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ return false;
}
#endif
static bool bm_edge_is_face_visible_any(const BMEdge *e)
{
- if (e->l) {
- const BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
- return true;
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
- return false;
+ if (e->l) {
+ const BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ return false;
}
/** \} */
@@ -169,67 +167,67 @@ static bool bm_edge_is_face_visible_any(const BMEdge *e)
*/
void BM_mesh_select_mode_clean_ex(BMesh *bm, const short selectmode)
{
- if (selectmode & SCE_SELECT_VERTEX) {
- /* pass */
- }
- else if (selectmode & SCE_SELECT_EDGE) {
- BMIter iter;
-
- if (bm->totvertsel) {
- BMVert *v;
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BM_elem_flag_disable(v, BM_ELEM_SELECT);
- }
- bm->totvertsel = 0;
- }
-
- if (bm->totedgesel) {
- BMEdge *e;
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- BM_vert_select_set(bm, e->v1, true);
- BM_vert_select_set(bm, e->v2, true);
- }
- }
- }
- }
- else if (selectmode & SCE_SELECT_FACE) {
- BMIter iter;
-
- if (bm->totvertsel) {
- BMVert *v;
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- BM_elem_flag_disable(v, BM_ELEM_SELECT);
- }
- bm->totvertsel = 0;
- }
-
- if (bm->totedgesel) {
- BMEdge *e;
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
- }
- bm->totedgesel = 0;
- }
-
- if (bm->totfacesel) {
- BMFace *f;
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- BMLoop *l_iter, *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BM_edge_select_set(bm, l_iter->e, true);
- } while ((l_iter = l_iter->next) != l_first);
- }
- }
- }
- }
+ if (selectmode & SCE_SELECT_VERTEX) {
+ /* pass */
+ }
+ else if (selectmode & SCE_SELECT_EDGE) {
+ BMIter iter;
+
+ if (bm->totvertsel) {
+ BMVert *v;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_elem_flag_disable(v, BM_ELEM_SELECT);
+ }
+ bm->totvertsel = 0;
+ }
+
+ if (bm->totedgesel) {
+ BMEdge *e;
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_vert_select_set(bm, e->v1, true);
+ BM_vert_select_set(bm, e->v2, true);
+ }
+ }
+ }
+ }
+ else if (selectmode & SCE_SELECT_FACE) {
+ BMIter iter;
+
+ if (bm->totvertsel) {
+ BMVert *v;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_elem_flag_disable(v, BM_ELEM_SELECT);
+ }
+ bm->totvertsel = 0;
+ }
+
+ if (bm->totedgesel) {
+ BMEdge *e;
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ }
+ bm->totedgesel = 0;
+ }
+
+ if (bm->totfacesel) {
+ BMFace *f;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_edge_select_set(bm, l_iter->e, true);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+ }
+ }
}
void BM_mesh_select_mode_clean(BMesh *bm)
{
- BM_mesh_select_mode_clean_ex(bm, bm->selectmode);
+ BM_mesh_select_mode_clean_ex(bm, bm->selectmode);
}
/**
@@ -241,74 +239,72 @@ void BM_mesh_select_mode_clean(BMesh *bm)
*/
void BM_mesh_select_mode_flush_ex(BMesh *bm, const short selectmode)
{
- BMEdge *e;
- BMLoop *l_iter;
- BMLoop *l_first;
- BMFace *f;
-
- BMIter eiter;
- BMIter fiter;
-
- if (selectmode & SCE_SELECT_VERTEX) {
- /* both loops only set edge/face flags and read off verts */
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
- BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
- !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
- {
- BM_elem_flag_enable(e, BM_ELEM_SELECT);
- }
- else {
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
- }
- }
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- bool ok = true;
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
- ok = false;
- break;
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- ok = false;
- }
-
- BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
- }
- }
- else if (selectmode & SCE_SELECT_EDGE) {
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- bool ok = true;
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (!BM_elem_flag_test(l_iter->e, BM_ELEM_SELECT)) {
- ok = false;
- break;
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- ok = false;
- }
-
- BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
- }
- }
-
- /* Remove any deselected elements from the BMEditSelection */
- BM_select_history_validate(bm);
-
- recount_totsels(bm);
+ BMEdge *e;
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ BMFace *f;
+
+ BMIter eiter;
+ BMIter fiter;
+
+ if (selectmode & SCE_SELECT_VERTEX) {
+ /* both loops only set edge/face flags and read off verts */
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
+ !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ }
+ else {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ }
+ }
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ bool ok = true;
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+ ok = false;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
+ ok = false;
+ }
+
+ BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
+ }
+ }
+ else if (selectmode & SCE_SELECT_EDGE) {
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ bool ok = true;
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (!BM_elem_flag_test(l_iter->e, BM_ELEM_SELECT)) {
+ ok = false;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
+ ok = false;
+ }
+
+ BM_elem_flag_set(f, BM_ELEM_SELECT, ok);
+ }
+ }
+
+ /* Remove any deselected elements from the BMEditSelection */
+ BM_select_history_validate(bm);
+
+ recount_totsels(bm);
}
void BM_mesh_select_mode_flush(BMesh *bm)
{
- BM_mesh_select_mode_flush_ex(bm, bm->selectmode);
+ BM_mesh_select_mode_flush_ex(bm, bm->selectmode);
}
/**
@@ -316,82 +312,78 @@ void BM_mesh_select_mode_flush(BMesh *bm)
*/
void BM_mesh_deselect_flush(BMesh *bm)
{
- BMIter eiter;
- BMEdge *e;
-
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- if (!BM_elem_flag_test(e->v1, BM_ELEM_SELECT) ||
- !BM_elem_flag_test(e->v2, BM_ELEM_SELECT))
- {
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
- }
- }
-
- if (e->l && !BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- BMLoop *l_iter;
- BMLoop *l_first;
-
- l_iter = l_first = e->l;
- do {
- BM_elem_flag_disable(l_iter->f, BM_ELEM_SELECT);
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
- }
- }
-
- /* Remove any deselected elements from the BMEditSelection */
- BM_select_history_validate(bm);
-
- recount_totsels(bm);
+ BMIter eiter;
+ BMEdge *e;
+
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ if (!BM_elem_flag_test(e->v1, BM_ELEM_SELECT) ||
+ !BM_elem_flag_test(e->v2, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ }
+ }
+
+ if (e->l && !BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ l_iter = l_first = e->l;
+ do {
+ BM_elem_flag_disable(l_iter->f, BM_ELEM_SELECT);
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ }
+ }
+
+ /* Remove any deselected elements from the BMEditSelection */
+ BM_select_history_validate(bm);
+
+ recount_totsels(bm);
}
-
/**
* mode independent flushing up/down
*/
void BM_mesh_select_flush(BMesh *bm)
{
- BMEdge *e;
- BMLoop *l_iter;
- BMLoop *l_first;
- BMFace *f;
-
- BMIter eiter;
- BMIter fiter;
-
- bool ok;
-
- BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) &&
- BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
- !BM_elem_flag_test(e, BM_ELEM_HIDDEN))
- {
- BM_elem_flag_enable(e, BM_ELEM_SELECT);
- }
- }
- BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
- ok = true;
- if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
- ok = false;
- break;
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- ok = false;
- }
-
- if (ok) {
- BM_elem_flag_enable(f, BM_ELEM_SELECT);
- }
- }
-
- recount_totsels(bm);
+ BMEdge *e;
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ BMFace *f;
+
+ BMIter eiter;
+ BMIter fiter;
+
+ bool ok;
+
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e->v1, BM_ELEM_SELECT) && BM_elem_flag_test(e->v2, BM_ELEM_SELECT) &&
+ !BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ }
+ }
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ ok = true;
+ if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (!BM_elem_flag_test(l_iter->v, BM_ELEM_SELECT)) {
+ ok = false;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
+ ok = false;
+ }
+
+ if (ok) {
+ BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ }
+ }
+
+ recount_totsels(bm);
}
/**
@@ -402,24 +394,24 @@ void BM_mesh_select_flush(BMesh *bm)
*/
void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select)
{
- BLI_assert(v->head.htype == BM_VERT);
-
- if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- return;
- }
-
- if (select) {
- if (!BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- BM_elem_flag_enable(v, BM_ELEM_SELECT);
- bm->totvertsel += 1;
- }
- }
- else {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- bm->totvertsel -= 1;
- BM_elem_flag_disable(v, BM_ELEM_SELECT);
- }
- }
+ BLI_assert(v->head.htype == BM_VERT);
+
+ if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+ return;
+ }
+
+ if (select) {
+ if (!BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(v, BM_ELEM_SELECT);
+ bm->totvertsel += 1;
+ }
+ }
+ else {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ bm->totvertsel -= 1;
+ BM_elem_flag_disable(v, BM_ELEM_SELECT);
+ }
+ }
}
/**
@@ -429,43 +421,42 @@ void BM_vert_select_set(BMesh *bm, BMVert *v, const bool select)
*/
void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
{
- BLI_assert(e->head.htype == BM_EDGE);
-
- if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- return;
- }
-
- if (select) {
- if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- BM_elem_flag_enable(e, BM_ELEM_SELECT);
- bm->totedgesel += 1;
- }
- BM_vert_select_set(bm, e->v1, true);
- BM_vert_select_set(bm, e->v2, true);
- }
- else {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
- bm->totedgesel -= 1;
- }
-
- if ((bm->selectmode & SCE_SELECT_VERTEX) == 0) {
- int i;
-
- /* check if the vert is used by a selected edge */
- for (i = 0; i < 2; i++) {
- BMVert *v = *((&e->v1) + i);
- if (bm_vert_is_edge_select_any_other(v, e) == false) {
- BM_vert_select_set(bm, v, false);
- }
- }
- }
- else {
- BM_vert_select_set(bm, e->v1, false);
- BM_vert_select_set(bm, e->v2, false);
- }
-
- }
+ BLI_assert(e->head.htype == BM_EDGE);
+
+ if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ return;
+ }
+
+ if (select) {
+ if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ bm->totedgesel += 1;
+ }
+ BM_vert_select_set(bm, e->v1, true);
+ BM_vert_select_set(bm, e->v2, true);
+ }
+ else {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ bm->totedgesel -= 1;
+ }
+
+ if ((bm->selectmode & SCE_SELECT_VERTEX) == 0) {
+ int i;
+
+ /* check if the vert is used by a selected edge */
+ for (i = 0; i < 2; i++) {
+ BMVert *v = *((&e->v1) + i);
+ if (bm_vert_is_edge_select_any_other(v, e) == false) {
+ BM_vert_select_set(bm, v, false);
+ }
+ }
+ }
+ else {
+ BM_vert_select_set(bm, e->v1, false);
+ BM_vert_select_set(bm, e->v2, false);
+ }
+ }
}
/**
@@ -476,77 +467,77 @@ void BM_edge_select_set(BMesh *bm, BMEdge *e, const bool select)
*/
void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
{
- BMLoop *l_iter;
- BMLoop *l_first;
-
- BLI_assert(f->head.htype == BM_FACE);
-
- if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- return;
- }
-
- if (select) {
- if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- BM_elem_flag_enable(f, BM_ELEM_SELECT);
- bm->totfacesel += 1;
- }
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BM_vert_select_set(bm, l_iter->v, true);
- BM_edge_select_set(bm, l_iter->e, true);
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
-
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- BM_elem_flag_disable(f, BM_ELEM_SELECT);
- bm->totfacesel -= 1;
- }
- /**
- * \note This allows a temporarily invalid state - where for eg
- * an edge bay be de-selected, but an adjacent face remains selected.
- *
- * Rely on #BM_mesh_select_mode_flush to correct these cases.
- *
- * \note flushing based on mode, see T46494
- */
- if (bm->selectmode & SCE_SELECT_VERTEX) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BM_vert_select_set(bm, l_iter->v, false);
- BM_edge_select_set_noflush(bm, l_iter->e, false);
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- /**
- * \note use #BM_edge_select_set_noflush,
- * vertex flushing is handled last.
- */
- if (bm->selectmode & SCE_SELECT_EDGE) {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BM_edge_select_set_noflush(bm, l_iter->e, false);
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (bm_edge_is_face_select_any_other(l_iter) == false) {
- BM_edge_select_set_noflush(bm, l_iter->e, false);
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
-
- /* flush down to verts */
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (bm_vert_is_edge_select_any_other(l_iter->v, l_iter->e) == false) {
- BM_vert_select_set(bm, l_iter->v, false);
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
- }
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ BLI_assert(f->head.htype == BM_FACE);
+
+ if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ return;
+ }
+
+ if (select) {
+ if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ bm->totfacesel += 1;
+ }
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_vert_select_set(bm, l_iter->v, true);
+ BM_edge_select_set(bm, l_iter->e, true);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
+
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ bm->totfacesel -= 1;
+ }
+ /**
+ * \note This allows a temporarily invalid state - where for eg
+ * an edge bay be de-selected, but an adjacent face remains selected.
+ *
+ * Rely on #BM_mesh_select_mode_flush to correct these cases.
+ *
+ * \note flushing based on mode, see T46494
+ */
+ if (bm->selectmode & SCE_SELECT_VERTEX) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_vert_select_set(bm, l_iter->v, false);
+ BM_edge_select_set_noflush(bm, l_iter->e, false);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
+ /**
+ * \note use #BM_edge_select_set_noflush,
+ * vertex flushing is handled last.
+ */
+ if (bm->selectmode & SCE_SELECT_EDGE) {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_edge_select_set_noflush(bm, l_iter->e, false);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (bm_edge_is_face_select_any_other(l_iter) == false) {
+ BM_edge_select_set_noflush(bm, l_iter->e, false);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ /* flush down to verts */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (bm_vert_is_edge_select_any_other(l_iter->v, l_iter->e) == false) {
+ BM_vert_select_set(bm, l_iter->v, false);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
}
/** \name Non flushing versions element selection.
@@ -554,46 +545,46 @@ void BM_face_select_set(BMesh *bm, BMFace *f, const bool select)
void BM_edge_select_set_noflush(BMesh *bm, BMEdge *e, const bool select)
{
- BLI_assert(e->head.htype == BM_EDGE);
-
- if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- return;
- }
-
- if (select) {
- if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- BM_elem_flag_enable(e, BM_ELEM_SELECT);
- bm->totedgesel += 1;
- }
- }
- else {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- BM_elem_flag_disable(e, BM_ELEM_SELECT);
- bm->totedgesel -= 1;
- }
- }
+ BLI_assert(e->head.htype == BM_EDGE);
+
+ if (BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ return;
+ }
+
+ if (select) {
+ if (!BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(e, BM_ELEM_SELECT);
+ bm->totedgesel += 1;
+ }
+ }
+ else {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(e, BM_ELEM_SELECT);
+ bm->totedgesel -= 1;
+ }
+ }
}
void BM_face_select_set_noflush(BMesh *bm, BMFace *f, const bool select)
{
- BLI_assert(f->head.htype == BM_FACE);
-
- if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- return;
- }
-
- if (select) {
- if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- BM_elem_flag_enable(f, BM_ELEM_SELECT);
- bm->totfacesel += 1;
- }
- }
- else {
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- BM_elem_flag_disable(f, BM_ELEM_SELECT);
- bm->totfacesel -= 1;
- }
- }
+ BLI_assert(f->head.htype == BM_FACE);
+
+ if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ return;
+ }
+
+ if (select) {
+ if (!BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_elem_flag_enable(f, BM_ELEM_SELECT);
+ bm->totfacesel += 1;
+ }
+ }
+ else {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_elem_flag_disable(f, BM_ELEM_SELECT);
+ bm->totfacesel -= 1;
+ }
+ }
}
/** \} */
@@ -606,109 +597,117 @@ void BM_face_select_set_noflush(BMesh *bm, BMFace *f, const bool select)
*/
void BM_mesh_select_mode_set(BMesh *bm, int selectmode)
{
- BMIter iter;
- BMElem *ele;
+ BMIter iter;
+ BMElem *ele;
- bm->selectmode = selectmode;
+ bm->selectmode = selectmode;
- if (bm->selectmode & SCE_SELECT_VERTEX) {
- /* disabled because selection flushing handles these */
+ if (bm->selectmode & SCE_SELECT_VERTEX) {
+ /* disabled because selection flushing handles these */
#if 0
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- BM_elem_flag_disable(ele, BM_ELEM_SELECT);
- }
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- BM_elem_flag_disable(ele, BM_ELEM_SELECT);
- }
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_elem_flag_disable(ele, BM_ELEM_SELECT);
+ }
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_disable(ele, BM_ELEM_SELECT);
+ }
#endif
- BM_mesh_select_mode_flush(bm);
- }
- else if (bm->selectmode & SCE_SELECT_EDGE) {
- /* disabled because selection flushing handles these */
+ BM_mesh_select_mode_flush(bm);
+ }
+ else if (bm->selectmode & SCE_SELECT_EDGE) {
+ /* disabled because selection flushing handles these */
#if 0
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- BM_elem_flag_disable(ele, BM_ELEM_SELECT);
- }
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_elem_flag_disable(ele, BM_ELEM_SELECT);
+ }
#endif
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- BM_edge_select_set(bm, (BMEdge *)ele, true);
- }
- }
- BM_mesh_select_mode_flush(bm);
- }
- else if (bm->selectmode & SCE_SELECT_FACE) {
- /* disabled because selection flushing handles these */
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
+ BM_edge_select_set(bm, (BMEdge *)ele, true);
+ }
+ }
+ BM_mesh_select_mode_flush(bm);
+ }
+ else if (bm->selectmode & SCE_SELECT_FACE) {
+ /* disabled because selection flushing handles these */
#if 0
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- BM_elem_flag_disable(ele, BM_ELEM_SELECT);
- }
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_elem_flag_disable(ele, BM_ELEM_SELECT);
+ }
#endif
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
- BM_face_select_set(bm, (BMFace *)ele, true);
- }
- }
- BM_mesh_select_mode_flush(bm);
- }
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(ele, BM_ELEM_SELECT)) {
+ BM_face_select_set(bm, (BMFace *)ele, true);
+ }
+ }
+ BM_mesh_select_mode_flush(bm);
+ }
}
/**
* counts number of elements with flag enabled/disabled
*/
-static int bm_mesh_flag_count(
- BMesh *bm, const char htype, const char hflag,
- const bool respecthide, const bool test_for_enabled)
+static int bm_mesh_flag_count(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide,
+ const bool test_for_enabled)
{
- BMElem *ele;
- BMIter iter;
- int tot = 0;
-
- BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
-
- if (htype & BM_VERT) {
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) {
- continue;
- }
- if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) {
- tot++;
- }
- }
- }
- if (htype & BM_EDGE) {
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) {
- continue;
- }
- if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) {
- tot++;
- }
- }
- }
- if (htype & BM_FACE) {
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) {
- continue;
- }
- if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) {
- tot++;
- }
- }
- }
-
- return tot;
+ BMElem *ele;
+ BMIter iter;
+ int tot = 0;
+
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
+ if (htype & BM_VERT) {
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) {
+ continue;
+ }
+ if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) {
+ tot++;
+ }
+ }
+ }
+ if (htype & BM_EDGE) {
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) {
+ continue;
+ }
+ if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) {
+ tot++;
+ }
+ }
+ }
+ if (htype & BM_FACE) {
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) {
+ continue;
+ }
+ if (BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) {
+ tot++;
+ }
+ }
+ }
+
+ return tot;
}
-int BM_mesh_elem_hflag_count_enabled(BMesh *bm, const char htype, const char hflag, const bool respecthide)
+int BM_mesh_elem_hflag_count_enabled(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide)
{
- return bm_mesh_flag_count(bm, htype, hflag, respecthide, true);
+ return bm_mesh_flag_count(bm, htype, hflag, respecthide, true);
}
-int BM_mesh_elem_hflag_count_disabled(BMesh *bm, const char htype, const char hflag, const bool respecthide)
+int BM_mesh_elem_hflag_count_disabled(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide)
{
- return bm_mesh_flag_count(bm, htype, hflag, respecthide, false);
+ return bm_mesh_flag_count(bm, htype, hflag, respecthide, false);
}
/**
@@ -717,105 +716,105 @@ int BM_mesh_elem_hflag_count_disabled(BMesh *bm, const char htype, const char hf
*/
void BM_elem_select_set(BMesh *bm, BMElem *ele, const bool select)
{
- switch (ele->head.htype) {
- case BM_VERT:
- BM_vert_select_set(bm, (BMVert *)ele, select);
- break;
- case BM_EDGE:
- BM_edge_select_set(bm, (BMEdge *)ele, select);
- break;
- case BM_FACE:
- BM_face_select_set(bm, (BMFace *)ele, select);
- break;
- default:
- BLI_assert(0);
- break;
- }
+ switch (ele->head.htype) {
+ case BM_VERT:
+ BM_vert_select_set(bm, (BMVert *)ele, select);
+ break;
+ case BM_EDGE:
+ BM_edge_select_set(bm, (BMEdge *)ele, select);
+ break;
+ case BM_FACE:
+ BM_face_select_set(bm, (BMFace *)ele, select);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
}
/* this replaces the active flag used in uv/face mode */
void BM_mesh_active_face_set(BMesh *bm, BMFace *efa)
{
- bm->act_face = efa;
+ bm->act_face = efa;
}
BMFace *BM_mesh_active_face_get(BMesh *bm, const bool is_sloppy, const bool is_selected)
{
- if (bm->act_face && (!is_selected || BM_elem_flag_test(bm->act_face, BM_ELEM_SELECT))) {
- return bm->act_face;
- }
- else if (is_sloppy) {
- BMIter iter;
- BMFace *f = NULL;
- BMEditSelection *ese;
-
- /* Find the latest non-hidden face from the BMEditSelection */
- ese = bm->selected.last;
- for ( ; ese; ese = ese->prev) {
- if (ese->htype == BM_FACE) {
- f = (BMFace *)ese->ele;
-
- if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- f = NULL;
- }
- else if (is_selected && !BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- f = NULL;
- }
- else {
- break;
- }
- }
- }
- /* Last attempt: try to find any selected face */
- if (f == NULL) {
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- break;
- }
- }
- }
- return f; /* can still be null */
- }
- return NULL;
+ if (bm->act_face && (!is_selected || BM_elem_flag_test(bm->act_face, BM_ELEM_SELECT))) {
+ return bm->act_face;
+ }
+ else if (is_sloppy) {
+ BMIter iter;
+ BMFace *f = NULL;
+ BMEditSelection *ese;
+
+ /* Find the latest non-hidden face from the BMEditSelection */
+ ese = bm->selected.last;
+ for (; ese; ese = ese->prev) {
+ if (ese->htype == BM_FACE) {
+ f = (BMFace *)ese->ele;
+
+ if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ f = NULL;
+ }
+ else if (is_selected && !BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ f = NULL;
+ }
+ else {
+ break;
+ }
+ }
+ }
+ /* Last attempt: try to find any selected face */
+ if (f == NULL) {
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ break;
+ }
+ }
+ }
+ return f; /* can still be null */
+ }
+ return NULL;
}
BMEdge *BM_mesh_active_edge_get(BMesh *bm)
{
- if (bm->selected.last) {
- BMEditSelection *ese = bm->selected.last;
+ if (bm->selected.last) {
+ BMEditSelection *ese = bm->selected.last;
- if (ese && ese->htype == BM_EDGE) {
- return (BMEdge *)ese->ele;
- }
- }
+ if (ese && ese->htype == BM_EDGE) {
+ return (BMEdge *)ese->ele;
+ }
+ }
- return NULL;
+ return NULL;
}
BMVert *BM_mesh_active_vert_get(BMesh *bm)
{
- if (bm->selected.last) {
- BMEditSelection *ese = bm->selected.last;
+ if (bm->selected.last) {
+ BMEditSelection *ese = bm->selected.last;
- if (ese && ese->htype == BM_VERT) {
- return (BMVert *)ese->ele;
- }
- }
+ if (ese && ese->htype == BM_VERT) {
+ return (BMVert *)ese->ele;
+ }
+ }
- return NULL;
+ return NULL;
}
BMElem *BM_mesh_active_elem_get(BMesh *bm)
{
- if (bm->selected.last) {
- BMEditSelection *ese = bm->selected.last;
+ if (bm->selected.last) {
+ BMEditSelection *ese = bm->selected.last;
- if (ese) {
- return ese->ele;
- }
- }
+ if (ese) {
+ return ese->ele;
+ }
+ }
- return NULL;
+ return NULL;
}
/**
@@ -829,47 +828,46 @@ BMElem *BM_mesh_active_elem_get(BMesh *bm)
*/
void BM_editselection_center(BMEditSelection *ese, float r_center[3])
{
- if (ese->htype == BM_VERT) {
- BMVert *eve = (BMVert *)ese->ele;
- copy_v3_v3(r_center, eve->co);
- }
- else if (ese->htype == BM_EDGE) {
- BMEdge *eed = (BMEdge *)ese->ele;
- mid_v3_v3v3(r_center, eed->v1->co, eed->v2->co);
- }
- else if (ese->htype == BM_FACE) {
- BMFace *efa = (BMFace *)ese->ele;
- BM_face_calc_center_median(efa, r_center);
- }
+ if (ese->htype == BM_VERT) {
+ BMVert *eve = (BMVert *)ese->ele;
+ copy_v3_v3(r_center, eve->co);
+ }
+ else if (ese->htype == BM_EDGE) {
+ BMEdge *eed = (BMEdge *)ese->ele;
+ mid_v3_v3v3(r_center, eed->v1->co, eed->v2->co);
+ }
+ else if (ese->htype == BM_FACE) {
+ BMFace *efa = (BMFace *)ese->ele;
+ BM_face_calc_center_median(efa, r_center);
+ }
}
void BM_editselection_normal(BMEditSelection *ese, float r_normal[3])
{
- if (ese->htype == BM_VERT) {
- BMVert *eve = (BMVert *)ese->ele;
- copy_v3_v3(r_normal, eve->no);
- }
- else if (ese->htype == BM_EDGE) {
- BMEdge *eed = (BMEdge *)ese->ele;
- float plane[3]; /* need a plane to correct the normal */
- float vec[3]; /* temp vec storage */
-
- add_v3_v3v3(r_normal, eed->v1->no, eed->v2->no);
- sub_v3_v3v3(plane, eed->v2->co, eed->v1->co);
-
- /* the 2 vertex normals will be close but not at rightangles to the edge
- * for rotate about edge we want them to be at right angles, so we need to
- * do some extra calculation to correct the vert normals,
- * we need the plane for this */
- cross_v3_v3v3(vec, r_normal, plane);
- cross_v3_v3v3(r_normal, plane, vec);
- normalize_v3(r_normal);
-
- }
- else if (ese->htype == BM_FACE) {
- BMFace *efa = (BMFace *)ese->ele;
- copy_v3_v3(r_normal, efa->no);
- }
+ if (ese->htype == BM_VERT) {
+ BMVert *eve = (BMVert *)ese->ele;
+ copy_v3_v3(r_normal, eve->no);
+ }
+ else if (ese->htype == BM_EDGE) {
+ BMEdge *eed = (BMEdge *)ese->ele;
+ float plane[3]; /* need a plane to correct the normal */
+ float vec[3]; /* temp vec storage */
+
+ add_v3_v3v3(r_normal, eed->v1->no, eed->v2->no);
+ sub_v3_v3v3(plane, eed->v2->co, eed->v1->co);
+
+ /* the 2 vertex normals will be close but not at rightangles to the edge
+ * for rotate about edge we want them to be at right angles, so we need to
+ * do some extra calculation to correct the vert normals,
+ * we need the plane for this */
+ cross_v3_v3v3(vec, r_normal, plane);
+ cross_v3_v3v3(r_normal, plane, vec);
+ normalize_v3(r_normal);
+ }
+ else if (ese->htype == BM_FACE) {
+ BMFace *efa = (BMFace *)ese->ele;
+ copy_v3_v3(r_normal, efa->no);
+ }
}
/* Calculate a plane that is rightangles to the edge/vert/faces normal
@@ -877,137 +875,142 @@ void BM_editselection_normal(BMEditSelection *ese, float r_normal[3])
* because this is used for the gizmos Y axis. */
void BM_editselection_plane(BMEditSelection *ese, float r_plane[3])
{
- if (ese->htype == BM_VERT) {
- BMVert *eve = (BMVert *)ese->ele;
- float vec[3] = {0.0f, 0.0f, 0.0f};
-
- if (ese->prev) { /* use previously selected data to make a useful vertex plane */
- BM_editselection_center(ese->prev, vec);
- sub_v3_v3v3(r_plane, vec, eve->co);
- }
- else {
- /* make a fake plane thats at rightangles to the normal
- * we cant make a crossvec from a vec thats the same as the vec
- * unlikely but possible, so make sure if the normal is (0, 0, 1)
- * that vec isn't the same or in the same direction even. */
- if (eve->no[0] < 0.5f) { vec[0] = 1.0f; }
- else if (eve->no[1] < 0.5f) { vec[1] = 1.0f; }
- else { vec[2] = 1.0f; }
- cross_v3_v3v3(r_plane, eve->no, vec);
- }
- normalize_v3(r_plane);
- }
- else if (ese->htype == BM_EDGE) {
- BMEdge *eed = (BMEdge *)ese->ele;
-
- if (BM_edge_is_boundary(eed)) {
- sub_v3_v3v3(r_plane, eed->l->v->co, eed->l->next->v->co);
- }
- else {
- /* the plane is simple, it runs along the edge
- * however selecting different edges can swap the direction of the y axis.
- * this makes it less likely for the y axis of the gizmo
- * (running along the edge).. to flip less often.
- * at least its more predictable */
- if (eed->v2->co[1] > eed->v1->co[1]) { /* check which to do first */
- sub_v3_v3v3(r_plane, eed->v2->co, eed->v1->co);
- }
- else {
- sub_v3_v3v3(r_plane, eed->v1->co, eed->v2->co);
- }
- }
-
- normalize_v3(r_plane);
- }
- else if (ese->htype == BM_FACE) {
- BMFace *efa = (BMFace *)ese->ele;
- BM_face_calc_tangent_auto(efa, r_plane);
- }
+ if (ese->htype == BM_VERT) {
+ BMVert *eve = (BMVert *)ese->ele;
+ float vec[3] = {0.0f, 0.0f, 0.0f};
+
+ if (ese->prev) { /* use previously selected data to make a useful vertex plane */
+ BM_editselection_center(ese->prev, vec);
+ sub_v3_v3v3(r_plane, vec, eve->co);
+ }
+ else {
+ /* make a fake plane thats at rightangles to the normal
+ * we cant make a crossvec from a vec thats the same as the vec
+ * unlikely but possible, so make sure if the normal is (0, 0, 1)
+ * that vec isn't the same or in the same direction even. */
+ if (eve->no[0] < 0.5f) {
+ vec[0] = 1.0f;
+ }
+ else if (eve->no[1] < 0.5f) {
+ vec[1] = 1.0f;
+ }
+ else {
+ vec[2] = 1.0f;
+ }
+ cross_v3_v3v3(r_plane, eve->no, vec);
+ }
+ normalize_v3(r_plane);
+ }
+ else if (ese->htype == BM_EDGE) {
+ BMEdge *eed = (BMEdge *)ese->ele;
+
+ if (BM_edge_is_boundary(eed)) {
+ sub_v3_v3v3(r_plane, eed->l->v->co, eed->l->next->v->co);
+ }
+ else {
+ /* the plane is simple, it runs along the edge
+ * however selecting different edges can swap the direction of the y axis.
+ * this makes it less likely for the y axis of the gizmo
+ * (running along the edge).. to flip less often.
+ * at least its more predictable */
+ if (eed->v2->co[1] > eed->v1->co[1]) { /* check which to do first */
+ sub_v3_v3v3(r_plane, eed->v2->co, eed->v1->co);
+ }
+ else {
+ sub_v3_v3v3(r_plane, eed->v1->co, eed->v2->co);
+ }
+ }
+
+ normalize_v3(r_plane);
+ }
+ else if (ese->htype == BM_FACE) {
+ BMFace *efa = (BMFace *)ese->ele;
+ BM_face_calc_tangent_auto(efa, r_plane);
+ }
}
static BMEditSelection *bm_select_history_create(BMHeader *ele)
{
- BMEditSelection *ese = (BMEditSelection *) MEM_callocN(sizeof(BMEditSelection), "BMEdit Selection");
- ese->htype = ele->htype;
- ese->ele = (BMElem *)ele;
- return ese;
+ BMEditSelection *ese = (BMEditSelection *)MEM_callocN(sizeof(BMEditSelection),
+ "BMEdit Selection");
+ ese->htype = ele->htype;
+ ese->ele = (BMElem *)ele;
+ return ese;
}
/* --- macro wrapped funcs --- */
bool _bm_select_history_check(BMesh *bm, const BMHeader *ele)
{
- return (BLI_findptr(&bm->selected, ele, offsetof(BMEditSelection, ele)) != NULL);
+ return (BLI_findptr(&bm->selected, ele, offsetof(BMEditSelection, ele)) != NULL);
}
bool _bm_select_history_remove(BMesh *bm, BMHeader *ele)
{
- BMEditSelection *ese = BLI_findptr(&bm->selected, ele, offsetof(BMEditSelection, ele));
- if (ese) {
- BLI_freelinkN(&bm->selected, ese);
- return true;
- }
- else {
- return false;
- }
+ BMEditSelection *ese = BLI_findptr(&bm->selected, ele, offsetof(BMEditSelection, ele));
+ if (ese) {
+ BLI_freelinkN(&bm->selected, ese);
+ return true;
+ }
+ else {
+ return false;
+ }
}
void _bm_select_history_store_notest(BMesh *bm, BMHeader *ele)
{
- BMEditSelection *ese = bm_select_history_create(ele);
- BLI_addtail(&(bm->selected), ese);
+ BMEditSelection *ese = bm_select_history_create(ele);
+ BLI_addtail(&(bm->selected), ese);
}
void _bm_select_history_store_head_notest(BMesh *bm, BMHeader *ele)
{
- BMEditSelection *ese = bm_select_history_create(ele);
- BLI_addhead(&(bm->selected), ese);
+ BMEditSelection *ese = bm_select_history_create(ele);
+ BLI_addhead(&(bm->selected), ese);
}
void _bm_select_history_store(BMesh *bm, BMHeader *ele)
{
- if (!BM_select_history_check(bm, (BMElem *)ele)) {
- BM_select_history_store_notest(bm, (BMElem *)ele);
- }
+ if (!BM_select_history_check(bm, (BMElem *)ele)) {
+ BM_select_history_store_notest(bm, (BMElem *)ele);
+ }
}
void _bm_select_history_store_head(BMesh *bm, BMHeader *ele)
{
- if (!BM_select_history_check(bm, (BMElem *)ele)) {
- BM_select_history_store_head_notest(bm, (BMElem *)ele);
- }
+ if (!BM_select_history_check(bm, (BMElem *)ele)) {
+ BM_select_history_store_head_notest(bm, (BMElem *)ele);
+ }
}
void _bm_select_history_store_after_notest(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele)
{
- BMEditSelection *ese = bm_select_history_create(ele);
- BLI_insertlinkafter(&(bm->selected), ese_ref, ese);
+ BMEditSelection *ese = bm_select_history_create(ele);
+ BLI_insertlinkafter(&(bm->selected), ese_ref, ese);
}
void _bm_select_history_store_after(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele)
{
- if (!BM_select_history_check(bm, (BMElem *)ele)) {
- BM_select_history_store_after_notest(bm, ese_ref, (BMElem *)ele);
- }
+ if (!BM_select_history_check(bm, (BMElem *)ele)) {
+ BM_select_history_store_after_notest(bm, ese_ref, (BMElem *)ele);
+ }
}
/* --- end macro wrapped funcs --- */
-
void BM_select_history_clear(BMesh *bm)
{
- BLI_freelistN(&bm->selected);
+ BLI_freelistN(&bm->selected);
}
-
void BM_select_history_validate(BMesh *bm)
{
- BMEditSelection *ese, *ese_next;
-
- for (ese = bm->selected.first; ese; ese = ese_next) {
- ese_next = ese->next;
- if (!BM_elem_flag_test(ese->ele, BM_ELEM_SELECT)) {
- BLI_freelinkN(&(bm->selected), ese);
- }
- }
+ BMEditSelection *ese, *ese_next;
+
+ for (ese = bm->selected.first; ese; ese = ese_next) {
+ ese_next = ese->next;
+ if (!BM_elem_flag_test(ese->ele, BM_ELEM_SELECT)) {
+ BLI_freelinkN(&(bm->selected), ese);
+ }
+ }
}
/**
@@ -1015,37 +1018,38 @@ void BM_select_history_validate(BMesh *bm)
*/
bool BM_select_history_active_get(BMesh *bm, BMEditSelection *ese)
{
- BMEditSelection *ese_last = bm->selected.last;
- BMFace *efa = BM_mesh_active_face_get(bm, false, false);
-
- ese->next = ese->prev = NULL;
-
- if (ese_last) {
- if (ese_last->htype == BM_FACE) { /* if there is an active face, use it over the last selected face */
- if (efa) {
- ese->ele = (BMElem *)efa;
- }
- else {
- ese->ele = ese_last->ele;
- }
- ese->htype = BM_FACE;
- }
- else {
- ese->ele = ese_last->ele;
- ese->htype = ese_last->htype;
- }
- }
- else if (efa) {
- /* no edit-selection, fallback to active face */
- ese->ele = (BMElem *)efa;
- ese->htype = BM_FACE;
- }
- else {
- ese->ele = NULL;
- return false;
- }
-
- return true;
+ BMEditSelection *ese_last = bm->selected.last;
+ BMFace *efa = BM_mesh_active_face_get(bm, false, false);
+
+ ese->next = ese->prev = NULL;
+
+ if (ese_last) {
+ if (ese_last->htype ==
+ BM_FACE) { /* if there is an active face, use it over the last selected face */
+ if (efa) {
+ ese->ele = (BMElem *)efa;
+ }
+ else {
+ ese->ele = ese_last->ele;
+ }
+ ese->htype = BM_FACE;
+ }
+ else {
+ ese->ele = ese_last->ele;
+ ese->htype = ese_last->htype;
+ }
+ }
+ else if (efa) {
+ /* no edit-selection, fallback to active face */
+ ese->ele = (BMElem *)efa;
+ ese->htype = BM_FACE;
+ }
+ else {
+ ese->ele = NULL;
+ return false;
+ }
+
+ return true;
}
/**
@@ -1053,220 +1057,225 @@ bool BM_select_history_active_get(BMesh *bm, BMEditSelection *ese)
*/
GHash *BM_select_history_map_create(BMesh *bm)
{
- BMEditSelection *ese;
- GHash *map;
+ BMEditSelection *ese;
+ GHash *map;
- if (BLI_listbase_is_empty(&bm->selected)) {
- return NULL;
- }
+ if (BLI_listbase_is_empty(&bm->selected)) {
+ return NULL;
+ }
- map = BLI_ghash_ptr_new(__func__);
+ map = BLI_ghash_ptr_new(__func__);
- for (ese = bm->selected.first; ese; ese = ese->next) {
- BLI_ghash_insert(map, ese->ele, ese);
- }
+ for (ese = bm->selected.first; ese; ese = ese->next) {
+ BLI_ghash_insert(map, ese->ele, ese);
+ }
- return map;
+ return map;
}
/**
* Map arguments may all be the same pointer.
*/
void BM_select_history_merge_from_targetmap(
- BMesh *bm,
- GHash *vert_map,
- GHash *edge_map,
- GHash *face_map,
- const bool use_chain)
+ BMesh *bm, GHash *vert_map, GHash *edge_map, GHash *face_map, const bool use_chain)
{
#ifdef DEBUG
- for (BMEditSelection *ese = bm->selected.first; ese; ese = ese->next) {
- BLI_assert(BM_ELEM_API_FLAG_TEST(ese->ele, _FLAG_OVERLAP) == 0);
- }
+ for (BMEditSelection *ese = bm->selected.first; ese; ese = ese->next) {
+ BLI_assert(BM_ELEM_API_FLAG_TEST(ese->ele, _FLAG_OVERLAP) == 0);
+ }
#endif
- for (BMEditSelection *ese = bm->selected.first; ese; ese = ese->next) {
- BM_ELEM_API_FLAG_ENABLE(ese->ele, _FLAG_OVERLAP);
-
- /* Only loop when (use_chain == true). */
- GHash *map = NULL;
- switch (ese->ele->head.htype) {
- case BM_VERT: map = vert_map; break;
- case BM_EDGE: map = edge_map; break;
- case BM_FACE: map = face_map; break;
- default: BMESH_ASSERT(0); break;
- }
- if (map != NULL) {
- BMElem *ele_dst = ese->ele;
- while (true) {
- BMElem *ele_dst_next = BLI_ghash_lookup(map, ele_dst);
- BLI_assert(ele_dst != ele_dst_next);
- if (ele_dst_next == NULL) {
- break;
- }
- ele_dst = ele_dst_next;
- /* Break loop on circular reference (should never happen). */
- if (UNLIKELY(ele_dst == ese->ele)) {
- BLI_assert(0);
- break;
- }
- if (use_chain == false) {
- break;
- }
- }
- ese->ele = ele_dst;
- }
- }
-
- /* Remove overlapping duplicates. */
- for (BMEditSelection *ese = bm->selected.first, *ese_next; ese; ese = ese_next) {
- ese_next = ese->next;
- if (BM_ELEM_API_FLAG_TEST(ese->ele, _FLAG_OVERLAP)) {
- BM_ELEM_API_FLAG_DISABLE(ese->ele, _FLAG_OVERLAP);
- }
- else {
- BLI_freelinkN(&bm->selected, ese);
- }
- }
+ for (BMEditSelection *ese = bm->selected.first; ese; ese = ese->next) {
+ BM_ELEM_API_FLAG_ENABLE(ese->ele, _FLAG_OVERLAP);
+
+ /* Only loop when (use_chain == true). */
+ GHash *map = NULL;
+ switch (ese->ele->head.htype) {
+ case BM_VERT:
+ map = vert_map;
+ break;
+ case BM_EDGE:
+ map = edge_map;
+ break;
+ case BM_FACE:
+ map = face_map;
+ break;
+ default:
+ BMESH_ASSERT(0);
+ break;
+ }
+ if (map != NULL) {
+ BMElem *ele_dst = ese->ele;
+ while (true) {
+ BMElem *ele_dst_next = BLI_ghash_lookup(map, ele_dst);
+ BLI_assert(ele_dst != ele_dst_next);
+ if (ele_dst_next == NULL) {
+ break;
+ }
+ ele_dst = ele_dst_next;
+ /* Break loop on circular reference (should never happen). */
+ if (UNLIKELY(ele_dst == ese->ele)) {
+ BLI_assert(0);
+ break;
+ }
+ if (use_chain == false) {
+ break;
+ }
+ }
+ ese->ele = ele_dst;
+ }
+ }
+
+ /* Remove overlapping duplicates. */
+ for (BMEditSelection *ese = bm->selected.first, *ese_next; ese; ese = ese_next) {
+ ese_next = ese->next;
+ if (BM_ELEM_API_FLAG_TEST(ese->ele, _FLAG_OVERLAP)) {
+ BM_ELEM_API_FLAG_DISABLE(ese->ele, _FLAG_OVERLAP);
+ }
+ else {
+ BLI_freelinkN(&bm->selected, ese);
+ }
+ }
}
-void BM_mesh_elem_hflag_disable_test(
- BMesh *bm, const char htype, const char hflag,
- const bool respecthide, const bool overwrite, const char hflag_test)
+void BM_mesh_elem_hflag_disable_test(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide,
+ const bool overwrite,
+ const char hflag_test)
{
- const char iter_types[3] = {BM_VERTS_OF_MESH,
- BM_EDGES_OF_MESH,
- BM_FACES_OF_MESH};
-
- const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
-
- const char hflag_nosel = hflag & ~BM_ELEM_SELECT;
-
- int i;
-
- BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
-
- if (hflag & BM_ELEM_SELECT) {
- BM_select_history_clear(bm);
- }
-
- if ((htype == (BM_VERT | BM_EDGE | BM_FACE)) &&
- (hflag == BM_ELEM_SELECT) &&
- (respecthide == false) &&
- (hflag_test == 0))
- {
- /* fast path for deselect all, avoid topology loops
- * since we know all will be de-selected anyway. */
- for (i = 0; i < 3; i++) {
- BMIter iter;
- BMElem *ele;
-
- ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
- BM_elem_flag_disable(ele, BM_ELEM_SELECT);
- }
- }
-
- bm->totvertsel = bm->totedgesel = bm->totfacesel = 0;
- }
- else {
- for (i = 0; i < 3; i++) {
- BMIter iter;
- BMElem *ele;
-
- if (htype & flag_types[i]) {
- ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
-
- if (UNLIKELY(respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN))) {
- /* pass */
- }
- else if (!hflag_test || BM_elem_flag_test(ele, hflag_test)) {
- if (hflag & BM_ELEM_SELECT) {
- BM_elem_select_set(bm, ele, false);
- }
- BM_elem_flag_disable(ele, hflag);
- }
- else if (overwrite) {
- /* no match! */
- if (hflag & BM_ELEM_SELECT) {
- BM_elem_select_set(bm, ele, true);
- }
- BM_elem_flag_enable(ele, hflag_nosel);
- }
- }
- }
- }
- }
+ const char iter_types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
+
+ const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
+
+ const char hflag_nosel = hflag & ~BM_ELEM_SELECT;
+
+ int i;
+
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
+ if (hflag & BM_ELEM_SELECT) {
+ BM_select_history_clear(bm);
+ }
+
+ if ((htype == (BM_VERT | BM_EDGE | BM_FACE)) && (hflag == BM_ELEM_SELECT) &&
+ (respecthide == false) && (hflag_test == 0)) {
+ /* fast path for deselect all, avoid topology loops
+ * since we know all will be de-selected anyway. */
+ for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+
+ ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
+ for (; ele; ele = BM_iter_step(&iter)) {
+ BM_elem_flag_disable(ele, BM_ELEM_SELECT);
+ }
+ }
+
+ bm->totvertsel = bm->totedgesel = bm->totfacesel = 0;
+ }
+ else {
+ for (i = 0; i < 3; i++) {
+ BMIter iter;
+ BMElem *ele;
+
+ if (htype & flag_types[i]) {
+ ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
+ for (; ele; ele = BM_iter_step(&iter)) {
+
+ if (UNLIKELY(respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN))) {
+ /* pass */
+ }
+ else if (!hflag_test || BM_elem_flag_test(ele, hflag_test)) {
+ if (hflag & BM_ELEM_SELECT) {
+ BM_elem_select_set(bm, ele, false);
+ }
+ BM_elem_flag_disable(ele, hflag);
+ }
+ else if (overwrite) {
+ /* no match! */
+ if (hflag & BM_ELEM_SELECT) {
+ BM_elem_select_set(bm, ele, true);
+ }
+ BM_elem_flag_enable(ele, hflag_nosel);
+ }
+ }
+ }
+ }
+ }
}
-void BM_mesh_elem_hflag_enable_test(
- BMesh *bm, const char htype, const char hflag,
- const bool respecthide, const bool overwrite, const char hflag_test)
+void BM_mesh_elem_hflag_enable_test(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide,
+ const bool overwrite,
+ const char hflag_test)
{
- const char iter_types[3] = {BM_VERTS_OF_MESH,
- BM_EDGES_OF_MESH,
- BM_FACES_OF_MESH};
-
- const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
-
- /* use the nosel version when setting so under no
- * condition may a hidden face become selected.
- * Applying other flags to hidden faces is OK. */
- const char hflag_nosel = hflag & ~BM_ELEM_SELECT;
-
- BMIter iter;
- BMElem *ele;
- int i;
-
- BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
-
- /* note, better not attempt a fast path for selection as done with de-select
- * because hidden geometry and different selection modes can give different results,
- * we could of course check for no hidden faces and then use quicker method but its not worth it. */
-
- for (i = 0; i < 3; i++) {
- if (htype & flag_types[i]) {
- ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
- for ( ; ele; ele = BM_iter_step(&iter)) {
-
- if (UNLIKELY(respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN))) {
- /* pass */
- }
- else if (!hflag_test || BM_elem_flag_test(ele, hflag_test)) {
- /* match! */
- if (hflag & BM_ELEM_SELECT) {
- BM_elem_select_set(bm, ele, true);
- }
- BM_elem_flag_enable(ele, hflag_nosel);
- }
- else if (overwrite) {
- /* no match! */
- if (hflag & BM_ELEM_SELECT) {
- BM_elem_select_set(bm, ele, false);
- }
- BM_elem_flag_disable(ele, hflag);
- }
- }
- }
- }
+ const char iter_types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
+
+ const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
+
+ /* use the nosel version when setting so under no
+ * condition may a hidden face become selected.
+ * Applying other flags to hidden faces is OK. */
+ const char hflag_nosel = hflag & ~BM_ELEM_SELECT;
+
+ BMIter iter;
+ BMElem *ele;
+ int i;
+
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
+ /* note, better not attempt a fast path for selection as done with de-select
+ * because hidden geometry and different selection modes can give different results,
+ * we could of course check for no hidden faces and then use quicker method but its not worth it. */
+
+ for (i = 0; i < 3; i++) {
+ if (htype & flag_types[i]) {
+ ele = BM_iter_new(&iter, bm, iter_types[i], NULL);
+ for (; ele; ele = BM_iter_step(&iter)) {
+
+ if (UNLIKELY(respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN))) {
+ /* pass */
+ }
+ else if (!hflag_test || BM_elem_flag_test(ele, hflag_test)) {
+ /* match! */
+ if (hflag & BM_ELEM_SELECT) {
+ BM_elem_select_set(bm, ele, true);
+ }
+ BM_elem_flag_enable(ele, hflag_nosel);
+ }
+ else if (overwrite) {
+ /* no match! */
+ if (hflag & BM_ELEM_SELECT) {
+ BM_elem_select_set(bm, ele, false);
+ }
+ BM_elem_flag_disable(ele, hflag);
+ }
+ }
+ }
+ }
}
-void BM_mesh_elem_hflag_disable_all(
- BMesh *bm, const char htype, const char hflag,
- const bool respecthide)
+void BM_mesh_elem_hflag_disable_all(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide)
{
- /* call with 0 hflag_test */
- BM_mesh_elem_hflag_disable_test(bm, htype, hflag, respecthide, false, 0);
+ /* call with 0 hflag_test */
+ BM_mesh_elem_hflag_disable_test(bm, htype, hflag, respecthide, false, 0);
}
-void BM_mesh_elem_hflag_enable_all(
- BMesh *bm, const char htype, const char hflag,
- const bool respecthide)
+void BM_mesh_elem_hflag_enable_all(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide)
{
- /* call with 0 hflag_test */
- BM_mesh_elem_hflag_enable_test(bm, htype, hflag, respecthide, false, 0);
+ /* call with 0 hflag_test */
+ BM_mesh_elem_hflag_enable_test(bm, htype, hflag, respecthide, false, 0);
}
/***************** Mesh Hiding stuff *********** */
@@ -1277,7 +1286,7 @@ void BM_mesh_elem_hflag_enable_all(
*/
static void vert_flush_hide_set(BMVert *v)
{
- BM_elem_flag_set(v, BM_ELEM_HIDDEN, !bm_vert_is_edge_visible_any(v));
+ BM_elem_flag_set(v, BM_ELEM_HIDDEN, !bm_vert_is_edge_visible_any(v));
}
/**
@@ -1286,124 +1295,124 @@ static void vert_flush_hide_set(BMVert *v)
*/
static void edge_flush_hide_set(BMEdge *e)
{
- BM_elem_flag_set(e, BM_ELEM_HIDDEN, !bm_edge_is_face_visible_any(e));
+ BM_elem_flag_set(e, BM_ELEM_HIDDEN, !bm_edge_is_face_visible_any(e));
}
void BM_vert_hide_set(BMVert *v, const bool hide)
{
- /* vert hiding: vert + surrounding edges and faces */
- BLI_assert(v->head.htype == BM_VERT);
- if (hide) {
- BLI_assert(!BM_elem_flag_test(v, BM_ELEM_SELECT));
- }
-
- BM_elem_flag_set(v, BM_ELEM_HIDDEN, hide);
-
- if (v->e) {
- BMEdge *e_iter, *e_first;
- e_iter = e_first = v->e;
- do {
- BM_elem_flag_set(e_iter, BM_ELEM_HIDDEN, hide);
- if (e_iter->l) {
- const BMLoop *l_radial_iter, *l_radial_first;
- l_radial_iter = l_radial_first = e_iter->l;
- do {
- BM_elem_flag_set(l_radial_iter->f, BM_ELEM_HIDDEN, hide);
- } while ((l_radial_iter = l_radial_iter->radial_next) != l_radial_first);
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- }
+ /* vert hiding: vert + surrounding edges and faces */
+ BLI_assert(v->head.htype == BM_VERT);
+ if (hide) {
+ BLI_assert(!BM_elem_flag_test(v, BM_ELEM_SELECT));
+ }
+
+ BM_elem_flag_set(v, BM_ELEM_HIDDEN, hide);
+
+ if (v->e) {
+ BMEdge *e_iter, *e_first;
+ e_iter = e_first = v->e;
+ do {
+ BM_elem_flag_set(e_iter, BM_ELEM_HIDDEN, hide);
+ if (e_iter->l) {
+ const BMLoop *l_radial_iter, *l_radial_first;
+ l_radial_iter = l_radial_first = e_iter->l;
+ do {
+ BM_elem_flag_set(l_radial_iter->f, BM_ELEM_HIDDEN, hide);
+ } while ((l_radial_iter = l_radial_iter->radial_next) != l_radial_first);
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
}
void BM_edge_hide_set(BMEdge *e, const bool hide)
{
- BLI_assert(e->head.htype == BM_EDGE);
- if (hide) {
- BLI_assert(!BM_elem_flag_test(e, BM_ELEM_SELECT));
- }
-
- /* edge hiding: faces around the edge */
- if (e->l) {
- const BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- BM_elem_flag_set(l_iter->f, BM_ELEM_HIDDEN, hide);
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
-
- BM_elem_flag_set(e, BM_ELEM_HIDDEN, hide);
-
- /* hide vertices if necessary */
- if (hide) {
- vert_flush_hide_set(e->v1);
- vert_flush_hide_set(e->v2);
- }
- else {
- BM_elem_flag_disable(e->v1, BM_ELEM_HIDDEN);
- BM_elem_flag_disable(e->v2, BM_ELEM_HIDDEN);
- }
+ BLI_assert(e->head.htype == BM_EDGE);
+ if (hide) {
+ BLI_assert(!BM_elem_flag_test(e, BM_ELEM_SELECT));
+ }
+
+ /* edge hiding: faces around the edge */
+ if (e->l) {
+ const BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ BM_elem_flag_set(l_iter->f, BM_ELEM_HIDDEN, hide);
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+
+ BM_elem_flag_set(e, BM_ELEM_HIDDEN, hide);
+
+ /* hide vertices if necessary */
+ if (hide) {
+ vert_flush_hide_set(e->v1);
+ vert_flush_hide_set(e->v2);
+ }
+ else {
+ BM_elem_flag_disable(e->v1, BM_ELEM_HIDDEN);
+ BM_elem_flag_disable(e->v2, BM_ELEM_HIDDEN);
+ }
}
void BM_face_hide_set(BMFace *f, const bool hide)
{
- BLI_assert(f->head.htype == BM_FACE);
- if (hide) {
- BLI_assert(!BM_elem_flag_test(f, BM_ELEM_SELECT));
- }
-
- BM_elem_flag_set(f, BM_ELEM_HIDDEN, hide);
-
- if (hide) {
- BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
- BMLoop *l_iter;
-
- l_iter = l_first;
- do {
- edge_flush_hide_set(l_iter->e);
- } while ((l_iter = l_iter->next) != l_first);
-
- l_iter = l_first;
- do {
- vert_flush_hide_set(l_iter->v);
- } while ((l_iter = l_iter->next) != l_first);
- }
- else {
- BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
- BMLoop *l_iter;
-
- l_iter = l_first;
- do {
- BM_elem_flag_disable(l_iter->e, BM_ELEM_HIDDEN);
- BM_elem_flag_disable(l_iter->v, BM_ELEM_HIDDEN);
- } while ((l_iter = l_iter->next) != l_first);
- }
+ BLI_assert(f->head.htype == BM_FACE);
+ if (hide) {
+ BLI_assert(!BM_elem_flag_test(f, BM_ELEM_SELECT));
+ }
+
+ BM_elem_flag_set(f, BM_ELEM_HIDDEN, hide);
+
+ if (hide) {
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
+
+ l_iter = l_first;
+ do {
+ edge_flush_hide_set(l_iter->e);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ l_iter = l_first;
+ do {
+ vert_flush_hide_set(l_iter->v);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ else {
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
+
+ l_iter = l_first;
+ do {
+ BM_elem_flag_disable(l_iter->e, BM_ELEM_HIDDEN);
+ BM_elem_flag_disable(l_iter->v, BM_ELEM_HIDDEN);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
}
void _bm_elem_hide_set(BMesh *bm, BMHeader *head, const bool hide)
{
- /* Follow convention of always deselecting before
- * hiding an element */
- switch (head->htype) {
- case BM_VERT:
- if (hide) {
- BM_vert_select_set(bm, (BMVert *)head, false);
- }
- BM_vert_hide_set((BMVert *)head, hide);
- break;
- case BM_EDGE:
- if (hide) {
- BM_edge_select_set(bm, (BMEdge *)head, false);
- }
- BM_edge_hide_set((BMEdge *)head, hide);
- break;
- case BM_FACE:
- if (hide) {
- BM_face_select_set(bm, (BMFace *)head, false);
- }
- BM_face_hide_set((BMFace *)head, hide);
- break;
- default:
- BMESH_ASSERT(0);
- break;
- }
+ /* Follow convention of always deselecting before
+ * hiding an element */
+ switch (head->htype) {
+ case BM_VERT:
+ if (hide) {
+ BM_vert_select_set(bm, (BMVert *)head, false);
+ }
+ BM_vert_hide_set((BMVert *)head, hide);
+ break;
+ case BM_EDGE:
+ if (hide) {
+ BM_edge_select_set(bm, (BMEdge *)head, false);
+ }
+ BM_edge_hide_set((BMEdge *)head, hide);
+ break;
+ case BM_FACE:
+ if (hide) {
+ BM_face_select_set(bm, (BMFace *)head, false);
+ }
+ BM_face_hide_set((BMFace *)head, hide);
+ break;
+ default:
+ BMESH_ASSERT(0);
+ break;
+ }
}
diff --git a/source/blender/bmesh/intern/bmesh_marking.h b/source/blender/bmesh/intern/bmesh_marking.h
index a7416b484d7..06314a7a388 100644
--- a/source/blender/bmesh/intern/bmesh_marking.h
+++ b/source/blender/bmesh/intern/bmesh_marking.h
@@ -22,9 +22,9 @@
*/
typedef struct BMEditSelection {
- struct BMEditSelection *next, *prev;
- BMElem *ele;
- char htype;
+ struct BMEditSelection *next, *prev;
+ BMElem *ele;
+ char htype;
} BMEditSelection;
/* geometry hiding code */
@@ -37,19 +37,27 @@ void BM_face_hide_set(BMFace *f, const bool hide);
/* Selection code */
void BM_elem_select_set(BMesh *bm, BMElem *ele, const bool select);
-void BM_mesh_elem_hflag_enable_test(
- BMesh *bm, const char htype, const char hflag,
- const bool respecthide, const bool overwrite, const char hflag_test);
-void BM_mesh_elem_hflag_disable_test(
- BMesh *bm, const char htype, const char hflag,
- const bool respecthide, const bool overwrite, const char hflag_test);
-
-void BM_mesh_elem_hflag_enable_all(
- BMesh *bm, const char htype, const char hflag,
- const bool respecthide);
-void BM_mesh_elem_hflag_disable_all(
- BMesh *bm, const char htype, const char hflag,
- const bool respecthide);
+void BM_mesh_elem_hflag_enable_test(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide,
+ const bool overwrite,
+ const char hflag_test);
+void BM_mesh_elem_hflag_disable_test(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide,
+ const bool overwrite,
+ const char hflag_test);
+
+void BM_mesh_elem_hflag_enable_all(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide);
+void BM_mesh_elem_hflag_disable_all(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide);
/* individual element select functions, BM_elem_select_set is a shortcut for these
* that automatically detects which one to use*/
@@ -71,37 +79,46 @@ void BM_mesh_select_mode_flush(BMesh *bm);
void BM_mesh_deselect_flush(BMesh *bm);
void BM_mesh_select_flush(BMesh *bm);
-int BM_mesh_elem_hflag_count_enabled(BMesh *bm, const char htype, const char hflag, const bool respecthide);
-int BM_mesh_elem_hflag_count_disabled(BMesh *bm, const char htype, const char hflag, const bool respecthide);
+int BM_mesh_elem_hflag_count_enabled(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide);
+int BM_mesh_elem_hflag_count_disabled(BMesh *bm,
+ const char htype,
+ const char hflag,
+ const bool respecthide);
/* edit selection stuff */
-void BM_mesh_active_face_set(BMesh *bm, BMFace *f);
+void BM_mesh_active_face_set(BMesh *bm, BMFace *f);
BMFace *BM_mesh_active_face_get(BMesh *bm, const bool is_sloppy, const bool is_selected);
BMEdge *BM_mesh_active_edge_get(BMesh *bm);
BMVert *BM_mesh_active_vert_get(BMesh *bm);
BMElem *BM_mesh_active_elem_get(BMesh *bm);
-void BM_editselection_center(BMEditSelection *ese, float r_center[3]);
-void BM_editselection_normal(BMEditSelection *ese, float r_normal[3]);
-void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]);
+void BM_editselection_center(BMEditSelection *ese, float r_center[3]);
+void BM_editselection_normal(BMEditSelection *ese, float r_normal[3]);
+void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]);
-#define BM_select_history_check(bm, ele) _bm_select_history_check(bm, &(ele)->head)
-#define BM_select_history_remove(bm, ele) _bm_select_history_remove(bm, &(ele)->head)
+#define BM_select_history_check(bm, ele) _bm_select_history_check(bm, &(ele)->head)
+#define BM_select_history_remove(bm, ele) _bm_select_history_remove(bm, &(ele)->head)
#define BM_select_history_store_notest(bm, ele) _bm_select_history_store_notest(bm, &(ele)->head)
-#define BM_select_history_store(bm, ele) _bm_select_history_store(bm, &(ele)->head)
-#define BM_select_history_store_head_notest(bm, ele) _bm_select_history_store_head_notest(bm, &(ele)->head)
-#define BM_select_history_store_head(bm, ele) _bm_select_history_store_head(bm, &(ele)->head)
-#define BM_select_history_store_after_notest(bm, ese_ref, ele) _bm_select_history_store_after_notest(bm, ese_ref, &(ele)->head)
-#define BM_select_history_store_after(bm, ese, ese_ref) _bm_select_history_store_after(bm, ese_ref, &(ele)->head)
-
-bool _bm_select_history_check(BMesh *bm, const BMHeader *ele);
-bool _bm_select_history_remove(BMesh *bm, BMHeader *ele);
+#define BM_select_history_store(bm, ele) _bm_select_history_store(bm, &(ele)->head)
+#define BM_select_history_store_head_notest(bm, ele) \
+ _bm_select_history_store_head_notest(bm, &(ele)->head)
+#define BM_select_history_store_head(bm, ele) _bm_select_history_store_head(bm, &(ele)->head)
+#define BM_select_history_store_after_notest(bm, ese_ref, ele) \
+ _bm_select_history_store_after_notest(bm, ese_ref, &(ele)->head)
+#define BM_select_history_store_after(bm, ese, ese_ref) \
+ _bm_select_history_store_after(bm, ese_ref, &(ele)->head)
+
+bool _bm_select_history_check(BMesh *bm, const BMHeader *ele);
+bool _bm_select_history_remove(BMesh *bm, BMHeader *ele);
void _bm_select_history_store_notest(BMesh *bm, BMHeader *ele);
-void _bm_select_history_store(BMesh *bm, BMHeader *ele);
+void _bm_select_history_store(BMesh *bm, BMHeader *ele);
void _bm_select_history_store_head_notest(BMesh *bm, BMHeader *ele);
-void _bm_select_history_store_head(BMesh *bm, BMHeader *ele);
-void _bm_select_history_store_after(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele);
-void _bm_select_history_store_after_notest(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele);
+void _bm_select_history_store_head(BMesh *bm, BMHeader *ele);
+void _bm_select_history_store_after(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele);
+void _bm_select_history_store_after_notest(BMesh *bm, BMEditSelection *ese_ref, BMHeader *ele);
void BM_select_history_validate(BMesh *bm);
void BM_select_history_clear(BMesh *bm);
@@ -109,12 +126,16 @@ bool BM_select_history_active_get(BMesh *bm, struct BMEditSelection *ese);
struct GHash *BM_select_history_map_create(BMesh *bm);
void BM_select_history_merge_from_targetmap(
- BMesh *bm, GHash *vert_map, GHash *edge_map, GHash *face_map, const bool use_chain);
+ BMesh *bm, GHash *vert_map, GHash *edge_map, GHash *face_map, const bool use_chain);
-#define BM_SELECT_HISTORY_BACKUP(bm) { \
- ListBase _bm_prev_selected = (bm)->selected; BLI_listbase_clear(&(bm)->selected)
+#define BM_SELECT_HISTORY_BACKUP(bm) \
+ { \
+ ListBase _bm_prev_selected = (bm)->selected; \
+ BLI_listbase_clear(&(bm)->selected)
#define BM_SELECT_HISTORY_RESTORE(bm) \
- (bm)->selected = _bm_prev_selected; } (void)0
+ (bm)->selected = _bm_prev_selected; \
+ } \
+ (void)0
#endif /* __BMESH_MARKING_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index 460b7ce8dae..8d445d428b2 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -45,106 +45,103 @@
const BMAllocTemplate bm_mesh_allocsize_default = {512, 1024, 2048, 512};
const BMAllocTemplate bm_mesh_chunksize_default = {512, 1024, 2048, 512};
-static void bm_mempool_init_ex(
- const BMAllocTemplate *allocsize, const bool use_toolflags,
- BLI_mempool **r_vpool, BLI_mempool **r_epool, BLI_mempool **r_lpool, BLI_mempool **r_fpool)
+static void bm_mempool_init_ex(const BMAllocTemplate *allocsize,
+ const bool use_toolflags,
+ BLI_mempool **r_vpool,
+ BLI_mempool **r_epool,
+ BLI_mempool **r_lpool,
+ BLI_mempool **r_fpool)
{
- size_t vert_size, edge_size, loop_size, face_size;
-
- if (use_toolflags == true) {
- vert_size = sizeof(BMVert_OFlag);
- edge_size = sizeof(BMEdge_OFlag);
- loop_size = sizeof(BMLoop);
- face_size = sizeof(BMFace_OFlag);
- }
- else {
- vert_size = sizeof(BMVert);
- edge_size = sizeof(BMEdge);
- loop_size = sizeof(BMLoop);
- face_size = sizeof(BMFace);
- }
-
- if (r_vpool) {
- *r_vpool = BLI_mempool_create(
- vert_size, allocsize->totvert,
- bm_mesh_chunksize_default.totvert, BLI_MEMPOOL_ALLOW_ITER);
- }
- if (r_epool) {
- *r_epool = BLI_mempool_create(
- edge_size, allocsize->totedge,
- bm_mesh_chunksize_default.totedge, BLI_MEMPOOL_ALLOW_ITER);
- }
- if (r_lpool) {
- *r_lpool = BLI_mempool_create(
- loop_size, allocsize->totloop,
- bm_mesh_chunksize_default.totloop, BLI_MEMPOOL_NOP);
- }
- if (r_fpool) {
- *r_fpool = BLI_mempool_create(
- face_size, allocsize->totface,
- bm_mesh_chunksize_default.totface, BLI_MEMPOOL_ALLOW_ITER);
- }
+ size_t vert_size, edge_size, loop_size, face_size;
+
+ if (use_toolflags == true) {
+ vert_size = sizeof(BMVert_OFlag);
+ edge_size = sizeof(BMEdge_OFlag);
+ loop_size = sizeof(BMLoop);
+ face_size = sizeof(BMFace_OFlag);
+ }
+ else {
+ vert_size = sizeof(BMVert);
+ edge_size = sizeof(BMEdge);
+ loop_size = sizeof(BMLoop);
+ face_size = sizeof(BMFace);
+ }
+
+ if (r_vpool) {
+ *r_vpool = BLI_mempool_create(
+ vert_size, allocsize->totvert, bm_mesh_chunksize_default.totvert, BLI_MEMPOOL_ALLOW_ITER);
+ }
+ if (r_epool) {
+ *r_epool = BLI_mempool_create(
+ edge_size, allocsize->totedge, bm_mesh_chunksize_default.totedge, BLI_MEMPOOL_ALLOW_ITER);
+ }
+ if (r_lpool) {
+ *r_lpool = BLI_mempool_create(
+ loop_size, allocsize->totloop, bm_mesh_chunksize_default.totloop, BLI_MEMPOOL_NOP);
+ }
+ if (r_fpool) {
+ *r_fpool = BLI_mempool_create(
+ face_size, allocsize->totface, bm_mesh_chunksize_default.totface, BLI_MEMPOOL_ALLOW_ITER);
+ }
}
static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize, const bool use_toolflags)
{
- bm_mempool_init_ex(
- allocsize, use_toolflags,
- &bm->vpool, &bm->epool, &bm->lpool, &bm->fpool);
+ bm_mempool_init_ex(allocsize, use_toolflags, &bm->vpool, &bm->epool, &bm->lpool, &bm->fpool);
#ifdef USE_BMESH_HOLES
- bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, BLI_MEMPOOL_NOP);
+ bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, BLI_MEMPOOL_NOP);
#endif
}
void BM_mesh_elem_toolflags_ensure(BMesh *bm)
{
- BLI_assert(bm->use_toolflags);
-
- if (bm->vtoolflagpool && bm->etoolflagpool && bm->ftoolflagpool) {
- return;
- }
-
- bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totvert, 512, BLI_MEMPOOL_NOP);
- bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totedge, 512, BLI_MEMPOOL_NOP);
- bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totface, 512, BLI_MEMPOOL_NOP);
-
- BMIter iter;
- BMVert_OFlag *v_olfag;
- BLI_mempool *toolflagpool = bm->vtoolflagpool;
- BM_ITER_MESH (v_olfag, &iter, bm, BM_VERTS_OF_MESH) {
- v_olfag->oflags = BLI_mempool_calloc(toolflagpool);
- }
-
- BMEdge_OFlag *e_olfag;
- toolflagpool = bm->etoolflagpool;
- BM_ITER_MESH (e_olfag, &iter, bm, BM_EDGES_OF_MESH) {
- e_olfag->oflags = BLI_mempool_calloc(toolflagpool);
- }
-
- BMFace_OFlag *f_olfag;
- toolflagpool = bm->ftoolflagpool;
- BM_ITER_MESH (f_olfag, &iter, bm, BM_FACES_OF_MESH) {
- f_olfag->oflags = BLI_mempool_calloc(toolflagpool);
- }
-
- bm->totflags = 1;
+ BLI_assert(bm->use_toolflags);
+
+ if (bm->vtoolflagpool && bm->etoolflagpool && bm->ftoolflagpool) {
+ return;
+ }
+
+ bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totvert, 512, BLI_MEMPOOL_NOP);
+ bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totedge, 512, BLI_MEMPOOL_NOP);
+ bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totface, 512, BLI_MEMPOOL_NOP);
+
+ BMIter iter;
+ BMVert_OFlag *v_olfag;
+ BLI_mempool *toolflagpool = bm->vtoolflagpool;
+ BM_ITER_MESH (v_olfag, &iter, bm, BM_VERTS_OF_MESH) {
+ v_olfag->oflags = BLI_mempool_calloc(toolflagpool);
+ }
+
+ BMEdge_OFlag *e_olfag;
+ toolflagpool = bm->etoolflagpool;
+ BM_ITER_MESH (e_olfag, &iter, bm, BM_EDGES_OF_MESH) {
+ e_olfag->oflags = BLI_mempool_calloc(toolflagpool);
+ }
+
+ BMFace_OFlag *f_olfag;
+ toolflagpool = bm->ftoolflagpool;
+ BM_ITER_MESH (f_olfag, &iter, bm, BM_FACES_OF_MESH) {
+ f_olfag->oflags = BLI_mempool_calloc(toolflagpool);
+ }
+
+ bm->totflags = 1;
}
void BM_mesh_elem_toolflags_clear(BMesh *bm)
{
- if (bm->vtoolflagpool) {
- BLI_mempool_destroy(bm->vtoolflagpool);
- bm->vtoolflagpool = NULL;
- }
- if (bm->etoolflagpool) {
- BLI_mempool_destroy(bm->etoolflagpool);
- bm->etoolflagpool = NULL;
- }
- if (bm->ftoolflagpool) {
- BLI_mempool_destroy(bm->ftoolflagpool);
- bm->ftoolflagpool = NULL;
- }
+ if (bm->vtoolflagpool) {
+ BLI_mempool_destroy(bm->vtoolflagpool);
+ bm->vtoolflagpool = NULL;
+ }
+ if (bm->etoolflagpool) {
+ BLI_mempool_destroy(bm->etoolflagpool);
+ bm->etoolflagpool = NULL;
+ }
+ if (bm->ftoolflagpool) {
+ BLI_mempool_destroy(bm->ftoolflagpool);
+ bm->ftoolflagpool = NULL;
+ }
}
/**
@@ -156,27 +153,25 @@ void BM_mesh_elem_toolflags_clear(BMesh *bm)
*
* \note ob is needed by multires
*/
-BMesh *BM_mesh_create(
- const BMAllocTemplate *allocsize,
- const struct BMeshCreateParams *params)
+BMesh *BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
{
- /* allocate the structure */
- BMesh *bm = MEM_callocN(sizeof(BMesh), __func__);
+ /* allocate the structure */
+ BMesh *bm = MEM_callocN(sizeof(BMesh), __func__);
- /* allocate the memory pools for the mesh elements */
- bm_mempool_init(bm, allocsize, params->use_toolflags);
+ /* allocate the memory pools for the mesh elements */
+ bm_mempool_init(bm, allocsize, params->use_toolflags);
- /* allocate one flag pool that we don't get rid of. */
- bm->use_toolflags = params->use_toolflags;
- bm->toolflag_index = 0;
- bm->totflags = 0;
+ /* allocate one flag pool that we don't get rid of. */
+ bm->use_toolflags = params->use_toolflags;
+ bm->toolflag_index = 0;
+ bm->totflags = 0;
- CustomData_reset(&bm->vdata);
- CustomData_reset(&bm->edata);
- CustomData_reset(&bm->ldata);
- CustomData_reset(&bm->pdata);
+ CustomData_reset(&bm->vdata);
+ CustomData_reset(&bm->edata);
+ CustomData_reset(&bm->ldata);
+ CustomData_reset(&bm->pdata);
- return bm;
+ return bm;
}
/**
@@ -188,79 +183,93 @@ BMesh *BM_mesh_create(
*/
void BM_mesh_data_free(BMesh *bm)
{
- BMVert *v;
- BMEdge *e;
- BMLoop *l;
- BMFace *f;
-
- BMIter iter;
- BMIter itersub;
-
- const bool is_ldata_free = CustomData_bmesh_has_free(&bm->ldata);
- const bool is_pdata_free = CustomData_bmesh_has_free(&bm->pdata);
-
- /* Check if we have to call free, if not we can avoid a lot of looping */
- if (CustomData_bmesh_has_free(&(bm->vdata))) {
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- CustomData_bmesh_free_block(&(bm->vdata), &(v->head.data));
- }
- }
- if (CustomData_bmesh_has_free(&(bm->edata))) {
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- CustomData_bmesh_free_block(&(bm->edata), &(e->head.data));
- }
- }
-
- if (is_ldata_free || is_pdata_free) {
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (is_pdata_free) {
- CustomData_bmesh_free_block(&(bm->pdata), &(f->head.data));
- }
- if (is_ldata_free) {
- BM_ITER_ELEM (l, &itersub, f, BM_LOOPS_OF_FACE) {
- CustomData_bmesh_free_block(&(bm->ldata), &(l->head.data));
- }
- }
- }
- }
-
- /* Free custom data pools, This should probably go in CustomData_free? */
- if (bm->vdata.totlayer) { BLI_mempool_destroy(bm->vdata.pool); }
- if (bm->edata.totlayer) { BLI_mempool_destroy(bm->edata.pool); }
- if (bm->ldata.totlayer) { BLI_mempool_destroy(bm->ldata.pool); }
- if (bm->pdata.totlayer) { BLI_mempool_destroy(bm->pdata.pool); }
-
- /* free custom data */
- CustomData_free(&bm->vdata, 0);
- CustomData_free(&bm->edata, 0);
- CustomData_free(&bm->ldata, 0);
- CustomData_free(&bm->pdata, 0);
-
- /* destroy element pools */
- BLI_mempool_destroy(bm->vpool);
- BLI_mempool_destroy(bm->epool);
- BLI_mempool_destroy(bm->lpool);
- BLI_mempool_destroy(bm->fpool);
-
- if (bm->vtable) { MEM_freeN(bm->vtable); }
- if (bm->etable) { MEM_freeN(bm->etable); }
- if (bm->ftable) { MEM_freeN(bm->ftable); }
-
- /* destroy flag pool */
- BM_mesh_elem_toolflags_clear(bm);
+ BMVert *v;
+ BMEdge *e;
+ BMLoop *l;
+ BMFace *f;
+
+ BMIter iter;
+ BMIter itersub;
+
+ const bool is_ldata_free = CustomData_bmesh_has_free(&bm->ldata);
+ const bool is_pdata_free = CustomData_bmesh_has_free(&bm->pdata);
+
+ /* Check if we have to call free, if not we can avoid a lot of looping */
+ if (CustomData_bmesh_has_free(&(bm->vdata))) {
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ CustomData_bmesh_free_block(&(bm->vdata), &(v->head.data));
+ }
+ }
+ if (CustomData_bmesh_has_free(&(bm->edata))) {
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ CustomData_bmesh_free_block(&(bm->edata), &(e->head.data));
+ }
+ }
+
+ if (is_ldata_free || is_pdata_free) {
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (is_pdata_free) {
+ CustomData_bmesh_free_block(&(bm->pdata), &(f->head.data));
+ }
+ if (is_ldata_free) {
+ BM_ITER_ELEM (l, &itersub, f, BM_LOOPS_OF_FACE) {
+ CustomData_bmesh_free_block(&(bm->ldata), &(l->head.data));
+ }
+ }
+ }
+ }
+
+ /* Free custom data pools, This should probably go in CustomData_free? */
+ if (bm->vdata.totlayer) {
+ BLI_mempool_destroy(bm->vdata.pool);
+ }
+ if (bm->edata.totlayer) {
+ BLI_mempool_destroy(bm->edata.pool);
+ }
+ if (bm->ldata.totlayer) {
+ BLI_mempool_destroy(bm->ldata.pool);
+ }
+ if (bm->pdata.totlayer) {
+ BLI_mempool_destroy(bm->pdata.pool);
+ }
+
+ /* free custom data */
+ CustomData_free(&bm->vdata, 0);
+ CustomData_free(&bm->edata, 0);
+ CustomData_free(&bm->ldata, 0);
+ CustomData_free(&bm->pdata, 0);
+
+ /* destroy element pools */
+ BLI_mempool_destroy(bm->vpool);
+ BLI_mempool_destroy(bm->epool);
+ BLI_mempool_destroy(bm->lpool);
+ BLI_mempool_destroy(bm->fpool);
+
+ if (bm->vtable) {
+ MEM_freeN(bm->vtable);
+ }
+ if (bm->etable) {
+ MEM_freeN(bm->etable);
+ }
+ if (bm->ftable) {
+ MEM_freeN(bm->ftable);
+ }
+
+ /* destroy flag pool */
+ BM_mesh_elem_toolflags_clear(bm);
#ifdef USE_BMESH_HOLES
- BLI_mempool_destroy(bm->looplistpool);
+ BLI_mempool_destroy(bm->looplistpool);
#endif
- BLI_freelistN(&bm->selected);
+ BLI_freelistN(&bm->selected);
- if (bm->lnor_spacearr) {
- BKE_lnor_spacearr_free(bm->lnor_spacearr);
- MEM_freeN(bm->lnor_spacearr);
- }
+ if (bm->lnor_spacearr) {
+ BKE_lnor_spacearr_free(bm->lnor_spacearr);
+ MEM_freeN(bm->lnor_spacearr);
+ }
- BMO_error_clear(bm);
+ BMO_error_clear(bm);
}
/**
@@ -270,23 +279,23 @@ void BM_mesh_data_free(BMesh *bm)
*/
void BM_mesh_clear(BMesh *bm)
{
- const bool use_toolflags = bm->use_toolflags;
+ const bool use_toolflags = bm->use_toolflags;
- /* free old mesh */
- BM_mesh_data_free(bm);
- memset(bm, 0, sizeof(BMesh));
+ /* free old mesh */
+ BM_mesh_data_free(bm);
+ memset(bm, 0, sizeof(BMesh));
- /* allocate the memory pools for the mesh elements */
- bm_mempool_init(bm, &bm_mesh_allocsize_default, use_toolflags);
+ /* allocate the memory pools for the mesh elements */
+ bm_mempool_init(bm, &bm_mesh_allocsize_default, use_toolflags);
- bm->use_toolflags = use_toolflags;
- bm->toolflag_index = 0;
- bm->totflags = 0;
+ bm->use_toolflags = use_toolflags;
+ bm->toolflag_index = 0;
+ bm->totflags = 0;
- CustomData_reset(&bm->vdata);
- CustomData_reset(&bm->edata);
- CustomData_reset(&bm->ldata);
- CustomData_reset(&bm->pdata);
+ CustomData_reset(&bm->vdata);
+ CustomData_reset(&bm->edata);
+ CustomData_reset(&bm->ldata);
+ CustomData_reset(&bm->pdata);
}
/**
@@ -296,19 +305,18 @@ void BM_mesh_clear(BMesh *bm)
*/
void BM_mesh_free(BMesh *bm)
{
- BM_mesh_data_free(bm);
+ BM_mesh_data_free(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. */
- bpy_bm_generic_invalidate(bm->py_handle);
- bm->py_handle = NULL;
- }
+ 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. */
+ bpy_bm_generic_invalidate(bm->py_handle);
+ bm->py_handle = NULL;
+ }
- MEM_freeN(bm);
+ MEM_freeN(bm);
}
-
/**
* Helpers for #BM_mesh_normals_update and #BM_verts_calc_normal_vcos
*/
@@ -317,166 +325,170 @@ void BM_mesh_free(BMesh *bm)
#define BM_LNORSPACE_UPDATE _FLAG_MF
typedef struct BMEdgesCalcVectorsData {
- /* Read-only data. */
- const float (*vcos)[3];
+ /* Read-only data. */
+ const float (*vcos)[3];
- /* Read-write data, but no need to protect it, no concurrency to fear here. */
- float (*edgevec)[3];
+ /* Read-write data, but no need to protect it, no concurrency to fear here. */
+ float (*edgevec)[3];
} BMEdgesCalcVectorsData;
-
static void mesh_edges_calc_vectors_cb(void *userdata, MempoolIterData *mp_e)
{
- BMEdgesCalcVectorsData *data = userdata;
- BMEdge *e = (BMEdge *)mp_e;
-
- if (e->l) {
- const float *v1_co = data->vcos ? data->vcos[BM_elem_index_get(e->v1)] : e->v1->co;
- const float *v2_co = data->vcos ? data->vcos[BM_elem_index_get(e->v2)] : e->v2->co;
- sub_v3_v3v3(data->edgevec[BM_elem_index_get(e)], v2_co, v1_co);
- normalize_v3(data->edgevec[BM_elem_index_get(e)]);
- }
- else {
- /* the edge vector will not be needed when the edge has no radial */
- }
+ BMEdgesCalcVectorsData *data = userdata;
+ BMEdge *e = (BMEdge *)mp_e;
+
+ if (e->l) {
+ const float *v1_co = data->vcos ? data->vcos[BM_elem_index_get(e->v1)] : e->v1->co;
+ const float *v2_co = data->vcos ? data->vcos[BM_elem_index_get(e->v2)] : e->v2->co;
+ sub_v3_v3v3(data->edgevec[BM_elem_index_get(e)], v2_co, v1_co);
+ normalize_v3(data->edgevec[BM_elem_index_get(e)]);
+ }
+ else {
+ /* the edge vector will not be needed when the edge has no radial */
+ }
}
static void bm_mesh_edges_calc_vectors(BMesh *bm, float (*edgevec)[3], const float (*vcos)[3])
{
- BM_mesh_elem_index_ensure(bm, BM_EDGE | (vcos ? BM_VERT : 0));
+ BM_mesh_elem_index_ensure(bm, BM_EDGE | (vcos ? BM_VERT : 0));
- BMEdgesCalcVectorsData data = {
- .vcos = vcos,
- .edgevec = edgevec,
- };
+ BMEdgesCalcVectorsData data = {
+ .vcos = vcos,
+ .edgevec = edgevec,
+ };
- BM_iter_parallel(bm, BM_EDGES_OF_MESH, mesh_edges_calc_vectors_cb, &data, bm->totedge >= BM_OMP_LIMIT);
+ BM_iter_parallel(
+ bm, BM_EDGES_OF_MESH, mesh_edges_calc_vectors_cb, &data, bm->totedge >= BM_OMP_LIMIT);
}
-
typedef struct BMVertsCalcNormalsData {
- /* Read-only data. */
- const float (*fnos)[3];
- const float (*edgevec)[3];
- const float (*vcos)[3];
+ /* Read-only data. */
+ const float (*fnos)[3];
+ const float (*edgevec)[3];
+ const float (*vcos)[3];
- /* Read-write data, protected by an atomic-based fake spinlock-like system... */
- float (*vnos)[3];
+ /* Read-write data, protected by an atomic-based fake spinlock-like system... */
+ float (*vnos)[3];
} BMVertsCalcNormalsData;
static void mesh_verts_calc_normals_accum_cb(void *userdata, MempoolIterData *mp_f)
{
#define FLT_EQ_NONAN(_fa, _fb) (*((const uint32_t *)&_fa) == *((const uint32_t *)&_fb))
- BMVertsCalcNormalsData *data = userdata;
- BMFace *f = (BMFace *)mp_f;
-
- const float *f_no = data->fnos ? data->fnos[BM_elem_index_get(f)] : f->no;
-
- BMLoop *l_first, *l_iter;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- const float *e1diff, *e2diff;
- float dotprod;
- float fac;
-
- /* calculate the dot product of the two edges that
- * meet at the loop's vertex */
- e1diff = data->edgevec[BM_elem_index_get(l_iter->prev->e)];
- e2diff = data->edgevec[BM_elem_index_get(l_iter->e)];
- dotprod = dot_v3v3(e1diff, e2diff);
-
- /* edge vectors are calculated from e->v1 to e->v2, so
- * adjust the dot product if one but not both loops
- * actually runs from from e->v2 to e->v1 */
- if ((l_iter->prev->e->v1 == l_iter->prev->v) ^ (l_iter->e->v1 == l_iter->v)) {
- dotprod = -dotprod;
- }
-
- fac = saacos(-dotprod);
-
- if (fac != fac) { /* NAN detection. */
- /* Degenerated case, nothing to do here, just ignore that vertex. */
- continue;
- }
-
- /* accumulate weighted face normal into the vertex's normal */
- float *v_no = data->vnos ? data->vnos[BM_elem_index_get(l_iter->v)] : l_iter->v->no;
-
- /* This block is a lockless threadsafe madd_v3_v3fl.
- * It uses the first float of the vector as a sort of cheap spinlock,
- * assuming FLT_MAX is a safe 'illegal' value that cannot be set here otherwise.
- * It also assumes that collisions between threads are highly unlikely,
- * else performances would be quite bad here. */
- float virtual_lock = v_no[0];
- while (true) {
- /* This loops until following conditions are met:
- * - v_no[0] has same value as virtual_lock (i.e. it did not change since last try).
- * - v_no[0] was not FLT_MAX, i.e. it was not locked by another thread.
- */
- const float vl = atomic_cas_float(&v_no[0], virtual_lock, FLT_MAX);
- if (FLT_EQ_NONAN(vl, virtual_lock) && vl != FLT_MAX) {
- break;
- }
- virtual_lock = vl;
- }
- BLI_assert(v_no[0] == FLT_MAX);
- /* Now we own that normal value, and can change it.
- * But first scalar of the vector must not be changed yet, it's our lock! */
- virtual_lock += f_no[0] * fac;
- v_no[1] += f_no[1] * fac;
- v_no[2] += f_no[2] * fac;
- /* Second atomic operation to 'release' our lock on that vector and set its first scalar value. */
- /* Note that we do not need to loop here, since we 'locked' v_no[0],
- * nobody should have changed it in the mean time. */
- virtual_lock = atomic_cas_float(&v_no[0], FLT_MAX, virtual_lock);
- BLI_assert(virtual_lock == FLT_MAX);
-
- } while ((l_iter = l_iter->next) != l_first);
+ BMVertsCalcNormalsData *data = userdata;
+ BMFace *f = (BMFace *)mp_f;
+
+ const float *f_no = data->fnos ? data->fnos[BM_elem_index_get(f)] : f->no;
+
+ BMLoop *l_first, *l_iter;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ const float *e1diff, *e2diff;
+ float dotprod;
+ float fac;
+
+ /* calculate the dot product of the two edges that
+ * meet at the loop's vertex */
+ e1diff = data->edgevec[BM_elem_index_get(l_iter->prev->e)];
+ e2diff = data->edgevec[BM_elem_index_get(l_iter->e)];
+ dotprod = dot_v3v3(e1diff, e2diff);
+
+ /* edge vectors are calculated from e->v1 to e->v2, so
+ * adjust the dot product if one but not both loops
+ * actually runs from from e->v2 to e->v1 */
+ if ((l_iter->prev->e->v1 == l_iter->prev->v) ^ (l_iter->e->v1 == l_iter->v)) {
+ dotprod = -dotprod;
+ }
+
+ fac = saacos(-dotprod);
+
+ if (fac != fac) { /* NAN detection. */
+ /* Degenerated case, nothing to do here, just ignore that vertex. */
+ continue;
+ }
+
+ /* accumulate weighted face normal into the vertex's normal */
+ float *v_no = data->vnos ? data->vnos[BM_elem_index_get(l_iter->v)] : l_iter->v->no;
+
+ /* This block is a lockless threadsafe madd_v3_v3fl.
+ * It uses the first float of the vector as a sort of cheap spinlock,
+ * assuming FLT_MAX is a safe 'illegal' value that cannot be set here otherwise.
+ * It also assumes that collisions between threads are highly unlikely,
+ * else performances would be quite bad here. */
+ float virtual_lock = v_no[0];
+ while (true) {
+ /* This loops until following conditions are met:
+ * - v_no[0] has same value as virtual_lock (i.e. it did not change since last try).
+ * - v_no[0] was not FLT_MAX, i.e. it was not locked by another thread.
+ */
+ const float vl = atomic_cas_float(&v_no[0], virtual_lock, FLT_MAX);
+ if (FLT_EQ_NONAN(vl, virtual_lock) && vl != FLT_MAX) {
+ break;
+ }
+ virtual_lock = vl;
+ }
+ BLI_assert(v_no[0] == FLT_MAX);
+ /* Now we own that normal value, and can change it.
+ * But first scalar of the vector must not be changed yet, it's our lock! */
+ virtual_lock += f_no[0] * fac;
+ v_no[1] += f_no[1] * fac;
+ v_no[2] += f_no[2] * fac;
+ /* Second atomic operation to 'release' our lock on that vector and set its first scalar value. */
+ /* Note that we do not need to loop here, since we 'locked' v_no[0],
+ * nobody should have changed it in the mean time. */
+ virtual_lock = atomic_cas_float(&v_no[0], FLT_MAX, virtual_lock);
+ BLI_assert(virtual_lock == FLT_MAX);
+
+ } while ((l_iter = l_iter->next) != l_first);
#undef FLT_EQ_NONAN
}
static void mesh_verts_calc_normals_normalize_cb(void *userdata, MempoolIterData *mp_v)
{
- BMVertsCalcNormalsData *data = userdata;
- BMVert *v = (BMVert *)mp_v;
-
- float *v_no = data->vnos ? data->vnos[BM_elem_index_get(v)] : v->no;
- if (UNLIKELY(normalize_v3(v_no) == 0.0f)) {
- const float *v_co = data->vcos ? data->vcos[BM_elem_index_get(v)] : v->co;
- normalize_v3_v3(v_no, v_co);
- }
+ BMVertsCalcNormalsData *data = userdata;
+ BMVert *v = (BMVert *)mp_v;
+
+ float *v_no = data->vnos ? data->vnos[BM_elem_index_get(v)] : v->no;
+ if (UNLIKELY(normalize_v3(v_no) == 0.0f)) {
+ const float *v_co = data->vcos ? data->vcos[BM_elem_index_get(v)] : v->co;
+ normalize_v3_v3(v_no, v_co);
+ }
}
-static void bm_mesh_verts_calc_normals(
- BMesh *bm, const float (*edgevec)[3], const float (*fnos)[3],
- const float (*vcos)[3], float (*vnos)[3])
+static void bm_mesh_verts_calc_normals(BMesh *bm,
+ const float (*edgevec)[3],
+ const float (*fnos)[3],
+ const float (*vcos)[3],
+ float (*vnos)[3])
{
- BM_mesh_elem_index_ensure(bm, (BM_EDGE | BM_FACE) | ((vnos || vcos) ? BM_VERT : 0));
-
- BMVertsCalcNormalsData data = {
- .fnos = fnos,
- .edgevec = edgevec,
- .vcos = vcos,
- .vnos = vnos,
- };
-
- BM_iter_parallel(bm, BM_FACES_OF_MESH, mesh_verts_calc_normals_accum_cb, &data, bm->totface >= BM_OMP_LIMIT);
-
- /* normalize the accumulated vertex normals */
- BM_iter_parallel(bm, BM_VERTS_OF_MESH, mesh_verts_calc_normals_normalize_cb, &data, bm->totvert >= BM_OMP_LIMIT);
+ BM_mesh_elem_index_ensure(bm, (BM_EDGE | BM_FACE) | ((vnos || vcos) ? BM_VERT : 0));
+
+ BMVertsCalcNormalsData data = {
+ .fnos = fnos,
+ .edgevec = edgevec,
+ .vcos = vcos,
+ .vnos = vnos,
+ };
+
+ BM_iter_parallel(
+ bm, BM_FACES_OF_MESH, mesh_verts_calc_normals_accum_cb, &data, bm->totface >= BM_OMP_LIMIT);
+
+ /* normalize the accumulated vertex normals */
+ BM_iter_parallel(bm,
+ BM_VERTS_OF_MESH,
+ mesh_verts_calc_normals_normalize_cb,
+ &data,
+ bm->totvert >= BM_OMP_LIMIT);
}
-
static void mesh_faces_calc_normals_cb(void *UNUSED(userdata), MempoolIterData *mp_f)
{
- BMFace *f = (BMFace *)mp_f;
+ BMFace *f = (BMFace *)mp_f;
- BM_face_normal_update(f);
+ BM_face_normal_update(f);
}
-
/**
* \brief BMesh Compute Normals
*
@@ -484,33 +496,34 @@ static void mesh_faces_calc_normals_cb(void *UNUSED(userdata), MempoolIterData *
*/
void BM_mesh_normals_update(BMesh *bm)
{
- float (*edgevec)[3] = MEM_mallocN(sizeof(*edgevec) * bm->totedge, __func__);
-
- /* Parallel mempool iteration does not allow to generate indices inline anymore... */
- BM_mesh_elem_index_ensure(bm, (BM_EDGE | BM_FACE));
-
- /* calculate all face normals */
- BM_iter_parallel(bm, BM_FACES_OF_MESH, mesh_faces_calc_normals_cb, NULL, bm->totface >= BM_OMP_LIMIT);
-
- /* Zero out vertex normals */
- BMIter viter;
- BMVert *v;
- int i;
-
- BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
- BM_elem_index_set(v, i); /* set_inline */
- zero_v3(v->no);
- }
- bm->elem_index_dirty &= ~BM_VERT;
-
- /* Compute normalized direction vectors for each edge.
- * Directions will be used for calculating the weights of the face normals on the vertex normals.
- */
- bm_mesh_edges_calc_vectors(bm, edgevec, NULL);
-
- /* Add weighted face normals to vertices, and normalize vert normals. */
- bm_mesh_verts_calc_normals(bm, (const float(*)[3])edgevec, NULL, NULL, NULL);
- MEM_freeN(edgevec);
+ float(*edgevec)[3] = MEM_mallocN(sizeof(*edgevec) * bm->totedge, __func__);
+
+ /* Parallel mempool iteration does not allow to generate indices inline anymore... */
+ BM_mesh_elem_index_ensure(bm, (BM_EDGE | BM_FACE));
+
+ /* calculate all face normals */
+ BM_iter_parallel(
+ bm, BM_FACES_OF_MESH, mesh_faces_calc_normals_cb, NULL, bm->totface >= BM_OMP_LIMIT);
+
+ /* Zero out vertex normals */
+ BMIter viter;
+ BMVert *v;
+ int i;
+
+ BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
+ BM_elem_index_set(v, i); /* set_inline */
+ zero_v3(v->no);
+ }
+ bm->elem_index_dirty &= ~BM_VERT;
+
+ /* Compute normalized direction vectors for each edge.
+ * Directions will be used for calculating the weights of the face normals on the vertex normals.
+ */
+ bm_mesh_edges_calc_vectors(bm, edgevec, NULL);
+
+ /* Add weighted face normals to vertices, and normalize vert normals. */
+ bm_mesh_verts_calc_normals(bm, (const float(*)[3])edgevec, NULL, NULL, NULL);
+ MEM_freeN(edgevec);
}
/**
@@ -518,95 +531,97 @@ void BM_mesh_normals_update(BMesh *bm)
*
* Computes the vertex normals of a mesh into vnos, using given vertex coordinates (vcos) and polygon normals (fnos).
*/
-void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (*vcos)[3], float (*vnos)[3])
+void BM_verts_calc_normal_vcos(BMesh *bm,
+ const float (*fnos)[3],
+ const float (*vcos)[3],
+ float (*vnos)[3])
{
- float (*edgevec)[3] = MEM_mallocN(sizeof(*edgevec) * bm->totedge, __func__);
+ float(*edgevec)[3] = MEM_mallocN(sizeof(*edgevec) * bm->totedge, __func__);
- /* Compute normalized direction vectors for each edge.
- * Directions will be used for calculating the weights of the face normals on the vertex normals.
- */
- bm_mesh_edges_calc_vectors(bm, edgevec, vcos);
+ /* Compute normalized direction vectors for each edge.
+ * Directions will be used for calculating the weights of the face normals on the vertex normals.
+ */
+ bm_mesh_edges_calc_vectors(bm, edgevec, vcos);
- /* Add weighted face normals to vertices, and normalize vert normals. */
- bm_mesh_verts_calc_normals(bm, (const float(*)[3])edgevec, fnos, vcos, vnos);
- MEM_freeN(edgevec);
+ /* Add weighted face normals to vertices, and normalize vert normals. */
+ bm_mesh_verts_calc_normals(bm, (const float(*)[3])edgevec, fnos, vcos, vnos);
+ MEM_freeN(edgevec);
}
/**
* Helpers for #BM_mesh_loop_normals_update and #BM_loops_calc_normal_vcos
*/
-static void bm_mesh_edges_sharp_tag(
- BMesh *bm,
- const float (*vnos)[3], const float (*fnos)[3], float (*r_lnos)[3],
- const float split_angle, const bool do_sharp_edges_tag)
+static void bm_mesh_edges_sharp_tag(BMesh *bm,
+ const float (*vnos)[3],
+ const float (*fnos)[3],
+ float (*r_lnos)[3],
+ const float split_angle,
+ const bool do_sharp_edges_tag)
{
- BMIter eiter;
- BMEdge *e;
- int i;
-
- const bool check_angle = (split_angle < (float)M_PI);
- const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f;
-
- {
- char htype = BM_VERT | BM_LOOP;
- if (fnos) {
- htype |= BM_FACE;
- }
- BM_mesh_elem_index_ensure(bm, htype);
- }
-
- /* This first loop checks which edges are actually smooth, and pre-populate lnos with vnos (as if they were
- * all smooth).
- */
- BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, i) {
- BMLoop *l_a, *l_b;
-
- BM_elem_index_set(e, i); /* set_inline */
- BM_elem_flag_disable(e, BM_ELEM_TAG); /* Clear tag (means edge is sharp). */
-
- /* An edge with only two loops, might be smooth... */
- if (BM_edge_loop_pair(e, &l_a, &l_b)) {
- bool is_angle_smooth = true;
- if (check_angle) {
- const float *no_a = fnos ? fnos[BM_elem_index_get(l_a->f)] : l_a->f->no;
- const float *no_b = fnos ? fnos[BM_elem_index_get(l_b->f)] : l_b->f->no;
- is_angle_smooth = (dot_v3v3(no_a, no_b) >= split_angle_cos);
- }
-
- /* We only tag edges that are *really* smooth:
- * If the angle between both its polys' normals is below split_angle value,
- * and it is tagged as such,
- * and both its faces are smooth,
- * and both its faces have compatible (non-flipped) normals,
- * i.e. both loops on the same edge do not share the same vertex.
- */
- if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) &&
- BM_elem_flag_test(l_a->f, BM_ELEM_SMOOTH) &&
- BM_elem_flag_test(l_b->f, BM_ELEM_SMOOTH) &&
- l_a->v != l_b->v)
- {
- if (is_angle_smooth) {
- const float *no;
- BM_elem_flag_enable(e, BM_ELEM_TAG);
-
- /* linked vertices might be fully smooth, copy their normals to loop ones. */
- if (r_lnos) {
- no = vnos ? vnos[BM_elem_index_get(l_a->v)] : l_a->v->no;
- copy_v3_v3(r_lnos[BM_elem_index_get(l_a)], no);
- no = vnos ? vnos[BM_elem_index_get(l_b->v)] : l_b->v->no;
- copy_v3_v3(r_lnos[BM_elem_index_get(l_b)], no);
- }
- }
- else if (do_sharp_edges_tag) {
- /* Note that we do not care about the other sharp-edge cases (sharp poly, non-manifold edge, etc.),
- * only tag edge as sharp when it is due to angle threashold. */
- BM_elem_flag_disable(e, BM_ELEM_SMOOTH);
- }
- }
- }
- }
-
- bm->elem_index_dirty &= ~BM_EDGE;
+ BMIter eiter;
+ BMEdge *e;
+ int i;
+
+ const bool check_angle = (split_angle < (float)M_PI);
+ const float split_angle_cos = check_angle ? cosf(split_angle) : -1.0f;
+
+ {
+ char htype = BM_VERT | BM_LOOP;
+ if (fnos) {
+ htype |= BM_FACE;
+ }
+ BM_mesh_elem_index_ensure(bm, htype);
+ }
+
+ /* This first loop checks which edges are actually smooth, and pre-populate lnos with vnos (as if they were
+ * all smooth).
+ */
+ BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, i) {
+ BMLoop *l_a, *l_b;
+
+ BM_elem_index_set(e, i); /* set_inline */
+ BM_elem_flag_disable(e, BM_ELEM_TAG); /* Clear tag (means edge is sharp). */
+
+ /* An edge with only two loops, might be smooth... */
+ if (BM_edge_loop_pair(e, &l_a, &l_b)) {
+ bool is_angle_smooth = true;
+ if (check_angle) {
+ const float *no_a = fnos ? fnos[BM_elem_index_get(l_a->f)] : l_a->f->no;
+ const float *no_b = fnos ? fnos[BM_elem_index_get(l_b->f)] : l_b->f->no;
+ is_angle_smooth = (dot_v3v3(no_a, no_b) >= split_angle_cos);
+ }
+
+ /* We only tag edges that are *really* smooth:
+ * If the angle between both its polys' normals is below split_angle value,
+ * and it is tagged as such,
+ * and both its faces are smooth,
+ * and both its faces have compatible (non-flipped) normals,
+ * i.e. both loops on the same edge do not share the same vertex.
+ */
+ if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && BM_elem_flag_test(l_a->f, BM_ELEM_SMOOTH) &&
+ BM_elem_flag_test(l_b->f, BM_ELEM_SMOOTH) && l_a->v != l_b->v) {
+ if (is_angle_smooth) {
+ const float *no;
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+
+ /* linked vertices might be fully smooth, copy their normals to loop ones. */
+ if (r_lnos) {
+ no = vnos ? vnos[BM_elem_index_get(l_a->v)] : l_a->v->no;
+ copy_v3_v3(r_lnos[BM_elem_index_get(l_a)], no);
+ no = vnos ? vnos[BM_elem_index_get(l_b->v)] : l_b->v->no;
+ copy_v3_v3(r_lnos[BM_elem_index_get(l_b)], no);
+ }
+ }
+ else if (do_sharp_edges_tag) {
+ /* Note that we do not care about the other sharp-edge cases (sharp poly, non-manifold edge, etc.),
+ * only tag edge as sharp when it is due to angle threashold. */
+ BM_elem_flag_disable(e, BM_ELEM_SMOOTH);
+ }
+ }
+ }
+ }
+
+ bm->elem_index_dirty &= ~BM_EDGE;
}
/**
@@ -615,389 +630,396 @@ static void bm_mesh_edges_sharp_tag(
*/
bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr)
{
- BMLoop *lfan_pivot_next = l_curr;
- BMEdge *e_next = l_curr->e;
-
- BLI_assert(!BM_elem_flag_test(lfan_pivot_next, BM_ELEM_TAG));
- BM_elem_flag_enable(lfan_pivot_next, BM_ELEM_TAG);
-
- while (true) {
- /* Much simpler than in sibling code with basic Mesh data! */
- lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot_next, &e_next);
-
- if (!lfan_pivot_next || !BM_elem_flag_test(e_next, BM_ELEM_TAG)) {
- /* Sharp loop/edge, so not a cyclic smooth fan... */
- return false;
- }
- /* Smooth loop/edge... */
- else if (BM_elem_flag_test(lfan_pivot_next, BM_ELEM_TAG)) {
- if (lfan_pivot_next == l_curr) {
- /* We walked around a whole cyclic smooth fan without finding any already-processed loop, means we can
- * use initial l_curr/l_prev edge as start for this smooth fan. */
- return true;
- }
- /* ... already checked in some previous looping, we can abort. */
- return false;
- }
- else {
- /* ... we can skip it in future, and keep checking the smooth fan. */
- BM_elem_flag_enable(lfan_pivot_next, BM_ELEM_TAG);
- }
- }
+ BMLoop *lfan_pivot_next = l_curr;
+ BMEdge *e_next = l_curr->e;
+
+ BLI_assert(!BM_elem_flag_test(lfan_pivot_next, BM_ELEM_TAG));
+ BM_elem_flag_enable(lfan_pivot_next, BM_ELEM_TAG);
+
+ while (true) {
+ /* Much simpler than in sibling code with basic Mesh data! */
+ lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot_next, &e_next);
+
+ if (!lfan_pivot_next || !BM_elem_flag_test(e_next, BM_ELEM_TAG)) {
+ /* Sharp loop/edge, so not a cyclic smooth fan... */
+ return false;
+ }
+ /* Smooth loop/edge... */
+ else if (BM_elem_flag_test(lfan_pivot_next, BM_ELEM_TAG)) {
+ if (lfan_pivot_next == l_curr) {
+ /* We walked around a whole cyclic smooth fan without finding any already-processed loop, means we can
+ * use initial l_curr/l_prev edge as start for this smooth fan. */
+ return true;
+ }
+ /* ... already checked in some previous looping, we can abort. */
+ return false;
+ }
+ else {
+ /* ... we can skip it in future, and keep checking the smooth fan. */
+ BM_elem_flag_enable(lfan_pivot_next, BM_ELEM_TAG);
+ }
+ }
}
/* BMesh version of BKE_mesh_normals_loop_split() in mesh_evaluate.c
* Will use first clnors_data array, and fallback to cd_loop_clnors_offset (use NULL and -1 to not use clnors). */
-static void bm_mesh_loops_calc_normals(
- BMesh *bm, const float (*vcos)[3], const float (*fnos)[3], float (*r_lnos)[3],
- MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2],
- const int cd_loop_clnors_offset, const bool do_rebuild)
+static void bm_mesh_loops_calc_normals(BMesh *bm,
+ const float (*vcos)[3],
+ const float (*fnos)[3],
+ float (*r_lnos)[3],
+ MLoopNorSpaceArray *r_lnors_spacearr,
+ short (*clnors_data)[2],
+ const int cd_loop_clnors_offset,
+ const bool do_rebuild)
{
- BMIter fiter;
- BMFace *f_curr;
- const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
-
- MLoopNorSpaceArray _lnors_spacearr = {NULL};
-
- /* Temp normal stack. */
- BLI_SMALLSTACK_DECLARE(normal, float *);
- /* Temp clnors stack. */
- BLI_SMALLSTACK_DECLARE(clnors, short *);
- /* Temp edge vectors stack, only used when computing lnor spacearr. */
- BLI_Stack *edge_vectors = NULL;
-
- {
- char htype = 0;
- if (vcos) {
- htype |= BM_VERT;
- }
- /* Face/Loop indices are set inline below. */
- BM_mesh_elem_index_ensure(bm, htype);
- }
-
- if (!r_lnors_spacearr && has_clnors) {
- /* We need to compute lnor spacearr if some custom lnor data are given to us! */
- r_lnors_spacearr = &_lnors_spacearr;
- }
- if (r_lnors_spacearr) {
- BKE_lnor_spacearr_init(r_lnors_spacearr, bm->totloop, MLNOR_SPACEARR_BMLOOP_PTR);
- edge_vectors = BLI_stack_new(sizeof(float[3]), __func__);
- }
-
- /* Clear all loops' tags (means none are to be skipped for now). */
- int index_face, index_loop = 0;
- BM_ITER_MESH_INDEX (f_curr, &fiter, bm, BM_FACES_OF_MESH, index_face) {
- BMLoop *l_curr, *l_first;
-
- BM_elem_index_set(f_curr, index_face); /* set_inline */
-
- l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
- do {
- BM_elem_index_set(l_curr, index_loop++); /* set_inline */
- BM_elem_flag_disable(l_curr, BM_ELEM_TAG);
- } while ((l_curr = l_curr->next) != l_first);
- }
- bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
-
- /* We now know edges that can be smoothed (they are tagged), and edges that will be hard (they aren't).
- * Now, time to generate the normals.
- */
- BM_ITER_MESH (f_curr, &fiter, bm, BM_FACES_OF_MESH) {
- BMLoop *l_curr, *l_first;
-
- l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
- do {
- if (do_rebuild && !BM_ELEM_API_FLAG_TEST(l_curr, BM_LNORSPACE_UPDATE) &&
- !(bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL))
- {
- continue;
- }
- /* A smooth edge, we have to check for cyclic smooth fan case.
- * If we find a new, never-processed cyclic smooth fan, we can do it now using that loop/edge as
- * 'entry point', otherwise we can skip it. */
- /* Note: In theory, we could make bm_mesh_loop_check_cyclic_smooth_fan() store mlfan_pivot's in a stack,
- * to avoid having to fan again around the vert during actual computation of clnor & clnorspace.
- * However, this would complicate the code, add more memory usage, and BM_vert_step_fan_loop()
- * is quite cheap in term of CPU cycles, so really think it's not worth it. */
- if (BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) &&
- (BM_elem_flag_test(l_curr, BM_ELEM_TAG) || !BM_loop_check_cyclic_smooth_fan(l_curr)))
- {
- }
- else if (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) &&
- !BM_elem_flag_test(l_curr->prev->e, BM_ELEM_TAG))
- {
- /* Simple case (both edges around that vertex are sharp in related polygon),
- * this vertex just takes its poly normal.
- */
- const int l_curr_index = BM_elem_index_get(l_curr);
- const float *no = fnos ? fnos[BM_elem_index_get(f_curr)] : f_curr->no;
- copy_v3_v3(r_lnos[l_curr_index], no);
-
- /* If needed, generate this (simple!) lnor space. */
- if (r_lnors_spacearr) {
- float vec_curr[3], vec_prev[3];
- MLoopNorSpace *lnor_space = BKE_lnor_space_create(r_lnors_spacearr);
-
- {
- const BMVert *v_pivot = l_curr->v;
- const float *co_pivot = vcos ? vcos[BM_elem_index_get(v_pivot)] : v_pivot->co;
- const BMVert *v_1 = BM_edge_other_vert(l_curr->e, v_pivot);
- const float *co_1 = vcos ? vcos[BM_elem_index_get(v_1)] : v_1->co;
- const BMVert *v_2 = BM_edge_other_vert(l_curr->prev->e, v_pivot);
- const float *co_2 = vcos ? vcos[BM_elem_index_get(v_2)] : v_2->co;
-
- sub_v3_v3v3(vec_curr, co_1, co_pivot);
- normalize_v3(vec_curr);
- sub_v3_v3v3(vec_prev, co_2, co_pivot);
- normalize_v3(vec_prev);
- }
-
- BKE_lnor_space_define(lnor_space, r_lnos[l_curr_index], vec_curr, vec_prev, NULL);
- /* We know there is only one loop in this space, no need to create a linklist in this case... */
- BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, l_curr_index, l_curr, true);
-
- if (has_clnors) {
- short (*clnor)[2] = clnors_data ? &clnors_data[l_curr_index] :
- BM_ELEM_CD_GET_VOID_P(l_curr, cd_loop_clnors_offset);
- BKE_lnor_space_custom_data_to_normal(lnor_space, *clnor, r_lnos[l_curr_index]);
- }
- }
- }
- /* We *do not need* to check/tag loops as already computed!
- * Due to the fact a loop only links to one of its two edges, a same fan *will never be walked more than
- * once!*
- * Since we consider edges having neighbor faces with inverted (flipped) normals as sharp, we are sure that
- * no fan will be skipped, even only considering the case (sharp curr_edge, smooth prev_edge), and not the
- * alternative (smooth curr_edge, sharp prev_edge).
- * All this due/thanks to link between normals and loop ordering.
- */
- else {
- /* We have to fan around current vertex, until we find the other non-smooth edge,
- * and accumulate face normals into the vertex!
- * Note in case this vertex has only one sharp edge, this is a waste because the normal is the same as
- * the vertex normal, but I do not see any easy way to detect that (would need to count number
- * of sharp edges per vertex, I doubt the additional memory usage would be worth it, especially as
- * it should not be a common case in real-life meshes anyway).
- */
- BMVert *v_pivot = l_curr->v;
- BMEdge *e_next;
- const BMEdge *e_org = l_curr->e;
- BMLoop *lfan_pivot, *lfan_pivot_next;
- int lfan_pivot_index;
- float lnor[3] = {0.0f, 0.0f, 0.0f};
- float vec_curr[3], vec_next[3], vec_org[3];
-
- /* We validate clnors data on the fly - cheapest way to do! */
- int clnors_avg[2] = {0, 0};
- short (*clnor_ref)[2] = NULL;
- int clnors_nbr = 0;
- bool clnors_invalid = false;
-
- const float *co_pivot = vcos ? vcos[BM_elem_index_get(v_pivot)] : v_pivot->co;
-
- MLoopNorSpace *lnor_space = r_lnors_spacearr ? BKE_lnor_space_create(r_lnors_spacearr) : NULL;
-
- BLI_assert((edge_vectors == NULL) || BLI_stack_is_empty(edge_vectors));
-
- lfan_pivot = l_curr;
- lfan_pivot_index = BM_elem_index_get(lfan_pivot);
- e_next = lfan_pivot->e; /* Current edge here, actually! */
-
- /* Only need to compute previous edge's vector once, then we can just reuse old current one! */
- {
- const BMVert *v_2 = BM_edge_other_vert(e_next, v_pivot);
- const float *co_2 = vcos ? vcos[BM_elem_index_get(v_2)] : v_2->co;
-
- sub_v3_v3v3(vec_org, co_2, co_pivot);
- normalize_v3(vec_org);
- copy_v3_v3(vec_curr, vec_org);
-
- if (r_lnors_spacearr) {
- BLI_stack_push(edge_vectors, vec_org);
- }
- }
-
- while (true) {
- /* Much simpler than in sibling code with basic Mesh data! */
- lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next);
- if (lfan_pivot_next) {
- BLI_assert(lfan_pivot_next->v == v_pivot);
- }
- else {
- /* next edge is non-manifold, we have to find it ourselves! */
- e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e;
- }
-
- /* Compute edge vector.
- * NOTE: We could pre-compute those into an array, in the first iteration, instead of computing them
- * twice (or more) here. However, time gained is not worth memory and time lost,
- * given the fact that this code should not be called that much in real-life meshes...
- */
- {
- const BMVert *v_2 = BM_edge_other_vert(e_next, v_pivot);
- const float *co_2 = vcos ? vcos[BM_elem_index_get(v_2)] : v_2->co;
-
- sub_v3_v3v3(vec_next, co_2, co_pivot);
- normalize_v3(vec_next);
- }
-
- {
- /* Code similar to accumulate_vertex_normals_poly_v3. */
- /* Calculate angle between the two poly edges incident on this vertex. */
- const BMFace *f = lfan_pivot->f;
- const float fac = saacos(dot_v3v3(vec_next, vec_curr));
- const float *no = fnos ? fnos[BM_elem_index_get(f)] : f->no;
- /* Accumulate */
- madd_v3_v3fl(lnor, no, fac);
-
- if (has_clnors) {
- /* Accumulate all clnors, if they are not all equal we have to fix that! */
- short (*clnor)[2] = clnors_data ? &clnors_data[lfan_pivot_index] :
- BM_ELEM_CD_GET_VOID_P(lfan_pivot, cd_loop_clnors_offset);
- if (clnors_nbr) {
- clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] || (*clnor_ref)[1] != (*clnor)[1]);
- }
- else {
- clnor_ref = clnor;
- }
- clnors_avg[0] += (*clnor)[0];
- clnors_avg[1] += (*clnor)[1];
- clnors_nbr++;
- /* We store here a pointer to all custom lnors processed. */
- BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor);
- }
- }
-
- /* We store here a pointer to all loop-normals processed. */
- BLI_SMALLSTACK_PUSH(normal, (float *)r_lnos[lfan_pivot_index]);
-
- if (r_lnors_spacearr) {
- /* Assign current lnor space to current 'vertex' loop. */
- BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, lfan_pivot_index, lfan_pivot, false);
- if (e_next != e_org) {
- /* We store here all edges-normalized vectors processed. */
- BLI_stack_push(edge_vectors, vec_next);
- }
- }
-
- if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) {
- /* Next edge is sharp, we have finished with this fan of faces around this vert! */
- break;
- }
-
- /* Copy next edge vector to current one. */
- copy_v3_v3(vec_curr, vec_next);
- /* Next pivot loop to current one. */
- lfan_pivot = lfan_pivot_next;
- lfan_pivot_index = BM_elem_index_get(lfan_pivot);
- }
-
- {
- float lnor_len = normalize_v3(lnor);
-
- /* If we are generating lnor spacearr, we can now define the one for this fan. */
- if (r_lnors_spacearr) {
- if (UNLIKELY(lnor_len == 0.0f)) {
- /* Use vertex normal as fallback! */
- copy_v3_v3(lnor, r_lnos[lfan_pivot_index]);
- lnor_len = 1.0f;
- }
-
- BKE_lnor_space_define(lnor_space, lnor, vec_org, vec_next, edge_vectors);
-
- if (has_clnors) {
- if (clnors_invalid) {
- short *clnor;
-
- clnors_avg[0] /= clnors_nbr;
- clnors_avg[1] /= clnors_nbr;
- /* Fix/update all clnors of this fan with computed average value. */
-
- /* Prints continuously when merge custom normals, so commenting. */
- /* printf("Invalid clnors in this fan!\n"); */
-
- while ((clnor = BLI_SMALLSTACK_POP(clnors))) {
- //print_v2("org clnor", clnor);
- clnor[0] = (short)clnors_avg[0];
- clnor[1] = (short)clnors_avg[1];
- }
- //print_v2("new clnors", clnors_avg);
- }
- else {
- /* We still have to consume the stack! */
- while (BLI_SMALLSTACK_POP(clnors)) {
- /* pass */
- }
- }
- BKE_lnor_space_custom_data_to_normal(lnor_space, *clnor_ref, lnor);
- }
- }
-
- /* In case we get a zero normal here, just use vertex normal already set! */
- if (LIKELY(lnor_len != 0.0f)) {
- /* Copy back the final computed normal into all related loop-normals. */
- float *nor;
-
- while ((nor = BLI_SMALLSTACK_POP(normal))) {
- copy_v3_v3(nor, lnor);
- }
- }
- else {
- /* We still have to consume the stack! */
- while (BLI_SMALLSTACK_POP(normal)) {
- /* pass */
- }
- }
- }
-
- /* Tag related vertex as sharp, to avoid fanning around it again (in case it was a smooth one). */
- if (r_lnors_spacearr) {
- BM_elem_flag_enable(l_curr->v, BM_ELEM_TAG);
- }
- }
- } while ((l_curr = l_curr->next) != l_first);
- }
-
- if (r_lnors_spacearr) {
- BLI_stack_free(edge_vectors);
- if (r_lnors_spacearr == &_lnors_spacearr) {
- BKE_lnor_spacearr_free(r_lnors_spacearr);
- }
- }
+ BMIter fiter;
+ BMFace *f_curr;
+ const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
+
+ MLoopNorSpaceArray _lnors_spacearr = {NULL};
+
+ /* Temp normal stack. */
+ BLI_SMALLSTACK_DECLARE(normal, float *);
+ /* Temp clnors stack. */
+ BLI_SMALLSTACK_DECLARE(clnors, short *);
+ /* Temp edge vectors stack, only used when computing lnor spacearr. */
+ BLI_Stack *edge_vectors = NULL;
+
+ {
+ char htype = 0;
+ if (vcos) {
+ htype |= BM_VERT;
+ }
+ /* Face/Loop indices are set inline below. */
+ BM_mesh_elem_index_ensure(bm, htype);
+ }
+
+ if (!r_lnors_spacearr && has_clnors) {
+ /* We need to compute lnor spacearr if some custom lnor data are given to us! */
+ r_lnors_spacearr = &_lnors_spacearr;
+ }
+ if (r_lnors_spacearr) {
+ BKE_lnor_spacearr_init(r_lnors_spacearr, bm->totloop, MLNOR_SPACEARR_BMLOOP_PTR);
+ edge_vectors = BLI_stack_new(sizeof(float[3]), __func__);
+ }
+
+ /* Clear all loops' tags (means none are to be skipped for now). */
+ int index_face, index_loop = 0;
+ BM_ITER_MESH_INDEX (f_curr, &fiter, bm, BM_FACES_OF_MESH, index_face) {
+ BMLoop *l_curr, *l_first;
+
+ BM_elem_index_set(f_curr, index_face); /* set_inline */
+
+ l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
+ do {
+ BM_elem_index_set(l_curr, index_loop++); /* set_inline */
+ BM_elem_flag_disable(l_curr, BM_ELEM_TAG);
+ } while ((l_curr = l_curr->next) != l_first);
+ }
+ bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
+
+ /* We now know edges that can be smoothed (they are tagged), and edges that will be hard (they aren't).
+ * Now, time to generate the normals.
+ */
+ BM_ITER_MESH (f_curr, &fiter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l_curr, *l_first;
+
+ l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
+ do {
+ if (do_rebuild && !BM_ELEM_API_FLAG_TEST(l_curr, BM_LNORSPACE_UPDATE) &&
+ !(bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL)) {
+ continue;
+ }
+ /* A smooth edge, we have to check for cyclic smooth fan case.
+ * If we find a new, never-processed cyclic smooth fan, we can do it now using that loop/edge as
+ * 'entry point', otherwise we can skip it. */
+ /* Note: In theory, we could make bm_mesh_loop_check_cyclic_smooth_fan() store mlfan_pivot's in a stack,
+ * to avoid having to fan again around the vert during actual computation of clnor & clnorspace.
+ * However, this would complicate the code, add more memory usage, and BM_vert_step_fan_loop()
+ * is quite cheap in term of CPU cycles, so really think it's not worth it. */
+ if (BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) &&
+ (BM_elem_flag_test(l_curr, BM_ELEM_TAG) || !BM_loop_check_cyclic_smooth_fan(l_curr))) {
+ }
+ else if (!BM_elem_flag_test(l_curr->e, BM_ELEM_TAG) &&
+ !BM_elem_flag_test(l_curr->prev->e, BM_ELEM_TAG)) {
+ /* Simple case (both edges around that vertex are sharp in related polygon),
+ * this vertex just takes its poly normal.
+ */
+ const int l_curr_index = BM_elem_index_get(l_curr);
+ const float *no = fnos ? fnos[BM_elem_index_get(f_curr)] : f_curr->no;
+ copy_v3_v3(r_lnos[l_curr_index], no);
+
+ /* If needed, generate this (simple!) lnor space. */
+ if (r_lnors_spacearr) {
+ float vec_curr[3], vec_prev[3];
+ MLoopNorSpace *lnor_space = BKE_lnor_space_create(r_lnors_spacearr);
+
+ {
+ const BMVert *v_pivot = l_curr->v;
+ const float *co_pivot = vcos ? vcos[BM_elem_index_get(v_pivot)] : v_pivot->co;
+ const BMVert *v_1 = BM_edge_other_vert(l_curr->e, v_pivot);
+ const float *co_1 = vcos ? vcos[BM_elem_index_get(v_1)] : v_1->co;
+ const BMVert *v_2 = BM_edge_other_vert(l_curr->prev->e, v_pivot);
+ const float *co_2 = vcos ? vcos[BM_elem_index_get(v_2)] : v_2->co;
+
+ sub_v3_v3v3(vec_curr, co_1, co_pivot);
+ normalize_v3(vec_curr);
+ sub_v3_v3v3(vec_prev, co_2, co_pivot);
+ normalize_v3(vec_prev);
+ }
+
+ BKE_lnor_space_define(lnor_space, r_lnos[l_curr_index], vec_curr, vec_prev, NULL);
+ /* We know there is only one loop in this space, no need to create a linklist in this case... */
+ BKE_lnor_space_add_loop(r_lnors_spacearr, lnor_space, l_curr_index, l_curr, true);
+
+ if (has_clnors) {
+ short(*clnor)[2] = clnors_data ? &clnors_data[l_curr_index] :
+ BM_ELEM_CD_GET_VOID_P(l_curr, cd_loop_clnors_offset);
+ BKE_lnor_space_custom_data_to_normal(lnor_space, *clnor, r_lnos[l_curr_index]);
+ }
+ }
+ }
+ /* We *do not need* to check/tag loops as already computed!
+ * Due to the fact a loop only links to one of its two edges, a same fan *will never be walked more than
+ * once!*
+ * Since we consider edges having neighbor faces with inverted (flipped) normals as sharp, we are sure that
+ * no fan will be skipped, even only considering the case (sharp curr_edge, smooth prev_edge), and not the
+ * alternative (smooth curr_edge, sharp prev_edge).
+ * All this due/thanks to link between normals and loop ordering.
+ */
+ else {
+ /* We have to fan around current vertex, until we find the other non-smooth edge,
+ * and accumulate face normals into the vertex!
+ * Note in case this vertex has only one sharp edge, this is a waste because the normal is the same as
+ * the vertex normal, but I do not see any easy way to detect that (would need to count number
+ * of sharp edges per vertex, I doubt the additional memory usage would be worth it, especially as
+ * it should not be a common case in real-life meshes anyway).
+ */
+ BMVert *v_pivot = l_curr->v;
+ BMEdge *e_next;
+ const BMEdge *e_org = l_curr->e;
+ BMLoop *lfan_pivot, *lfan_pivot_next;
+ int lfan_pivot_index;
+ float lnor[3] = {0.0f, 0.0f, 0.0f};
+ float vec_curr[3], vec_next[3], vec_org[3];
+
+ /* We validate clnors data on the fly - cheapest way to do! */
+ int clnors_avg[2] = {0, 0};
+ short(*clnor_ref)[2] = NULL;
+ int clnors_nbr = 0;
+ bool clnors_invalid = false;
+
+ const float *co_pivot = vcos ? vcos[BM_elem_index_get(v_pivot)] : v_pivot->co;
+
+ MLoopNorSpace *lnor_space = r_lnors_spacearr ? BKE_lnor_space_create(r_lnors_spacearr) :
+ NULL;
+
+ BLI_assert((edge_vectors == NULL) || BLI_stack_is_empty(edge_vectors));
+
+ lfan_pivot = l_curr;
+ lfan_pivot_index = BM_elem_index_get(lfan_pivot);
+ e_next = lfan_pivot->e; /* Current edge here, actually! */
+
+ /* Only need to compute previous edge's vector once, then we can just reuse old current one! */
+ {
+ const BMVert *v_2 = BM_edge_other_vert(e_next, v_pivot);
+ const float *co_2 = vcos ? vcos[BM_elem_index_get(v_2)] : v_2->co;
+
+ sub_v3_v3v3(vec_org, co_2, co_pivot);
+ normalize_v3(vec_org);
+ copy_v3_v3(vec_curr, vec_org);
+
+ if (r_lnors_spacearr) {
+ BLI_stack_push(edge_vectors, vec_org);
+ }
+ }
+
+ while (true) {
+ /* Much simpler than in sibling code with basic Mesh data! */
+ lfan_pivot_next = BM_vert_step_fan_loop(lfan_pivot, &e_next);
+ if (lfan_pivot_next) {
+ BLI_assert(lfan_pivot_next->v == v_pivot);
+ }
+ else {
+ /* next edge is non-manifold, we have to find it ourselves! */
+ e_next = (lfan_pivot->e == e_next) ? lfan_pivot->prev->e : lfan_pivot->e;
+ }
+
+ /* Compute edge vector.
+ * NOTE: We could pre-compute those into an array, in the first iteration, instead of computing them
+ * twice (or more) here. However, time gained is not worth memory and time lost,
+ * given the fact that this code should not be called that much in real-life meshes...
+ */
+ {
+ const BMVert *v_2 = BM_edge_other_vert(e_next, v_pivot);
+ const float *co_2 = vcos ? vcos[BM_elem_index_get(v_2)] : v_2->co;
+
+ sub_v3_v3v3(vec_next, co_2, co_pivot);
+ normalize_v3(vec_next);
+ }
+
+ {
+ /* Code similar to accumulate_vertex_normals_poly_v3. */
+ /* Calculate angle between the two poly edges incident on this vertex. */
+ const BMFace *f = lfan_pivot->f;
+ const float fac = saacos(dot_v3v3(vec_next, vec_curr));
+ const float *no = fnos ? fnos[BM_elem_index_get(f)] : f->no;
+ /* Accumulate */
+ madd_v3_v3fl(lnor, no, fac);
+
+ if (has_clnors) {
+ /* Accumulate all clnors, if they are not all equal we have to fix that! */
+ short(*clnor)[2] = clnors_data ?
+ &clnors_data[lfan_pivot_index] :
+ BM_ELEM_CD_GET_VOID_P(lfan_pivot, cd_loop_clnors_offset);
+ if (clnors_nbr) {
+ clnors_invalid |= ((*clnor_ref)[0] != (*clnor)[0] ||
+ (*clnor_ref)[1] != (*clnor)[1]);
+ }
+ else {
+ clnor_ref = clnor;
+ }
+ clnors_avg[0] += (*clnor)[0];
+ clnors_avg[1] += (*clnor)[1];
+ clnors_nbr++;
+ /* We store here a pointer to all custom lnors processed. */
+ BLI_SMALLSTACK_PUSH(clnors, (short *)*clnor);
+ }
+ }
+
+ /* We store here a pointer to all loop-normals processed. */
+ BLI_SMALLSTACK_PUSH(normal, (float *)r_lnos[lfan_pivot_index]);
+
+ if (r_lnors_spacearr) {
+ /* Assign current lnor space to current 'vertex' loop. */
+ BKE_lnor_space_add_loop(
+ r_lnors_spacearr, lnor_space, lfan_pivot_index, lfan_pivot, false);
+ if (e_next != e_org) {
+ /* We store here all edges-normalized vectors processed. */
+ BLI_stack_push(edge_vectors, vec_next);
+ }
+ }
+
+ if (!BM_elem_flag_test(e_next, BM_ELEM_TAG) || (e_next == e_org)) {
+ /* Next edge is sharp, we have finished with this fan of faces around this vert! */
+ break;
+ }
+
+ /* Copy next edge vector to current one. */
+ copy_v3_v3(vec_curr, vec_next);
+ /* Next pivot loop to current one. */
+ lfan_pivot = lfan_pivot_next;
+ lfan_pivot_index = BM_elem_index_get(lfan_pivot);
+ }
+
+ {
+ float lnor_len = normalize_v3(lnor);
+
+ /* If we are generating lnor spacearr, we can now define the one for this fan. */
+ if (r_lnors_spacearr) {
+ if (UNLIKELY(lnor_len == 0.0f)) {
+ /* Use vertex normal as fallback! */
+ copy_v3_v3(lnor, r_lnos[lfan_pivot_index]);
+ lnor_len = 1.0f;
+ }
+
+ BKE_lnor_space_define(lnor_space, lnor, vec_org, vec_next, edge_vectors);
+
+ if (has_clnors) {
+ if (clnors_invalid) {
+ short *clnor;
+
+ clnors_avg[0] /= clnors_nbr;
+ clnors_avg[1] /= clnors_nbr;
+ /* Fix/update all clnors of this fan with computed average value. */
+
+ /* Prints continuously when merge custom normals, so commenting. */
+ /* printf("Invalid clnors in this fan!\n"); */
+
+ while ((clnor = BLI_SMALLSTACK_POP(clnors))) {
+ //print_v2("org clnor", clnor);
+ clnor[0] = (short)clnors_avg[0];
+ clnor[1] = (short)clnors_avg[1];
+ }
+ //print_v2("new clnors", clnors_avg);
+ }
+ else {
+ /* We still have to consume the stack! */
+ while (BLI_SMALLSTACK_POP(clnors)) {
+ /* pass */
+ }
+ }
+ BKE_lnor_space_custom_data_to_normal(lnor_space, *clnor_ref, lnor);
+ }
+ }
+
+ /* In case we get a zero normal here, just use vertex normal already set! */
+ if (LIKELY(lnor_len != 0.0f)) {
+ /* Copy back the final computed normal into all related loop-normals. */
+ float *nor;
+
+ while ((nor = BLI_SMALLSTACK_POP(normal))) {
+ copy_v3_v3(nor, lnor);
+ }
+ }
+ else {
+ /* We still have to consume the stack! */
+ while (BLI_SMALLSTACK_POP(normal)) {
+ /* pass */
+ }
+ }
+ }
+
+ /* Tag related vertex as sharp, to avoid fanning around it again (in case it was a smooth one). */
+ if (r_lnors_spacearr) {
+ BM_elem_flag_enable(l_curr->v, BM_ELEM_TAG);
+ }
+ }
+ } while ((l_curr = l_curr->next) != l_first);
+ }
+
+ if (r_lnors_spacearr) {
+ BLI_stack_free(edge_vectors);
+ if (r_lnors_spacearr == &_lnors_spacearr) {
+ BKE_lnor_spacearr_free(r_lnors_spacearr);
+ }
+ }
}
-static void bm_mesh_loops_calc_normals_no_autosmooth(
- BMesh *bm, const float (*vnos)[3], const float (*fnos)[3], float (*r_lnos)[3])
+static void bm_mesh_loops_calc_normals_no_autosmooth(BMesh *bm,
+ const float (*vnos)[3],
+ const float (*fnos)[3],
+ float (*r_lnos)[3])
{
- BMIter fiter;
- BMFace *f_curr;
-
- {
- char htype = BM_LOOP;
- if (vnos) {
- htype |= BM_VERT;
- }
- if (fnos) {
- htype |= BM_FACE;
- }
- BM_mesh_elem_index_ensure(bm, htype);
- }
-
- BM_ITER_MESH (f_curr, &fiter, bm, BM_FACES_OF_MESH) {
- BMLoop *l_curr, *l_first;
- const bool is_face_flat = !BM_elem_flag_test(f_curr, BM_ELEM_SMOOTH);
-
- l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
- do {
- const float *no = is_face_flat ? (fnos ? fnos[BM_elem_index_get(f_curr)] : f_curr->no) :
- (vnos ? vnos[BM_elem_index_get(l_curr->v)] : l_curr->v->no);
- copy_v3_v3(r_lnos[BM_elem_index_get(l_curr)], no);
-
- } while ((l_curr = l_curr->next) != l_first);
- }
+ BMIter fiter;
+ BMFace *f_curr;
+
+ {
+ char htype = BM_LOOP;
+ if (vnos) {
+ htype |= BM_VERT;
+ }
+ if (fnos) {
+ htype |= BM_FACE;
+ }
+ BM_mesh_elem_index_ensure(bm, htype);
+ }
+
+ BM_ITER_MESH (f_curr, &fiter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l_curr, *l_first;
+ const bool is_face_flat = !BM_elem_flag_test(f_curr, BM_ELEM_SMOOTH);
+
+ l_curr = l_first = BM_FACE_FIRST_LOOP(f_curr);
+ do {
+ const float *no = is_face_flat ? (fnos ? fnos[BM_elem_index_get(f_curr)] : f_curr->no) :
+ (vnos ? vnos[BM_elem_index_get(l_curr->v)] : l_curr->v->no);
+ copy_v3_v3(r_lnos[BM_elem_index_get(l_curr)], no);
+
+ } while ((l_curr = l_curr->next) != l_first);
+ }
}
-#if 0 /* Unused currently */
+#if 0 /* Unused currently */
/**
* \brief BMesh Compute Loop Normals
*
@@ -1008,20 +1030,20 @@ void BM_mesh_loop_normals_update(
BMesh *bm, const bool use_split_normals, const float split_angle, float (*r_lnos)[3],
MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2], const int cd_loop_clnors_offset)
{
- const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
-
- if (use_split_normals) {
- /* Tag smooth edges and set lnos from vnos when they might be completely smooth...
- * When using custom loop normals, disable the angle feature! */
- bm_mesh_edges_sharp_tag(bm, NULL, NULL, has_clnors ? (float)M_PI : split_angle, r_lnos);
-
- /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
- bm_mesh_loops_calc_normals(bm, NULL, NULL, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset);
- }
- else {
- BLI_assert(!r_lnors_spacearr);
- bm_mesh_loops_calc_normals_no_autosmooth(bm, NULL, NULL, r_lnos);
- }
+ const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
+
+ if (use_split_normals) {
+ /* Tag smooth edges and set lnos from vnos when they might be completely smooth...
+ * When using custom loop normals, disable the angle feature! */
+ bm_mesh_edges_sharp_tag(bm, NULL, NULL, has_clnors ? (float)M_PI : split_angle, r_lnos);
+
+ /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
+ bm_mesh_loops_calc_normals(bm, NULL, NULL, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset);
+ }
+ else {
+ BLI_assert(!r_lnors_spacearr);
+ bm_mesh_loops_calc_normals_no_autosmooth(bm, NULL, NULL, r_lnos);
+ }
}
#endif
@@ -1031,27 +1053,33 @@ void BM_mesh_loop_normals_update(
* Compute split normals, i.e. vertex normals associated with each poly (hence 'loop normals').
* Useful to materialize sharp edges (or non-smooth faces) without actually modifying the geometry (splitting edges).
*/
-void BM_loops_calc_normal_vcos(
- BMesh *bm, const float (*vcos)[3], const float (*vnos)[3], const float (*fnos)[3],
- const bool use_split_normals, const float split_angle, float (*r_lnos)[3],
- MLoopNorSpaceArray *r_lnors_spacearr, short (*clnors_data)[2],
- const int cd_loop_clnors_offset, const bool do_rebuild)
+void BM_loops_calc_normal_vcos(BMesh *bm,
+ const float (*vcos)[3],
+ const float (*vnos)[3],
+ const float (*fnos)[3],
+ const bool use_split_normals,
+ const float split_angle,
+ float (*r_lnos)[3],
+ MLoopNorSpaceArray *r_lnors_spacearr,
+ short (*clnors_data)[2],
+ const int cd_loop_clnors_offset,
+ const bool do_rebuild)
{
- const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
-
- if (use_split_normals) {
- /* Tag smooth edges and set lnos from vnos when they might be completely smooth...
- * When using custom loop normals, disable the angle feature! */
- bm_mesh_edges_sharp_tag(bm, vnos, fnos, r_lnos, has_clnors ? (float)M_PI : split_angle, false);
-
- /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
- bm_mesh_loops_calc_normals(
- bm, vcos, fnos, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset, do_rebuild);
- }
- else {
- BLI_assert(!r_lnors_spacearr);
- bm_mesh_loops_calc_normals_no_autosmooth(bm, vnos, fnos, r_lnos);
- }
+ const bool has_clnors = clnors_data || (cd_loop_clnors_offset != -1);
+
+ if (use_split_normals) {
+ /* Tag smooth edges and set lnos from vnos when they might be completely smooth...
+ * When using custom loop normals, disable the angle feature! */
+ bm_mesh_edges_sharp_tag(bm, vnos, fnos, r_lnos, has_clnors ? (float)M_PI : split_angle, false);
+
+ /* Finish computing lnos by accumulating face normals in each fan of faces defined by sharp edges. */
+ bm_mesh_loops_calc_normals(
+ bm, vcos, fnos, r_lnos, r_lnors_spacearr, clnors_data, cd_loop_clnors_offset, do_rebuild);
+ }
+ else {
+ BLI_assert(!r_lnors_spacearr);
+ bm_mesh_loops_calc_normals_no_autosmooth(bm, vnos, fnos, r_lnos);
+ }
}
/** Define sharp edges as needed to mimic 'autosmooth' from angle threshold.
@@ -1060,215 +1088,232 @@ void BM_loops_calc_normal_vcos(
*/
void BM_edges_sharp_from_angle_set(BMesh *bm, const float split_angle)
{
- if (split_angle >= (float)M_PI) {
- /* Nothing to do! */
- return;
- }
+ if (split_angle >= (float)M_PI) {
+ /* Nothing to do! */
+ return;
+ }
- bm_mesh_edges_sharp_tag(bm, NULL, NULL, NULL, split_angle, true);
+ bm_mesh_edges_sharp_tag(bm, NULL, NULL, NULL, split_angle, true);
}
-void BM_lnorspacearr_store(BMesh *bm, float(*r_lnors)[3])
+void BM_lnorspacearr_store(BMesh *bm, float (*r_lnors)[3])
{
- BLI_assert(bm->lnor_spacearr != NULL);
-
- if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) {
- BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL);
- }
-
- int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
-
- BM_loops_calc_normal_vcos(
- bm, NULL, NULL, NULL, true, M_PI, r_lnors, bm->lnor_spacearr, NULL, cd_loop_clnors_offset, false);
- bm->spacearr_dirty &= ~(BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL);
+ BLI_assert(bm->lnor_spacearr != NULL);
+
+ if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) {
+ BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL);
+ }
+
+ int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+
+ BM_loops_calc_normal_vcos(bm,
+ NULL,
+ NULL,
+ NULL,
+ true,
+ M_PI,
+ r_lnors,
+ bm->lnor_spacearr,
+ NULL,
+ cd_loop_clnors_offset,
+ false);
+ bm->spacearr_dirty &= ~(BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL);
}
#define CLEAR_SPACEARRAY_THRESHOLD(x) ((x) / 2)
void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all)
{
- if (bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) {
- return;
- }
- if (do_invalidate_all || bm->totvertsel > CLEAR_SPACEARRAY_THRESHOLD(bm->totvert)) {
- bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
- return;
- }
- if (bm->lnor_spacearr == NULL) {
- bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
- return;
- }
-
- BMVert *v;
- BMLoop *l;
- BMIter viter, liter;
- /* Note: we could use temp tag of BMItem for that, but probably better not use it in such a low-level func?
- * --mont29 */
- BLI_bitmap *done_verts = BLI_BITMAP_NEW(bm->totvert, __func__);
-
- BM_mesh_elem_index_ensure(bm, BM_VERT);
-
- /* When we affect a given vertex, we may affect following smooth fans:
- * - all smooth fans of said vertex;
- * - all smooth fans of all immediate loop-neighbors vertices;
- * This can be simplified as 'all loops of selected vertices and their immediate neighbors'
- * need to be tagged for update.
- */
- BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
- BM_ELEM_API_FLAG_ENABLE(l, BM_LNORSPACE_UPDATE);
-
- /* Note that we only handle unselected neighbor vertices here, main loop will take care of
- * selected ones. */
- if ((!BM_elem_flag_test(l->prev->v, BM_ELEM_SELECT)) &&
- !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->prev->v)))
- {
-
- BMLoop *l_prev;
- BMIter liter_prev;
- BM_ITER_ELEM(l_prev, &liter_prev, l->prev->v, BM_LOOPS_OF_VERT) {
- BM_ELEM_API_FLAG_ENABLE(l_prev, BM_LNORSPACE_UPDATE);
- }
- BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(l_prev->v));
- }
-
- if ((!BM_elem_flag_test(l->next->v, BM_ELEM_SELECT)) &&
- !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->next->v)))
- {
-
- BMLoop *l_next;
- BMIter liter_next;
- BM_ITER_ELEM(l_next, &liter_next, l->next->v, BM_LOOPS_OF_VERT) {
- BM_ELEM_API_FLAG_ENABLE(l_next, BM_LNORSPACE_UPDATE);
- }
- BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(l_next->v));
- }
- }
-
- BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(v));
- }
- }
-
- MEM_freeN(done_verts);
- bm->spacearr_dirty |= BM_SPACEARR_DIRTY;
+ if (bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) {
+ return;
+ }
+ if (do_invalidate_all || bm->totvertsel > CLEAR_SPACEARRAY_THRESHOLD(bm->totvert)) {
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+ return;
+ }
+ if (bm->lnor_spacearr == NULL) {
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+ return;
+ }
+
+ BMVert *v;
+ BMLoop *l;
+ BMIter viter, liter;
+ /* Note: we could use temp tag of BMItem for that, but probably better not use it in such a low-level func?
+ * --mont29 */
+ BLI_bitmap *done_verts = BLI_BITMAP_NEW(bm->totvert, __func__);
+
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+
+ /* When we affect a given vertex, we may affect following smooth fans:
+ * - all smooth fans of said vertex;
+ * - all smooth fans of all immediate loop-neighbors vertices;
+ * This can be simplified as 'all loops of selected vertices and their immediate neighbors'
+ * need to be tagged for update.
+ */
+ BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ BM_ELEM_API_FLAG_ENABLE(l, BM_LNORSPACE_UPDATE);
+
+ /* Note that we only handle unselected neighbor vertices here, main loop will take care of
+ * selected ones. */
+ if ((!BM_elem_flag_test(l->prev->v, BM_ELEM_SELECT)) &&
+ !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->prev->v))) {
+
+ BMLoop *l_prev;
+ BMIter liter_prev;
+ BM_ITER_ELEM (l_prev, &liter_prev, l->prev->v, BM_LOOPS_OF_VERT) {
+ BM_ELEM_API_FLAG_ENABLE(l_prev, BM_LNORSPACE_UPDATE);
+ }
+ BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(l_prev->v));
+ }
+
+ if ((!BM_elem_flag_test(l->next->v, BM_ELEM_SELECT)) &&
+ !BLI_BITMAP_TEST(done_verts, BM_elem_index_get(l->next->v))) {
+
+ BMLoop *l_next;
+ BMIter liter_next;
+ BM_ITER_ELEM (l_next, &liter_next, l->next->v, BM_LOOPS_OF_VERT) {
+ BM_ELEM_API_FLAG_ENABLE(l_next, BM_LNORSPACE_UPDATE);
+ }
+ BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(l_next->v));
+ }
+ }
+
+ BLI_BITMAP_ENABLE(done_verts, BM_elem_index_get(v));
+ }
+ }
+
+ MEM_freeN(done_verts);
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY;
}
void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor)
{
- BLI_assert(bm->lnor_spacearr != NULL);
-
- if (!(bm->spacearr_dirty & (BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL))) {
- return;
- }
- BMFace *f;
- BMLoop *l;
- BMIter fiter, liter;
-
- float(*r_lnors)[3] = MEM_callocN(sizeof(*r_lnors) * bm->totloop, __func__);
- float(*oldnors)[3] = preserve_clnor ? MEM_mallocN(sizeof(*oldnors) * bm->totloop, __func__) : NULL;
-
- int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
-
- BM_mesh_elem_index_ensure(bm, BM_LOOP);
-
- if (preserve_clnor) {
- BLI_assert(bm->lnor_spacearr->lspacearr != NULL);
-
- BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
- if (BM_ELEM_API_FLAG_TEST(l, BM_LNORSPACE_UPDATE) || bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) {
- short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset);
- int l_index = BM_elem_index_get(l);
-
- BKE_lnor_space_custom_data_to_normal(
- bm->lnor_spacearr->lspacearr[l_index], *clnor,
- oldnors[l_index]);
- }
- }
- }
- }
-
- if (bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) {
- BKE_lnor_spacearr_clear(bm->lnor_spacearr);
- }
- BM_loops_calc_normal_vcos(
- bm, NULL, NULL, NULL, true, M_PI, r_lnors, bm->lnor_spacearr, NULL, cd_loop_clnors_offset, true);
- MEM_freeN(r_lnors);
-
- BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
- if (BM_ELEM_API_FLAG_TEST(l, BM_LNORSPACE_UPDATE) || bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) {
- if (preserve_clnor) {
- short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset);
- int l_index = BM_elem_index_get(l);
- BKE_lnor_space_custom_normal_to_data(
- bm->lnor_spacearr->lspacearr[l_index], oldnors[l_index],
- *clnor);
- }
- BM_ELEM_API_FLAG_DISABLE(l, BM_LNORSPACE_UPDATE);
- }
- }
- }
-
- MEM_SAFE_FREE(oldnors);
- bm->spacearr_dirty &= ~(BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL);
+ BLI_assert(bm->lnor_spacearr != NULL);
+
+ if (!(bm->spacearr_dirty & (BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL))) {
+ return;
+ }
+ BMFace *f;
+ BMLoop *l;
+ BMIter fiter, liter;
+
+ float(*r_lnors)[3] = MEM_callocN(sizeof(*r_lnors) * bm->totloop, __func__);
+ float(*oldnors)[3] = preserve_clnor ? MEM_mallocN(sizeof(*oldnors) * bm->totloop, __func__) :
+ NULL;
+
+ int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+
+ if (preserve_clnor) {
+ BLI_assert(bm->lnor_spacearr->lspacearr != NULL);
+
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ if (BM_ELEM_API_FLAG_TEST(l, BM_LNORSPACE_UPDATE) ||
+ bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) {
+ short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset);
+ int l_index = BM_elem_index_get(l);
+
+ BKE_lnor_space_custom_data_to_normal(
+ bm->lnor_spacearr->lspacearr[l_index], *clnor, oldnors[l_index]);
+ }
+ }
+ }
+ }
+
+ if (bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) {
+ BKE_lnor_spacearr_clear(bm->lnor_spacearr);
+ }
+ BM_loops_calc_normal_vcos(bm,
+ NULL,
+ NULL,
+ NULL,
+ true,
+ M_PI,
+ r_lnors,
+ bm->lnor_spacearr,
+ NULL,
+ cd_loop_clnors_offset,
+ true);
+ MEM_freeN(r_lnors);
+
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ if (BM_ELEM_API_FLAG_TEST(l, BM_LNORSPACE_UPDATE) ||
+ bm->spacearr_dirty & BM_SPACEARR_DIRTY_ALL) {
+ if (preserve_clnor) {
+ short(*clnor)[2] = BM_ELEM_CD_GET_VOID_P(l, cd_loop_clnors_offset);
+ int l_index = BM_elem_index_get(l);
+ BKE_lnor_space_custom_normal_to_data(
+ bm->lnor_spacearr->lspacearr[l_index], oldnors[l_index], *clnor);
+ }
+ BM_ELEM_API_FLAG_DISABLE(l, BM_LNORSPACE_UPDATE);
+ }
+ }
+ }
+
+ MEM_SAFE_FREE(oldnors);
+ bm->spacearr_dirty &= ~(BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL);
#ifndef NDEBUG
- BM_lnorspace_err(bm);
+ BM_lnorspace_err(bm);
#endif
}
void BM_lnorspace_update(BMesh *bm)
{
- if (bm->lnor_spacearr == NULL) {
- bm->lnor_spacearr = MEM_callocN(sizeof(*bm->lnor_spacearr), __func__);
- }
- if (bm->lnor_spacearr->lspacearr == NULL) {
- float(*lnors)[3] = MEM_callocN(sizeof(*lnors) * bm->totloop, __func__);
-
- BM_lnorspacearr_store(bm, lnors);
-
- MEM_freeN(lnors);
- }
- else if (bm->spacearr_dirty & (BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL)) {
- BM_lnorspace_rebuild(bm, false);
- }
+ if (bm->lnor_spacearr == NULL) {
+ bm->lnor_spacearr = MEM_callocN(sizeof(*bm->lnor_spacearr), __func__);
+ }
+ if (bm->lnor_spacearr->lspacearr == NULL) {
+ float(*lnors)[3] = MEM_callocN(sizeof(*lnors) * bm->totloop, __func__);
+
+ BM_lnorspacearr_store(bm, lnors);
+
+ MEM_freeN(lnors);
+ }
+ else if (bm->spacearr_dirty & (BM_SPACEARR_DIRTY | BM_SPACEARR_DIRTY_ALL)) {
+ BM_lnorspace_rebuild(bm, false);
+ }
}
void BM_normals_loops_edges_tag(BMesh *bm, const bool do_edges)
{
- BMFace *f;
- BMEdge *e;
- BMIter fiter, eiter;
- BMLoop *l_curr, *l_first;
-
- if (do_edges) {
- int index_edge;
- BM_ITER_MESH_INDEX(e, &eiter, bm, BM_EDGES_OF_MESH, index_edge) {
- BMLoop *l_a, *l_b;
-
- BM_elem_index_set(e, index_edge); /* set_inline */
- BM_elem_flag_disable(e, BM_ELEM_TAG);
- if (BM_edge_loop_pair(e, &l_a, &l_b)) {
- if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && l_a->v != l_b->v) {
- BM_elem_flag_enable(e, BM_ELEM_TAG);
- }
- }
- }
- bm->elem_index_dirty &= ~BM_EDGE;
- }
-
- int index_face, index_loop = 0;
- BM_ITER_MESH_INDEX(f, &fiter, bm, BM_FACES_OF_MESH, index_face) {
- BM_elem_index_set(f, index_face); /* set_inline */
- l_curr = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BM_elem_index_set(l_curr, index_loop++); /* set_inline */
- BM_elem_flag_disable(l_curr, BM_ELEM_TAG);
- } while ((l_curr = l_curr->next) != l_first);
- }
- bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
+ BMFace *f;
+ BMEdge *e;
+ BMIter fiter, eiter;
+ BMLoop *l_curr, *l_first;
+
+ if (do_edges) {
+ int index_edge;
+ BM_ITER_MESH_INDEX (e, &eiter, bm, BM_EDGES_OF_MESH, index_edge) {
+ BMLoop *l_a, *l_b;
+
+ BM_elem_index_set(e, index_edge); /* set_inline */
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ if (BM_edge_loop_pair(e, &l_a, &l_b)) {
+ if (BM_elem_flag_test(e, BM_ELEM_SMOOTH) && l_a->v != l_b->v) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
+ }
+ }
+ bm->elem_index_dirty &= ~BM_EDGE;
+ }
+
+ int index_face, index_loop = 0;
+ BM_ITER_MESH_INDEX (f, &fiter, bm, BM_FACES_OF_MESH, index_face) {
+ BM_elem_index_set(f, index_face); /* set_inline */
+ l_curr = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_elem_index_set(l_curr, index_loop++); /* set_inline */
+ BM_elem_flag_disable(l_curr, BM_ELEM_TAG);
+ } while ((l_curr = l_curr->next) != l_first);
+ }
+ bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
}
/**
@@ -1279,253 +1324,268 @@ void BM_normals_loops_edges_tag(BMesh *bm, const bool do_edges)
#ifndef NDEBUG
void BM_lnorspace_err(BMesh *bm)
{
- bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
- bool clear = true;
-
- MLoopNorSpaceArray *temp = MEM_callocN(sizeof(*temp), __func__);
- temp->lspacearr = NULL;
-
- BKE_lnor_spacearr_init(temp, bm->totloop, MLNOR_SPACEARR_BMLOOP_PTR);
-
- int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
- float(*lnors)[3] = MEM_callocN(sizeof(*lnors) * bm->totloop, __func__);
- BM_loops_calc_normal_vcos(bm, NULL, NULL, NULL, true, M_PI, lnors, temp, NULL, cd_loop_clnors_offset, true);
-
- for (int i = 0; i < bm->totloop; i++) {
- int j = 0;
- j += compare_ff(temp->lspacearr[i]->ref_alpha, bm->lnor_spacearr->lspacearr[i]->ref_alpha, 1e-4f);
- j += compare_ff(temp->lspacearr[i]->ref_beta, bm->lnor_spacearr->lspacearr[i]->ref_beta, 1e-4f);
- j += compare_v3v3(temp->lspacearr[i]->vec_lnor, bm->lnor_spacearr->lspacearr[i]->vec_lnor, 1e-4f);
- j += compare_v3v3(temp->lspacearr[i]->vec_ortho, bm->lnor_spacearr->lspacearr[i]->vec_ortho, 1e-4f);
- j += compare_v3v3(temp->lspacearr[i]->vec_ref, bm->lnor_spacearr->lspacearr[i]->vec_ref, 1e-4f);
-
- if (j != 5) {
- clear = false;
- break;
- }
- }
- BKE_lnor_spacearr_free(temp);
- MEM_freeN(temp);
- MEM_freeN(lnors);
- BLI_assert(clear);
-
- bm->spacearr_dirty &= ~BM_SPACEARR_DIRTY_ALL;
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+ bool clear = true;
+
+ MLoopNorSpaceArray *temp = MEM_callocN(sizeof(*temp), __func__);
+ temp->lspacearr = NULL;
+
+ BKE_lnor_spacearr_init(temp, bm->totloop, MLNOR_SPACEARR_BMLOOP_PTR);
+
+ int cd_loop_clnors_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+ float(*lnors)[3] = MEM_callocN(sizeof(*lnors) * bm->totloop, __func__);
+ BM_loops_calc_normal_vcos(
+ bm, NULL, NULL, NULL, true, M_PI, lnors, temp, NULL, cd_loop_clnors_offset, true);
+
+ for (int i = 0; i < bm->totloop; i++) {
+ int j = 0;
+ j += compare_ff(
+ temp->lspacearr[i]->ref_alpha, bm->lnor_spacearr->lspacearr[i]->ref_alpha, 1e-4f);
+ j += compare_ff(
+ temp->lspacearr[i]->ref_beta, bm->lnor_spacearr->lspacearr[i]->ref_beta, 1e-4f);
+ j += compare_v3v3(
+ temp->lspacearr[i]->vec_lnor, bm->lnor_spacearr->lspacearr[i]->vec_lnor, 1e-4f);
+ j += compare_v3v3(
+ temp->lspacearr[i]->vec_ortho, bm->lnor_spacearr->lspacearr[i]->vec_ortho, 1e-4f);
+ j += compare_v3v3(
+ temp->lspacearr[i]->vec_ref, bm->lnor_spacearr->lspacearr[i]->vec_ref, 1e-4f);
+
+ if (j != 5) {
+ clear = false;
+ break;
+ }
+ }
+ BKE_lnor_spacearr_free(temp);
+ MEM_freeN(temp);
+ MEM_freeN(lnors);
+ BLI_assert(clear);
+
+ bm->spacearr_dirty &= ~BM_SPACEARR_DIRTY_ALL;
}
#endif
-static void bm_loop_normal_mark_indiv_do_loop(
- BMLoop *l, BLI_bitmap *loops, MLoopNorSpaceArray *lnor_spacearr, int *totloopsel)
+static void bm_loop_normal_mark_indiv_do_loop(BMLoop *l,
+ BLI_bitmap *loops,
+ MLoopNorSpaceArray *lnor_spacearr,
+ int *totloopsel)
{
- if (l != NULL) {
- const int l_idx = BM_elem_index_get(l);
-
- if (!BLI_BITMAP_TEST(loops, BM_elem_index_get(l))) {
- /* If vert and face selected share a loop, mark it for editing. */
- BLI_BITMAP_ENABLE(loops, l_idx);
- (*totloopsel)++;
-
- /* Mark all loops in same loop normal space (aka smooth fan). */
- if ((lnor_spacearr->lspacearr[l_idx]->flags & MLNOR_SPACE_IS_SINGLE) == 0) {
- for (LinkNode *node = lnor_spacearr->lspacearr[l_idx]->loops; node; node = node->next) {
- const int lfan_idx = BM_elem_index_get((BMLoop *)node->link);
- if (!BLI_BITMAP_TEST(loops, lfan_idx)) {
- BLI_BITMAP_ENABLE(loops, lfan_idx);
- (*totloopsel)++;
- }
- }
- }
- }
- }
+ if (l != NULL) {
+ const int l_idx = BM_elem_index_get(l);
+
+ if (!BLI_BITMAP_TEST(loops, BM_elem_index_get(l))) {
+ /* If vert and face selected share a loop, mark it for editing. */
+ BLI_BITMAP_ENABLE(loops, l_idx);
+ (*totloopsel)++;
+
+ /* Mark all loops in same loop normal space (aka smooth fan). */
+ if ((lnor_spacearr->lspacearr[l_idx]->flags & MLNOR_SPACE_IS_SINGLE) == 0) {
+ for (LinkNode *node = lnor_spacearr->lspacearr[l_idx]->loops; node; node = node->next) {
+ const int lfan_idx = BM_elem_index_get((BMLoop *)node->link);
+ if (!BLI_BITMAP_TEST(loops, lfan_idx)) {
+ BLI_BITMAP_ENABLE(loops, lfan_idx);
+ (*totloopsel)++;
+ }
+ }
+ }
+ }
+ }
}
/* Mark the individual clnors to be edited, if multiple selection methods are used. */
static int bm_loop_normal_mark_indiv(BMesh *bm, BLI_bitmap *loops)
{
- BMEditSelection *ese, *ese_prev;
- int totloopsel = 0;
-
- const bool sel_verts = (bm->selectmode & SCE_SELECT_VERTEX) != 0;
- const bool sel_edges = (bm->selectmode & SCE_SELECT_EDGE) != 0;
- const bool sel_faces = (bm->selectmode & SCE_SELECT_FACE) != 0;
- const bool use_sel_face_history = sel_faces && (sel_edges || sel_verts);
-
- BM_mesh_elem_index_ensure(bm, BM_LOOP);
-
- BLI_assert(bm->lnor_spacearr != NULL);
- BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR);
-
- if (use_sel_face_history) {
- /* Using face history allows to select a single loop from a single face...
- * Note that this is On² piece of code, but it is not designed to be used with huge selection sets,
- * rather with only a few items selected at most.*/
- printf("using face history selection\n");
- /* Goes from last selected to the first selected element. */
- for (ese = bm->selected.last; ese; ese = ese->prev) {
- if (ese->htype == BM_FACE) {
- /* If current face is selected, then any verts to be edited must have been selected before it. */
- for (ese_prev = ese->prev; ese_prev; ese_prev = ese_prev->prev) {
- if (ese_prev->htype == BM_VERT) {
- bm_loop_normal_mark_indiv_do_loop(
- BM_face_vert_share_loop((BMFace *)ese->ele, (BMVert *)ese_prev->ele),
- loops, bm->lnor_spacearr, &totloopsel);
- }
- else if (ese_prev->htype == BM_EDGE) {
- BMEdge *e = (BMEdge *)ese_prev->ele;
- bm_loop_normal_mark_indiv_do_loop(
- BM_face_vert_share_loop((BMFace *)ese->ele, e->v1),
- loops, bm->lnor_spacearr, &totloopsel);
-
- bm_loop_normal_mark_indiv_do_loop(
- BM_face_vert_share_loop((BMFace *)ese->ele, e->v2),
- loops, bm->lnor_spacearr, &totloopsel);
- }
- }
- }
- }
- }
- else {
- if (sel_faces) {
- /* Only select all loops of selected faces. */
- printf("using face selection\n");
- BMLoop *l;
- BMFace *f;
- BMIter liter, fiter;
- BM_ITER_MESH(f, &fiter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
- BM_ITER_ELEM(l, &liter, f, BM_LOOPS_OF_FACE) {
- bm_loop_normal_mark_indiv_do_loop(l, loops, bm->lnor_spacearr, &totloopsel);
- }
- }
- }
- }
- if (sel_edges) {
- /* Only select all loops of selected edges. */
- printf("using edge selection\n");
- BMLoop *l;
- BMEdge *e;
- BMIter liter, eiter;
- BM_ITER_MESH(e, &eiter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
- BM_ITER_ELEM(l, &liter, e, BM_LOOPS_OF_EDGE) {
- bm_loop_normal_mark_indiv_do_loop(l, loops, bm->lnor_spacearr, &totloopsel);
- /* Loops actually 'have' two edges, or said otherwise, a selected edge actually selects
- * *two* loops in each of its faces. We have to find the other one too. */
- if (BM_vert_in_edge(e, l->next->v)) {
- bm_loop_normal_mark_indiv_do_loop(l->next, loops, bm->lnor_spacearr, &totloopsel);
- }
- else {
- BLI_assert(BM_vert_in_edge(e, l->prev->v));
- bm_loop_normal_mark_indiv_do_loop(l->prev, loops, bm->lnor_spacearr, &totloopsel);
- }
- }
- }
- }
- }
- if (sel_verts) {
- /* Select all loops of selected verts. */
- printf("using vert selection\n");
- BMLoop *l;
- BMVert *v;
- BMIter liter, viter;
- BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
- bm_loop_normal_mark_indiv_do_loop(l, loops, bm->lnor_spacearr, &totloopsel);
- }
- }
- }
- }
- }
-
- return totloopsel;
+ BMEditSelection *ese, *ese_prev;
+ int totloopsel = 0;
+
+ const bool sel_verts = (bm->selectmode & SCE_SELECT_VERTEX) != 0;
+ const bool sel_edges = (bm->selectmode & SCE_SELECT_EDGE) != 0;
+ const bool sel_faces = (bm->selectmode & SCE_SELECT_FACE) != 0;
+ const bool use_sel_face_history = sel_faces && (sel_edges || sel_verts);
+
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
+
+ BLI_assert(bm->lnor_spacearr != NULL);
+ BLI_assert(bm->lnor_spacearr->data_type == MLNOR_SPACEARR_BMLOOP_PTR);
+
+ if (use_sel_face_history) {
+ /* Using face history allows to select a single loop from a single face...
+ * Note that this is On² piece of code, but it is not designed to be used with huge selection sets,
+ * rather with only a few items selected at most.*/
+ printf("using face history selection\n");
+ /* Goes from last selected to the first selected element. */
+ for (ese = bm->selected.last; ese; ese = ese->prev) {
+ if (ese->htype == BM_FACE) {
+ /* If current face is selected, then any verts to be edited must have been selected before it. */
+ for (ese_prev = ese->prev; ese_prev; ese_prev = ese_prev->prev) {
+ if (ese_prev->htype == BM_VERT) {
+ bm_loop_normal_mark_indiv_do_loop(
+ BM_face_vert_share_loop((BMFace *)ese->ele, (BMVert *)ese_prev->ele),
+ loops,
+ bm->lnor_spacearr,
+ &totloopsel);
+ }
+ else if (ese_prev->htype == BM_EDGE) {
+ BMEdge *e = (BMEdge *)ese_prev->ele;
+ bm_loop_normal_mark_indiv_do_loop(BM_face_vert_share_loop((BMFace *)ese->ele, e->v1),
+ loops,
+ bm->lnor_spacearr,
+ &totloopsel);
+
+ bm_loop_normal_mark_indiv_do_loop(BM_face_vert_share_loop((BMFace *)ese->ele, e->v2),
+ loops,
+ bm->lnor_spacearr,
+ &totloopsel);
+ }
+ }
+ }
+ }
+ }
+ else {
+ if (sel_faces) {
+ /* Only select all loops of selected faces. */
+ printf("using face selection\n");
+ BMLoop *l;
+ BMFace *f;
+ BMIter liter, fiter;
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
+ BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
+ bm_loop_normal_mark_indiv_do_loop(l, loops, bm->lnor_spacearr, &totloopsel);
+ }
+ }
+ }
+ }
+ if (sel_edges) {
+ /* Only select all loops of selected edges. */
+ printf("using edge selection\n");
+ BMLoop *l;
+ BMEdge *e;
+ BMIter liter, eiter;
+ BM_ITER_MESH (e, &eiter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
+ BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
+ bm_loop_normal_mark_indiv_do_loop(l, loops, bm->lnor_spacearr, &totloopsel);
+ /* Loops actually 'have' two edges, or said otherwise, a selected edge actually selects
+ * *two* loops in each of its faces. We have to find the other one too. */
+ if (BM_vert_in_edge(e, l->next->v)) {
+ bm_loop_normal_mark_indiv_do_loop(l->next, loops, bm->lnor_spacearr, &totloopsel);
+ }
+ else {
+ BLI_assert(BM_vert_in_edge(e, l->prev->v));
+ bm_loop_normal_mark_indiv_do_loop(l->prev, loops, bm->lnor_spacearr, &totloopsel);
+ }
+ }
+ }
+ }
+ }
+ if (sel_verts) {
+ /* Select all loops of selected verts. */
+ printf("using vert selection\n");
+ BMLoop *l;
+ BMVert *v;
+ BMIter liter, viter;
+ BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ bm_loop_normal_mark_indiv_do_loop(l, loops, bm->lnor_spacearr, &totloopsel);
+ }
+ }
+ }
+ }
+ }
+
+ return totloopsel;
}
-static void loop_normal_editdata_init(BMesh *bm, BMLoopNorEditData *lnor_ed, BMVert *v, BMLoop *l, const int offset)
+static void loop_normal_editdata_init(
+ BMesh *bm, BMLoopNorEditData *lnor_ed, BMVert *v, BMLoop *l, const int offset)
{
- BLI_assert(bm->lnor_spacearr != NULL);
- BLI_assert(bm->lnor_spacearr->lspacearr != NULL);
+ BLI_assert(bm->lnor_spacearr != NULL);
+ BLI_assert(bm->lnor_spacearr->lspacearr != NULL);
- const int l_index = BM_elem_index_get(l);
- short *clnors_data = BM_ELEM_CD_GET_VOID_P(l, offset);
+ const int l_index = BM_elem_index_get(l);
+ short *clnors_data = BM_ELEM_CD_GET_VOID_P(l, offset);
- lnor_ed->loop_index = l_index;
- lnor_ed->loop = l;
+ lnor_ed->loop_index = l_index;
+ lnor_ed->loop = l;
- float custom_normal[3];
- BKE_lnor_space_custom_data_to_normal(bm->lnor_spacearr->lspacearr[l_index], clnors_data, custom_normal);
+ float custom_normal[3];
+ BKE_lnor_space_custom_data_to_normal(
+ bm->lnor_spacearr->lspacearr[l_index], clnors_data, custom_normal);
- lnor_ed->clnors_data = clnors_data;
- copy_v3_v3(lnor_ed->nloc, custom_normal);
- copy_v3_v3(lnor_ed->niloc, custom_normal);
+ lnor_ed->clnors_data = clnors_data;
+ copy_v3_v3(lnor_ed->nloc, custom_normal);
+ copy_v3_v3(lnor_ed->niloc, custom_normal);
- lnor_ed->loc = v->co;
+ lnor_ed->loc = v->co;
}
BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm)
{
- BMLoop *l;
- BMVert *v;
- BMIter liter, viter;
+ BMLoop *l;
+ BMVert *v;
+ BMIter liter, viter;
- int totloopsel = 0;
+ int totloopsel = 0;
- BLI_assert(bm->spacearr_dirty == 0);
+ BLI_assert(bm->spacearr_dirty == 0);
- BMLoopNorEditDataArray *lnors_ed_arr = MEM_mallocN(sizeof(*lnors_ed_arr), __func__);
- lnors_ed_arr->lidx_to_lnor_editdata = MEM_callocN(
- sizeof(*lnors_ed_arr->lidx_to_lnor_editdata) * bm->totloop, __func__);
+ BMLoopNorEditDataArray *lnors_ed_arr = MEM_mallocN(sizeof(*lnors_ed_arr), __func__);
+ lnors_ed_arr->lidx_to_lnor_editdata = MEM_callocN(
+ sizeof(*lnors_ed_arr->lidx_to_lnor_editdata) * bm->totloop, __func__);
- if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) {
- BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL);
- }
- const int cd_custom_normal_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
+ if (!CustomData_has_layer(&bm->ldata, CD_CUSTOMLOOPNORMAL)) {
+ BM_data_layer_add(bm, &bm->ldata, CD_CUSTOMLOOPNORMAL);
+ }
+ const int cd_custom_normal_offset = CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
- BM_mesh_elem_index_ensure(bm, BM_LOOP);
+ BM_mesh_elem_index_ensure(bm, BM_LOOP);
- BLI_bitmap *loops = BLI_BITMAP_NEW(bm->totloop, __func__);
+ BLI_bitmap *loops = BLI_BITMAP_NEW(bm->totloop, __func__);
- /* This function define loop normals to edit, based on selection modes and history. */
- totloopsel = bm_loop_normal_mark_indiv(bm, loops);
+ /* This function define loop normals to edit, based on selection modes and history. */
+ totloopsel = bm_loop_normal_mark_indiv(bm, loops);
- if (totloopsel) {
- BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata = MEM_mallocN(sizeof(*lnor_ed) * totloopsel, __func__);
+ if (totloopsel) {
+ BMLoopNorEditData *lnor_ed = lnors_ed_arr->lnor_editdata = MEM_mallocN(
+ sizeof(*lnor_ed) * totloopsel, __func__);
- BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
- BM_ITER_ELEM(l, &liter, v, BM_LOOPS_OF_VERT) {
- if (BLI_BITMAP_TEST(loops, BM_elem_index_get(l))) {
- loop_normal_editdata_init(bm, lnor_ed, v, l, cd_custom_normal_offset);
- lnors_ed_arr->lidx_to_lnor_editdata[BM_elem_index_get(l)] = lnor_ed;
- lnor_ed++;
- }
- }
- }
- lnors_ed_arr->totloop = totloopsel;
- }
+ BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
+ BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
+ if (BLI_BITMAP_TEST(loops, BM_elem_index_get(l))) {
+ loop_normal_editdata_init(bm, lnor_ed, v, l, cd_custom_normal_offset);
+ lnors_ed_arr->lidx_to_lnor_editdata[BM_elem_index_get(l)] = lnor_ed;
+ lnor_ed++;
+ }
+ }
+ }
+ lnors_ed_arr->totloop = totloopsel;
+ }
- MEM_freeN(loops);
- lnors_ed_arr->cd_custom_normal_offset = cd_custom_normal_offset;
- return lnors_ed_arr;
+ MEM_freeN(loops);
+ lnors_ed_arr->cd_custom_normal_offset = cd_custom_normal_offset;
+ return lnors_ed_arr;
}
void BM_loop_normal_editdata_array_free(BMLoopNorEditDataArray *lnors_ed_arr)
{
- MEM_SAFE_FREE(lnors_ed_arr->lnor_editdata);
- MEM_SAFE_FREE(lnors_ed_arr->lidx_to_lnor_editdata);
- MEM_freeN(lnors_ed_arr);
+ MEM_SAFE_FREE(lnors_ed_arr->lnor_editdata);
+ MEM_SAFE_FREE(lnors_ed_arr->lidx_to_lnor_editdata);
+ MEM_freeN(lnors_ed_arr);
}
int BM_total_loop_select(BMesh *bm)
{
- int r_sel = 0;
- BMVert *v;
- BMIter viter;
-
- BM_ITER_MESH(v, &viter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
- r_sel += BM_vert_face_count(v);
- }
- }
- return r_sel;
+ int r_sel = 0;
+ BMVert *v;
+ BMIter viter;
+
+ BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
+ r_sel += BM_vert_face_count(v);
+ }
+ }
+ return r_sel;
}
/**
@@ -1537,20 +1597,21 @@ int BM_total_loop_select(BMesh *bm)
*/
void bmesh_edit_begin(BMesh *UNUSED(bm), BMOpTypeFlag UNUSED(type_flag))
{
- /* Most operators seem to be using BMO_OPTYPE_FLAG_UNTAN_MULTIRES to change the MDisps to
- * absolute space during mesh edits. With this enabled, changes to the topology
- * (loop cuts, edge subdivides, etc) are not reflected in the higher levels of
- * the mesh at all, which doesn't seem right. Turning off completely for now,
- * until this is shown to be better for certain types of mesh edits. */
+ /* Most operators seem to be using BMO_OPTYPE_FLAG_UNTAN_MULTIRES to change the MDisps to
+ * absolute space during mesh edits. With this enabled, changes to the topology
+ * (loop cuts, edge subdivides, etc) are not reflected in the higher levels of
+ * the mesh at all, which doesn't seem right. Turning off completely for now,
+ * until this is shown to be better for certain types of mesh edits. */
#ifdef BMOP_UNTAN_MULTIRES_ENABLED
- /* switch multires data out of tangent space */
- if ((type_flag & BMO_OPTYPE_FLAG_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
- bmesh_mdisps_space_set(bm, MULTIRES_SPACE_TANGENT, MULTIRES_SPACE_ABSOLUTE);
-
- /* ensure correct normals, if possible */
- bmesh_rationalize_normals(bm, 0);
- BM_mesh_normals_update(bm);
- }
+ /* switch multires data out of tangent space */
+ if ((type_flag & BMO_OPTYPE_FLAG_UNTAN_MULTIRES) &&
+ CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
+ bmesh_mdisps_space_set(bm, MULTIRES_SPACE_TANGENT, MULTIRES_SPACE_ABSOLUTE);
+
+ /* ensure correct normals, if possible */
+ bmesh_rationalize_normals(bm, 0);
+ BM_mesh_normals_update(bm);
+ }
#endif
}
@@ -1559,164 +1620,163 @@ void bmesh_edit_begin(BMesh *UNUSED(bm), BMOpTypeFlag UNUSED(type_flag))
*/
void bmesh_edit_end(BMesh *bm, BMOpTypeFlag type_flag)
{
- ListBase select_history;
+ ListBase select_history;
- /* BMO_OPTYPE_FLAG_UNTAN_MULTIRES disabled for now, see comment above in bmesh_edit_begin. */
+ /* BMO_OPTYPE_FLAG_UNTAN_MULTIRES disabled for now, see comment above in bmesh_edit_begin. */
#ifdef BMOP_UNTAN_MULTIRES_ENABLED
- /* switch multires data into tangent space */
- if ((flag & BMO_OPTYPE_FLAG_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
- /* set normals to their previous winding */
- bmesh_rationalize_normals(bm, 1);
- bmesh_mdisps_space_set(bm, MULTIRES_SPACE_ABSOLUTE, MULTIRES_SPACE_TANGENT);
- }
- else if (flag & BMO_OP_FLAG_RATIONALIZE_NORMALS) {
- bmesh_rationalize_normals(bm, 1);
- }
+ /* switch multires data into tangent space */
+ if ((flag & BMO_OPTYPE_FLAG_UNTAN_MULTIRES) && CustomData_has_layer(&bm->ldata, CD_MDISPS)) {
+ /* set normals to their previous winding */
+ bmesh_rationalize_normals(bm, 1);
+ bmesh_mdisps_space_set(bm, MULTIRES_SPACE_ABSOLUTE, MULTIRES_SPACE_TANGENT);
+ }
+ else if (flag & BMO_OP_FLAG_RATIONALIZE_NORMALS) {
+ bmesh_rationalize_normals(bm, 1);
+ }
#endif
- /* compute normals, clear temp flags and flush selections */
- if (type_flag & BMO_OPTYPE_FLAG_NORMALS_CALC) {
- bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
- BM_mesh_normals_update(bm);
- }
-
-
- if ((type_flag & BMO_OPTYPE_FLAG_SELECT_VALIDATE) == 0) {
- select_history = bm->selected;
- BLI_listbase_clear(&bm->selected);
- }
-
- if (type_flag & BMO_OPTYPE_FLAG_SELECT_FLUSH) {
- BM_mesh_select_mode_flush(bm);
- }
-
- if ((type_flag & BMO_OPTYPE_FLAG_SELECT_VALIDATE) == 0) {
- bm->selected = select_history;
- }
- if (type_flag & BMO_OPTYPE_FLAG_INVALIDATE_CLNOR_ALL) {
- bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
- }
+ /* compute normals, clear temp flags and flush selections */
+ if (type_flag & BMO_OPTYPE_FLAG_NORMALS_CALC) {
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+ BM_mesh_normals_update(bm);
+ }
+
+ if ((type_flag & BMO_OPTYPE_FLAG_SELECT_VALIDATE) == 0) {
+ select_history = bm->selected;
+ BLI_listbase_clear(&bm->selected);
+ }
+
+ if (type_flag & BMO_OPTYPE_FLAG_SELECT_FLUSH) {
+ BM_mesh_select_mode_flush(bm);
+ }
+
+ if ((type_flag & BMO_OPTYPE_FLAG_SELECT_VALIDATE) == 0) {
+ bm->selected = select_history;
+ }
+ if (type_flag & BMO_OPTYPE_FLAG_INVALIDATE_CLNOR_ALL) {
+ bm->spacearr_dirty |= BM_SPACEARR_DIRTY_ALL;
+ }
}
void BM_mesh_elem_index_ensure_ex(BMesh *bm, const char htype, int elem_offset[4])
{
#ifdef DEBUG
- BM_ELEM_INDEX_VALIDATE(bm, "Should Never Fail!", __func__);
+ BM_ELEM_INDEX_VALIDATE(bm, "Should Never Fail!", __func__);
#endif
- if (elem_offset == NULL) {
- /* Simple case. */
- const char htype_needed = bm->elem_index_dirty & htype;
- if (htype_needed == 0) {
- goto finally;
- }
- }
-
- if (htype & BM_VERT) {
- if ((bm->elem_index_dirty & BM_VERT) || (elem_offset && elem_offset[0])) {
- BMIter iter;
- BMElem *ele;
-
- int index = elem_offset ? elem_offset[0] : 0;
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- BM_elem_index_set(ele, index++); /* set_ok */
- }
- BLI_assert(elem_offset || index == bm->totvert);
- }
- else {
- // printf("%s: skipping vert index calc!\n", __func__);
- }
- }
-
- if (htype & BM_EDGE) {
- if ((bm->elem_index_dirty & BM_EDGE) || (elem_offset && elem_offset[1])) {
- BMIter iter;
- BMElem *ele;
-
- int index = elem_offset ? elem_offset[1] : 0;
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- BM_elem_index_set(ele, index++); /* set_ok */
- }
- BLI_assert(elem_offset || index == bm->totedge);
- }
- else {
- // printf("%s: skipping edge index calc!\n", __func__);
- }
- }
-
- if (htype & (BM_FACE | BM_LOOP)) {
- if ((bm->elem_index_dirty & (BM_FACE | BM_LOOP)) || (elem_offset && (elem_offset[2] || elem_offset[3]))) {
- BMIter iter;
- BMElem *ele;
-
- const bool update_face = (htype & BM_FACE) && (bm->elem_index_dirty & BM_FACE);
- const bool update_loop = (htype & BM_LOOP) && (bm->elem_index_dirty & BM_LOOP);
-
- int index_loop = elem_offset ? elem_offset[2] : 0;
- int index = elem_offset ? elem_offset[3] : 0;
-
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- if (update_face) {
- BM_elem_index_set(ele, index++); /* set_ok */
- }
-
- if (update_loop) {
- BMLoop *l_iter, *l_first;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP((BMFace *)ele);
- do {
- BM_elem_index_set(l_iter, index_loop++); /* set_ok */
- } while ((l_iter = l_iter->next) != l_first);
- }
- }
-
- BLI_assert(elem_offset || !update_face || index == bm->totface);
- if (update_loop) {
- BLI_assert(elem_offset || !update_loop || index_loop == bm->totloop);
- }
- }
- else {
- // printf("%s: skipping face/loop index calc!\n", __func__);
- }
- }
+ if (elem_offset == NULL) {
+ /* Simple case. */
+ const char htype_needed = bm->elem_index_dirty & htype;
+ if (htype_needed == 0) {
+ goto finally;
+ }
+ }
+
+ if (htype & BM_VERT) {
+ if ((bm->elem_index_dirty & BM_VERT) || (elem_offset && elem_offset[0])) {
+ BMIter iter;
+ BMElem *ele;
+
+ int index = elem_offset ? elem_offset[0] : 0;
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ BM_elem_index_set(ele, index++); /* set_ok */
+ }
+ BLI_assert(elem_offset || index == bm->totvert);
+ }
+ else {
+ // printf("%s: skipping vert index calc!\n", __func__);
+ }
+ }
+
+ if (htype & BM_EDGE) {
+ if ((bm->elem_index_dirty & BM_EDGE) || (elem_offset && elem_offset[1])) {
+ BMIter iter;
+ BMElem *ele;
+
+ int index = elem_offset ? elem_offset[1] : 0;
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ BM_elem_index_set(ele, index++); /* set_ok */
+ }
+ BLI_assert(elem_offset || index == bm->totedge);
+ }
+ else {
+ // printf("%s: skipping edge index calc!\n", __func__);
+ }
+ }
+
+ if (htype & (BM_FACE | BM_LOOP)) {
+ if ((bm->elem_index_dirty & (BM_FACE | BM_LOOP)) ||
+ (elem_offset && (elem_offset[2] || elem_offset[3]))) {
+ BMIter iter;
+ BMElem *ele;
+
+ const bool update_face = (htype & BM_FACE) && (bm->elem_index_dirty & BM_FACE);
+ const bool update_loop = (htype & BM_LOOP) && (bm->elem_index_dirty & BM_LOOP);
+
+ int index_loop = elem_offset ? elem_offset[2] : 0;
+ int index = elem_offset ? elem_offset[3] : 0;
+
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ if (update_face) {
+ BM_elem_index_set(ele, index++); /* set_ok */
+ }
+
+ if (update_loop) {
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP((BMFace *)ele);
+ do {
+ BM_elem_index_set(l_iter, index_loop++); /* set_ok */
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+
+ BLI_assert(elem_offset || !update_face || index == bm->totface);
+ if (update_loop) {
+ BLI_assert(elem_offset || !update_loop || index_loop == bm->totloop);
+ }
+ }
+ else {
+ // printf("%s: skipping face/loop index calc!\n", __func__);
+ }
+ }
finally:
- bm->elem_index_dirty &= ~htype;
- if (elem_offset) {
- if (htype & BM_VERT) {
- elem_offset[0] += bm->totvert;
- if (elem_offset[0] != bm->totvert) {
- bm->elem_index_dirty |= BM_VERT;
- }
- }
- if (htype & BM_EDGE) {
- elem_offset[1] += bm->totedge;
- if (elem_offset[1] != bm->totedge) {
- bm->elem_index_dirty |= BM_EDGE;
- }
- }
- if (htype & BM_LOOP) {
- elem_offset[2] += bm->totloop;
- if (elem_offset[2] != bm->totloop) {
- bm->elem_index_dirty |= BM_LOOP;
- }
- }
- if (htype & BM_FACE) {
- elem_offset[3] += bm->totface;
- if (elem_offset[3] != bm->totface) {
- bm->elem_index_dirty |= BM_FACE;
- }
- }
- }
+ bm->elem_index_dirty &= ~htype;
+ if (elem_offset) {
+ if (htype & BM_VERT) {
+ elem_offset[0] += bm->totvert;
+ if (elem_offset[0] != bm->totvert) {
+ bm->elem_index_dirty |= BM_VERT;
+ }
+ }
+ if (htype & BM_EDGE) {
+ elem_offset[1] += bm->totedge;
+ if (elem_offset[1] != bm->totedge) {
+ bm->elem_index_dirty |= BM_EDGE;
+ }
+ }
+ if (htype & BM_LOOP) {
+ elem_offset[2] += bm->totloop;
+ if (elem_offset[2] != bm->totloop) {
+ bm->elem_index_dirty |= BM_LOOP;
+ }
+ }
+ if (htype & BM_FACE) {
+ elem_offset[3] += bm->totface;
+ if (elem_offset[3] != bm->totface) {
+ bm->elem_index_dirty |= BM_FACE;
+ }
+ }
+ }
}
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
{
- BM_mesh_elem_index_ensure_ex(bm, htype, NULL);
+ BM_mesh_elem_index_ensure_ex(bm, htype, NULL);
}
-
/**
* Array checking/setting macros
*
@@ -1729,221 +1789,223 @@ void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
*/
void BM_mesh_elem_index_validate(
- BMesh *bm, const char *location, const char *func,
- const char *msg_a, const char *msg_b)
+ BMesh *bm, const char *location, const char *func, const char *msg_a, const char *msg_b)
{
- const char iter_types[3] = {BM_VERTS_OF_MESH,
- BM_EDGES_OF_MESH,
- BM_FACES_OF_MESH};
-
- const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
- const char *type_names[3] = {"vert", "edge", "face"};
-
- BMIter iter;
- BMElem *ele;
- int i;
- bool is_any_error = 0;
-
- for (i = 0; i < 3; i++) {
- const bool is_dirty = (flag_types[i] & bm->elem_index_dirty) != 0;
- int index = 0;
- bool is_error = false;
- int err_val = 0;
- int err_idx = 0;
-
- BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
- if (!is_dirty) {
- if (BM_elem_index_get(ele) != index) {
- err_val = BM_elem_index_get(ele);
- err_idx = index;
- is_error = true;
- }
- }
-
- BM_elem_index_set(ele, index); /* set_ok */
- index++;
- }
-
- if ((is_error == true) && (is_dirty == false)) {
- is_any_error = true;
- fprintf(stderr,
- "Invalid Index: at %s, %s, %s[%d] invalid index %d, '%s', '%s'\n",
- location, func, type_names[i], err_idx, err_val, msg_a, msg_b);
- }
- else if ((is_error == false) && (is_dirty == true)) {
-
-#if 0 /* mostly annoying */
-
- /* dirty may have been incorrectly set */
- fprintf(stderr,
- "Invalid Dirty: at %s, %s (%s), dirty flag was set but all index values are correct, '%s', '%s'\n",
- location, func, type_names[i], msg_a, msg_b);
+ const char iter_types[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
+
+ const char flag_types[3] = {BM_VERT, BM_EDGE, BM_FACE};
+ const char *type_names[3] = {"vert", "edge", "face"};
+
+ BMIter iter;
+ BMElem *ele;
+ int i;
+ bool is_any_error = 0;
+
+ for (i = 0; i < 3; i++) {
+ const bool is_dirty = (flag_types[i] & bm->elem_index_dirty) != 0;
+ int index = 0;
+ bool is_error = false;
+ int err_val = 0;
+ int err_idx = 0;
+
+ BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
+ if (!is_dirty) {
+ if (BM_elem_index_get(ele) != index) {
+ err_val = BM_elem_index_get(ele);
+ err_idx = index;
+ is_error = true;
+ }
+ }
+
+ BM_elem_index_set(ele, index); /* set_ok */
+ index++;
+ }
+
+ if ((is_error == true) && (is_dirty == false)) {
+ is_any_error = true;
+ fprintf(stderr,
+ "Invalid Index: at %s, %s, %s[%d] invalid index %d, '%s', '%s'\n",
+ location,
+ func,
+ type_names[i],
+ err_idx,
+ err_val,
+ msg_a,
+ msg_b);
+ }
+ else if ((is_error == false) && (is_dirty == true)) {
+
+#if 0 /* mostly annoying */
+
+ /* dirty may have been incorrectly set */
+ fprintf(stderr,
+ "Invalid Dirty: at %s, %s (%s), dirty flag was set but all index values are correct, '%s', '%s'\n",
+ location, func, type_names[i], msg_a, msg_b);
#endif
- }
- }
+ }
+ }
#if 0 /* mostly annoying, even in debug mode */
-#ifdef DEBUG
- if (is_any_error == 0) {
- fprintf(stderr,
- "Valid Index Success: at %s, %s, '%s', '%s'\n",
- location, func, msg_a, msg_b);
- }
+# ifdef DEBUG
+ if (is_any_error == 0) {
+ fprintf(stderr,
+ "Valid Index Success: at %s, %s, '%s', '%s'\n",
+ location, func, msg_a, msg_b);
+ }
+# endif
#endif
-#endif
- (void) is_any_error; /* shut up the compiler */
-
+ (void)is_any_error; /* shut up the compiler */
}
/* debug check only - no need to optimize */
#ifndef NDEBUG
bool BM_mesh_elem_table_check(BMesh *bm)
{
- BMIter iter;
- BMElem *ele;
- int i;
-
- if (bm->vtable && ((bm->elem_table_dirty & BM_VERT) == 0)) {
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
- if (ele != (BMElem *)bm->vtable[i]) {
- return false;
- }
- }
- }
-
- if (bm->etable && ((bm->elem_table_dirty & BM_EDGE) == 0)) {
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
- if (ele != (BMElem *)bm->etable[i]) {
- return false;
- }
- }
- }
-
- if (bm->ftable && ((bm->elem_table_dirty & BM_FACE) == 0)) {
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
- if (ele != (BMElem *)bm->ftable[i]) {
- return false;
- }
- }
- }
-
- return true;
+ BMIter iter;
+ BMElem *ele;
+ int i;
+
+ if (bm->vtable && ((bm->elem_table_dirty & BM_VERT) == 0)) {
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
+ if (ele != (BMElem *)bm->vtable[i]) {
+ return false;
+ }
+ }
+ }
+
+ if (bm->etable && ((bm->elem_table_dirty & BM_EDGE) == 0)) {
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
+ if (ele != (BMElem *)bm->etable[i]) {
+ return false;
+ }
+ }
+ }
+
+ if (bm->ftable && ((bm->elem_table_dirty & BM_FACE) == 0)) {
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
+ if (ele != (BMElem *)bm->ftable[i]) {
+ return false;
+ }
+ }
+ }
+
+ return true;
}
#endif
-
-
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
{
- /* assume if the array is non-null then its valid and no need to recalc */
- const char htype_needed = (((bm->vtable && ((bm->elem_table_dirty & BM_VERT) == 0)) ? 0 : BM_VERT) |
- ((bm->etable && ((bm->elem_table_dirty & BM_EDGE) == 0)) ? 0 : BM_EDGE) |
- ((bm->ftable && ((bm->elem_table_dirty & BM_FACE) == 0)) ? 0 : BM_FACE)) & htype;
-
- BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
-
- /* in debug mode double check we didn't need to recalculate */
- BLI_assert(BM_mesh_elem_table_check(bm) == true);
-
- if (htype_needed == 0) {
- goto finally;
- }
-
- if (htype_needed & BM_VERT) {
- if (bm->vtable && bm->totvert <= bm->vtable_tot && bm->totvert * 2 >= bm->vtable_tot) {
- /* pass (re-use the array) */
- }
- else {
- if (bm->vtable) {
- MEM_freeN(bm->vtable);
- }
- bm->vtable = MEM_mallocN(sizeof(void **) * bm->totvert, "bm->vtable");
- bm->vtable_tot = bm->totvert;
- }
- }
- if (htype_needed & BM_EDGE) {
- if (bm->etable && bm->totedge <= bm->etable_tot && bm->totedge * 2 >= bm->etable_tot) {
- /* pass (re-use the array) */
- }
- else {
- if (bm->etable) {
- MEM_freeN(bm->etable);
- }
- bm->etable = MEM_mallocN(sizeof(void **) * bm->totedge, "bm->etable");
- bm->etable_tot = bm->totedge;
- }
- }
- if (htype_needed & BM_FACE) {
- if (bm->ftable && bm->totface <= bm->ftable_tot && bm->totface * 2 >= bm->ftable_tot) {
- /* pass (re-use the array) */
- }
- else {
- if (bm->ftable) {
- MEM_freeN(bm->ftable);
- }
- bm->ftable = MEM_mallocN(sizeof(void **) * bm->totface, "bm->ftable");
- bm->ftable_tot = bm->totface;
- }
- }
-
- if (htype_needed & BM_VERT) {
- BM_iter_as_array(bm, BM_VERTS_OF_MESH, NULL, (void **)bm->vtable, bm->totvert);
- }
-
- if (htype_needed & BM_EDGE) {
- BM_iter_as_array(bm, BM_EDGES_OF_MESH, NULL, (void **)bm->etable, bm->totedge);
- }
-
- if (htype_needed & BM_FACE) {
- BM_iter_as_array(bm, BM_FACES_OF_MESH, NULL, (void **)bm->ftable, bm->totface);
- }
+ /* assume if the array is non-null then its valid and no need to recalc */
+ const char htype_needed =
+ (((bm->vtable && ((bm->elem_table_dirty & BM_VERT) == 0)) ? 0 : BM_VERT) |
+ ((bm->etable && ((bm->elem_table_dirty & BM_EDGE) == 0)) ? 0 : BM_EDGE) |
+ ((bm->ftable && ((bm->elem_table_dirty & BM_FACE) == 0)) ? 0 : BM_FACE)) &
+ htype;
+
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
+ /* in debug mode double check we didn't need to recalculate */
+ BLI_assert(BM_mesh_elem_table_check(bm) == true);
+
+ if (htype_needed == 0) {
+ goto finally;
+ }
+
+ if (htype_needed & BM_VERT) {
+ if (bm->vtable && bm->totvert <= bm->vtable_tot && bm->totvert * 2 >= bm->vtable_tot) {
+ /* pass (re-use the array) */
+ }
+ else {
+ if (bm->vtable) {
+ MEM_freeN(bm->vtable);
+ }
+ bm->vtable = MEM_mallocN(sizeof(void **) * bm->totvert, "bm->vtable");
+ bm->vtable_tot = bm->totvert;
+ }
+ }
+ if (htype_needed & BM_EDGE) {
+ if (bm->etable && bm->totedge <= bm->etable_tot && bm->totedge * 2 >= bm->etable_tot) {
+ /* pass (re-use the array) */
+ }
+ else {
+ if (bm->etable) {
+ MEM_freeN(bm->etable);
+ }
+ bm->etable = MEM_mallocN(sizeof(void **) * bm->totedge, "bm->etable");
+ bm->etable_tot = bm->totedge;
+ }
+ }
+ if (htype_needed & BM_FACE) {
+ if (bm->ftable && bm->totface <= bm->ftable_tot && bm->totface * 2 >= bm->ftable_tot) {
+ /* pass (re-use the array) */
+ }
+ else {
+ if (bm->ftable) {
+ MEM_freeN(bm->ftable);
+ }
+ bm->ftable = MEM_mallocN(sizeof(void **) * bm->totface, "bm->ftable");
+ bm->ftable_tot = bm->totface;
+ }
+ }
+
+ if (htype_needed & BM_VERT) {
+ BM_iter_as_array(bm, BM_VERTS_OF_MESH, NULL, (void **)bm->vtable, bm->totvert);
+ }
+
+ if (htype_needed & BM_EDGE) {
+ BM_iter_as_array(bm, BM_EDGES_OF_MESH, NULL, (void **)bm->etable, bm->totedge);
+ }
+
+ if (htype_needed & BM_FACE) {
+ BM_iter_as_array(bm, BM_FACES_OF_MESH, NULL, (void **)bm->ftable, bm->totface);
+ }
finally:
- /* Only clear dirty flags when all the pointers and data are actually valid.
- * This prevents possible threading issues when dirty flag check failed but
- * data wasn't ready still.
- */
- bm->elem_table_dirty &= ~htype_needed;
+ /* Only clear dirty flags when all the pointers and data are actually valid.
+ * This prevents possible threading issues when dirty flag check failed but
+ * data wasn't ready still.
+ */
+ bm->elem_table_dirty &= ~htype_needed;
}
/* use BM_mesh_elem_table_ensure where possible to avoid full rebuild */
void BM_mesh_elem_table_init(BMesh *bm, const char htype)
{
- BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
- /* force recalc */
- BM_mesh_elem_table_free(bm, BM_ALL_NOLOOP);
- BM_mesh_elem_table_ensure(bm, htype);
+ /* force recalc */
+ BM_mesh_elem_table_free(bm, BM_ALL_NOLOOP);
+ BM_mesh_elem_table_ensure(bm, htype);
}
void BM_mesh_elem_table_free(BMesh *bm, const char htype)
{
- if (htype & BM_VERT) {
- MEM_SAFE_FREE(bm->vtable);
- }
+ if (htype & BM_VERT) {
+ MEM_SAFE_FREE(bm->vtable);
+ }
- if (htype & BM_EDGE) {
- MEM_SAFE_FREE(bm->etable);
- }
+ if (htype & BM_EDGE) {
+ MEM_SAFE_FREE(bm->etable);
+ }
- if (htype & BM_FACE) {
- MEM_SAFE_FREE(bm->ftable);
- }
+ if (htype & BM_FACE) {
+ MEM_SAFE_FREE(bm->ftable);
+ }
}
BMVert *BM_vert_at_index_find(BMesh *bm, const int index)
{
- return BLI_mempool_findelem(bm->vpool, index);
+ return BLI_mempool_findelem(bm->vpool, index);
}
BMEdge *BM_edge_at_index_find(BMesh *bm, const int index)
{
- return BLI_mempool_findelem(bm->epool, index);
+ return BLI_mempool_findelem(bm->epool, index);
}
BMFace *BM_face_at_index_find(BMesh *bm, const int index)
{
- return BLI_mempool_findelem(bm->fpool, index);
+ return BLI_mempool_findelem(bm->fpool, index);
}
/**
@@ -1953,55 +2015,55 @@ BMFace *BM_face_at_index_find(BMesh *bm, const int index)
*/
BMVert *BM_vert_at_index_find_or_table(BMesh *bm, const int index)
{
- if ((bm->elem_table_dirty & BM_VERT) == 0) {
- return (index < bm->totvert) ? bm->vtable[index] : NULL;
- }
- else {
- return BM_vert_at_index_find(bm, index);
- }
+ if ((bm->elem_table_dirty & BM_VERT) == 0) {
+ return (index < bm->totvert) ? bm->vtable[index] : NULL;
+ }
+ else {
+ return BM_vert_at_index_find(bm, index);
+ }
}
BMEdge *BM_edge_at_index_find_or_table(BMesh *bm, const int index)
{
- if ((bm->elem_table_dirty & BM_EDGE) == 0) {
- return (index < bm->totedge) ? bm->etable[index] : NULL;
- }
- else {
- return BM_edge_at_index_find(bm, index);
- }
+ if ((bm->elem_table_dirty & BM_EDGE) == 0) {
+ return (index < bm->totedge) ? bm->etable[index] : NULL;
+ }
+ else {
+ return BM_edge_at_index_find(bm, index);
+ }
}
BMFace *BM_face_at_index_find_or_table(BMesh *bm, const int index)
{
- if ((bm->elem_table_dirty & BM_FACE) == 0) {
- return (index < bm->totface) ? bm->ftable[index] : NULL;
- }
- else {
- return BM_face_at_index_find(bm, index);
- }
+ if ((bm->elem_table_dirty & BM_FACE) == 0) {
+ return (index < bm->totface) ? bm->ftable[index] : NULL;
+ }
+ else {
+ return BM_face_at_index_find(bm, index);
+ }
}
-
/**
* Return the amount of element of type 'type' in a given bmesh.
*/
int BM_mesh_elem_count(BMesh *bm, const char htype)
{
- BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
-
- switch (htype) {
- case BM_VERT: return bm->totvert;
- case BM_EDGE: return bm->totedge;
- case BM_FACE: return bm->totface;
- default:
- {
- BLI_assert(0);
- return 0;
- }
- }
+ BLI_assert((htype & ~BM_ALL_NOLOOP) == 0);
+
+ switch (htype) {
+ case BM_VERT:
+ return bm->totvert;
+ case BM_EDGE:
+ return bm->totedge;
+ case BM_FACE:
+ return bm->totface;
+ default: {
+ BLI_assert(0);
+ return 0;
+ }
+ }
}
-
/**
* Remaps the vertices, edges and/or faces of the bmesh as indicated by vert/edge/face_idx arrays
* (xxx_idx[org_index] = new_index).
@@ -2014,281 +2076,277 @@ int BM_mesh_elem_count(BMesh *bm, const char htype)
*
* WARNING: Be careful if you keep pointers to affected BM elements, or arrays, when using this func!
*/
-void BM_mesh_remap(
- BMesh *bm,
- const uint *vert_idx,
- const uint *edge_idx,
- const uint *face_idx)
+void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const uint *face_idx)
{
- /* Mapping old to new pointers. */
- GHash *vptr_map = NULL, *eptr_map = NULL, *fptr_map = NULL;
- BMIter iter, iterl;
- BMVert *ve;
- BMEdge *ed;
- BMFace *fa;
- BMLoop *lo;
-
- if (!(vert_idx || edge_idx || face_idx)) {
- return;
- }
-
- BM_mesh_elem_table_ensure(
- bm,
- (vert_idx ? BM_VERT : 0) |
- (edge_idx ? BM_EDGE : 0) |
- (face_idx ? BM_FACE : 0));
-
- /* Remap Verts */
- if (vert_idx) {
- BMVert **verts_pool, *verts_copy, **vep;
- int i, totvert = bm->totvert;
- const uint *new_idx;
- /* Special case: Python uses custom - data layers to hold PyObject references.
- * These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
- const int cd_vert_pyptr = CustomData_get_offset(&bm->vdata, CD_BM_ELEM_PYPTR);
-
- /* Init the old-to-new vert pointers mapping */
- vptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap vert pointers mapping", bm->totvert);
-
- /* Make a copy of all vertices. */
- verts_pool = bm->vtable;
- verts_copy = MEM_mallocN(sizeof(BMVert) * totvert, "BM_mesh_remap verts copy");
- void **pyptrs = (cd_vert_pyptr != -1) ? MEM_mallocN(sizeof(void *) * totvert, __func__) : NULL;
- for (i = totvert, ve = verts_copy + totvert - 1, vep = verts_pool + totvert - 1; i--; ve--, vep--) {
- *ve = **vep;
-/* printf("*vep: %p, verts_pool[%d]: %p\n", *vep, i, verts_pool[i]);*/
- if (cd_vert_pyptr != -1) {
- void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)ve), cd_vert_pyptr);
- pyptrs[i] = *pyptr;
- }
- }
-
- /* Copy back verts to their new place, and update old2new pointers mapping. */
- new_idx = vert_idx + totvert - 1;
- ve = verts_copy + totvert - 1;
- vep = verts_pool + totvert - 1; /* old, org pointer */
- for (i = totvert; i--; new_idx--, ve--, vep--) {
- BMVert *new_vep = verts_pool[*new_idx];
- *new_vep = *ve;
-/* printf("mapping vert from %d to %d (%p/%p to %p)\n", i, *new_idx, *vep, verts_pool[i], new_vep);*/
- BLI_ghash_insert(vptr_map, *vep, new_vep);
- if (cd_vert_pyptr != -1) {
- void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_vep), cd_vert_pyptr);
- *pyptr = pyptrs[*new_idx];
- }
- }
- bm->elem_index_dirty |= BM_VERT;
- bm->elem_table_dirty |= BM_VERT;
-
- MEM_freeN(verts_copy);
- if (pyptrs) {
- MEM_freeN(pyptrs);
- }
- }
-
- /* Remap Edges */
- if (edge_idx) {
- BMEdge **edges_pool, *edges_copy, **edp;
- int i, totedge = bm->totedge;
- const uint *new_idx;
- /* Special case: Python uses custom - data layers to hold PyObject references.
- * These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
- const int cd_edge_pyptr = CustomData_get_offset(&bm->edata, CD_BM_ELEM_PYPTR);
-
- /* Init the old-to-new vert pointers mapping */
- eptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap edge pointers mapping", bm->totedge);
-
- /* Make a copy of all vertices. */
- edges_pool = bm->etable;
- edges_copy = MEM_mallocN(sizeof(BMEdge) * totedge, "BM_mesh_remap edges copy");
- void **pyptrs = (cd_edge_pyptr != -1) ? MEM_mallocN(sizeof(void *) * totedge, __func__) : NULL;
- for (i = totedge, ed = edges_copy + totedge - 1, edp = edges_pool + totedge - 1; i--; ed--, edp--) {
- *ed = **edp;
- if (cd_edge_pyptr != -1) {
- void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)ed), cd_edge_pyptr);
- pyptrs[i] = *pyptr;
- }
- }
-
- /* Copy back verts to their new place, and update old2new pointers mapping. */
- new_idx = edge_idx + totedge - 1;
- ed = edges_copy + totedge - 1;
- edp = edges_pool + totedge - 1; /* old, org pointer */
- for (i = totedge; i--; new_idx--, ed--, edp--) {
- BMEdge *new_edp = edges_pool[*new_idx];
- *new_edp = *ed;
- BLI_ghash_insert(eptr_map, *edp, new_edp);
-/* printf("mapping edge from %d to %d (%p/%p to %p)\n", i, *new_idx, *edp, edges_pool[i], new_edp);*/
- if (cd_edge_pyptr != -1) {
- void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_edp), cd_edge_pyptr);
- *pyptr = pyptrs[*new_idx];
- }
- }
- bm->elem_index_dirty |= BM_EDGE;
- bm->elem_table_dirty |= BM_EDGE;
-
- MEM_freeN(edges_copy);
- if (pyptrs) {
- MEM_freeN(pyptrs);
- }
- }
-
- /* Remap Faces */
- if (face_idx) {
- BMFace **faces_pool, *faces_copy, **fap;
- int i, totface = bm->totface;
- const uint *new_idx;
- /* Special case: Python uses custom - data layers to hold PyObject references.
- * These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
- const int cd_poly_pyptr = CustomData_get_offset(&bm->pdata, CD_BM_ELEM_PYPTR);
-
- /* Init the old-to-new vert pointers mapping */
- fptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap face pointers mapping", bm->totface);
-
- /* Make a copy of all vertices. */
- faces_pool = bm->ftable;
- faces_copy = MEM_mallocN(sizeof(BMFace) * totface, "BM_mesh_remap faces copy");
- void **pyptrs = (cd_poly_pyptr != -1) ? MEM_mallocN(sizeof(void *) * totface, __func__) : NULL;
- for (i = totface, fa = faces_copy + totface - 1, fap = faces_pool + totface - 1; i--; fa--, fap--) {
- *fa = **fap;
- if (cd_poly_pyptr != -1) {
- void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)fa), cd_poly_pyptr);
- pyptrs[i] = *pyptr;
- }
- }
-
- /* Copy back verts to their new place, and update old2new pointers mapping. */
- new_idx = face_idx + totface - 1;
- fa = faces_copy + totface - 1;
- fap = faces_pool + totface - 1; /* old, org pointer */
- for (i = totface; i--; new_idx--, fa--, fap--) {
- BMFace *new_fap = faces_pool[*new_idx];
- *new_fap = *fa;
- BLI_ghash_insert(fptr_map, *fap, new_fap);
- if (cd_poly_pyptr != -1) {
- void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_fap), cd_poly_pyptr);
- *pyptr = pyptrs[*new_idx];
- }
- }
-
- bm->elem_index_dirty |= BM_FACE | BM_LOOP;
- bm->elem_table_dirty |= BM_FACE;
-
- MEM_freeN(faces_copy);
- if (pyptrs) {
- MEM_freeN(pyptrs);
- }
- }
-
- /* And now, fix all vertices/edges/faces/loops pointers! */
- /* Verts' pointers, only edge pointers... */
- if (eptr_map) {
- BM_ITER_MESH (ve, &iter, bm, BM_VERTS_OF_MESH) {
-/* printf("Vert e: %p -> %p\n", ve->e, BLI_ghash_lookup(eptr_map, ve->e));*/
- if (ve->e) {
- ve->e = BLI_ghash_lookup(eptr_map, ve->e);
- BLI_assert(ve->e);
- }
- }
- }
-
- /* Edges' pointers, only vert pointers (as we don't mess with loops!), and - ack! - edge pointers,
- * as we have to handle disklinks... */
- if (vptr_map || eptr_map) {
- BM_ITER_MESH (ed, &iter, bm, BM_EDGES_OF_MESH) {
- if (vptr_map) {
-/* printf("Edge v1: %p -> %p\n", ed->v1, BLI_ghash_lookup(vptr_map, ed->v1));*/
-/* printf("Edge v2: %p -> %p\n", ed->v2, BLI_ghash_lookup(vptr_map, ed->v2));*/
- ed->v1 = BLI_ghash_lookup(vptr_map, ed->v1);
- ed->v2 = BLI_ghash_lookup(vptr_map, ed->v2);
- BLI_assert(ed->v1);
- BLI_assert(ed->v2);
- }
- if (eptr_map) {
-/* printf("Edge v1_disk_link prev: %p -> %p\n", ed->v1_disk_link.prev,*/
-/* BLI_ghash_lookup(eptr_map, ed->v1_disk_link.prev));*/
-/* printf("Edge v1_disk_link next: %p -> %p\n", ed->v1_disk_link.next,*/
-/* BLI_ghash_lookup(eptr_map, ed->v1_disk_link.next));*/
-/* printf("Edge v2_disk_link prev: %p -> %p\n", ed->v2_disk_link.prev,*/
-/* BLI_ghash_lookup(eptr_map, ed->v2_disk_link.prev));*/
-/* printf("Edge v2_disk_link next: %p -> %p\n", ed->v2_disk_link.next,*/
-/* BLI_ghash_lookup(eptr_map, ed->v2_disk_link.next));*/
- ed->v1_disk_link.prev = BLI_ghash_lookup(eptr_map, ed->v1_disk_link.prev);
- ed->v1_disk_link.next = BLI_ghash_lookup(eptr_map, ed->v1_disk_link.next);
- ed->v2_disk_link.prev = BLI_ghash_lookup(eptr_map, ed->v2_disk_link.prev);
- ed->v2_disk_link.next = BLI_ghash_lookup(eptr_map, ed->v2_disk_link.next);
- BLI_assert(ed->v1_disk_link.prev);
- BLI_assert(ed->v1_disk_link.next);
- BLI_assert(ed->v2_disk_link.prev);
- BLI_assert(ed->v2_disk_link.next);
- }
- }
- }
-
- /* Faces' pointers (loops, in fact), always needed... */
- BM_ITER_MESH (fa, &iter, bm, BM_FACES_OF_MESH) {
- BM_ITER_ELEM (lo, &iterl, fa, BM_LOOPS_OF_FACE) {
- if (vptr_map) {
-/* printf("Loop v: %p -> %p\n", lo->v, BLI_ghash_lookup(vptr_map, lo->v));*/
- lo->v = BLI_ghash_lookup(vptr_map, lo->v);
- BLI_assert(lo->v);
- }
- if (eptr_map) {
-/* printf("Loop e: %p -> %p\n", lo->e, BLI_ghash_lookup(eptr_map, lo->e));*/
- lo->e = BLI_ghash_lookup(eptr_map, lo->e);
- BLI_assert(lo->e);
- }
- if (fptr_map) {
-/* printf("Loop f: %p -> %p\n", lo->f, BLI_ghash_lookup(fptr_map, lo->f));*/
- lo->f = BLI_ghash_lookup(fptr_map, lo->f);
- BLI_assert(lo->f);
- }
- }
- }
-
- /* Selection history */
- {
- BMEditSelection *ese;
- for (ese = bm->selected.first; ese; ese = ese->next) {
- switch (ese->htype) {
- case BM_VERT:
- if (vptr_map) {
- ese->ele = BLI_ghash_lookup(vptr_map, ese->ele);
- BLI_assert(ese->ele);
- }
- break;
- case BM_EDGE:
- if (eptr_map) {
- ese->ele = BLI_ghash_lookup(eptr_map, ese->ele);
- BLI_assert(ese->ele);
- }
- break;
- case BM_FACE:
- if (fptr_map) {
- ese->ele = BLI_ghash_lookup(fptr_map, ese->ele);
- BLI_assert(ese->ele);
- }
- break;
- }
- }
- }
-
- if (fptr_map) {
- if (bm->act_face) {
- bm->act_face = BLI_ghash_lookup(fptr_map, bm->act_face);
- BLI_assert(bm->act_face);
- }
- }
-
- if (vptr_map) {
- BLI_ghash_free(vptr_map, NULL, NULL);
- }
- if (eptr_map) {
- BLI_ghash_free(eptr_map, NULL, NULL);
- }
- if (fptr_map) {
- BLI_ghash_free(fptr_map, NULL, NULL);
- }
+ /* Mapping old to new pointers. */
+ GHash *vptr_map = NULL, *eptr_map = NULL, *fptr_map = NULL;
+ BMIter iter, iterl;
+ BMVert *ve;
+ BMEdge *ed;
+ BMFace *fa;
+ BMLoop *lo;
+
+ if (!(vert_idx || edge_idx || face_idx)) {
+ return;
+ }
+
+ BM_mesh_elem_table_ensure(
+ bm, (vert_idx ? BM_VERT : 0) | (edge_idx ? BM_EDGE : 0) | (face_idx ? BM_FACE : 0));
+
+ /* Remap Verts */
+ if (vert_idx) {
+ BMVert **verts_pool, *verts_copy, **vep;
+ int i, totvert = bm->totvert;
+ const uint *new_idx;
+ /* Special case: Python uses custom - data layers to hold PyObject references.
+ * These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
+ const int cd_vert_pyptr = CustomData_get_offset(&bm->vdata, CD_BM_ELEM_PYPTR);
+
+ /* Init the old-to-new vert pointers mapping */
+ vptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap vert pointers mapping", bm->totvert);
+
+ /* Make a copy of all vertices. */
+ verts_pool = bm->vtable;
+ verts_copy = MEM_mallocN(sizeof(BMVert) * totvert, "BM_mesh_remap verts copy");
+ void **pyptrs = (cd_vert_pyptr != -1) ? MEM_mallocN(sizeof(void *) * totvert, __func__) : NULL;
+ for (i = totvert, ve = verts_copy + totvert - 1, vep = verts_pool + totvert - 1; i--;
+ ve--, vep--) {
+ *ve = **vep;
+ /* printf("*vep: %p, verts_pool[%d]: %p\n", *vep, i, verts_pool[i]);*/
+ if (cd_vert_pyptr != -1) {
+ void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)ve), cd_vert_pyptr);
+ pyptrs[i] = *pyptr;
+ }
+ }
+
+ /* Copy back verts to their new place, and update old2new pointers mapping. */
+ new_idx = vert_idx + totvert - 1;
+ ve = verts_copy + totvert - 1;
+ vep = verts_pool + totvert - 1; /* old, org pointer */
+ for (i = totvert; i--; new_idx--, ve--, vep--) {
+ BMVert *new_vep = verts_pool[*new_idx];
+ *new_vep = *ve;
+ /* printf("mapping vert from %d to %d (%p/%p to %p)\n", i, *new_idx, *vep, verts_pool[i], new_vep);*/
+ BLI_ghash_insert(vptr_map, *vep, new_vep);
+ if (cd_vert_pyptr != -1) {
+ void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_vep), cd_vert_pyptr);
+ *pyptr = pyptrs[*new_idx];
+ }
+ }
+ bm->elem_index_dirty |= BM_VERT;
+ bm->elem_table_dirty |= BM_VERT;
+
+ MEM_freeN(verts_copy);
+ if (pyptrs) {
+ MEM_freeN(pyptrs);
+ }
+ }
+
+ /* Remap Edges */
+ if (edge_idx) {
+ BMEdge **edges_pool, *edges_copy, **edp;
+ int i, totedge = bm->totedge;
+ const uint *new_idx;
+ /* Special case: Python uses custom - data layers to hold PyObject references.
+ * These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
+ const int cd_edge_pyptr = CustomData_get_offset(&bm->edata, CD_BM_ELEM_PYPTR);
+
+ /* Init the old-to-new vert pointers mapping */
+ eptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap edge pointers mapping", bm->totedge);
+
+ /* Make a copy of all vertices. */
+ edges_pool = bm->etable;
+ edges_copy = MEM_mallocN(sizeof(BMEdge) * totedge, "BM_mesh_remap edges copy");
+ void **pyptrs = (cd_edge_pyptr != -1) ? MEM_mallocN(sizeof(void *) * totedge, __func__) : NULL;
+ for (i = totedge, ed = edges_copy + totedge - 1, edp = edges_pool + totedge - 1; i--;
+ ed--, edp--) {
+ *ed = **edp;
+ if (cd_edge_pyptr != -1) {
+ void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)ed), cd_edge_pyptr);
+ pyptrs[i] = *pyptr;
+ }
+ }
+
+ /* Copy back verts to their new place, and update old2new pointers mapping. */
+ new_idx = edge_idx + totedge - 1;
+ ed = edges_copy + totedge - 1;
+ edp = edges_pool + totedge - 1; /* old, org pointer */
+ for (i = totedge; i--; new_idx--, ed--, edp--) {
+ BMEdge *new_edp = edges_pool[*new_idx];
+ *new_edp = *ed;
+ BLI_ghash_insert(eptr_map, *edp, new_edp);
+ /* printf("mapping edge from %d to %d (%p/%p to %p)\n", i, *new_idx, *edp, edges_pool[i], new_edp);*/
+ if (cd_edge_pyptr != -1) {
+ void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_edp), cd_edge_pyptr);
+ *pyptr = pyptrs[*new_idx];
+ }
+ }
+ bm->elem_index_dirty |= BM_EDGE;
+ bm->elem_table_dirty |= BM_EDGE;
+
+ MEM_freeN(edges_copy);
+ if (pyptrs) {
+ MEM_freeN(pyptrs);
+ }
+ }
+
+ /* Remap Faces */
+ if (face_idx) {
+ BMFace **faces_pool, *faces_copy, **fap;
+ int i, totface = bm->totface;
+ const uint *new_idx;
+ /* Special case: Python uses custom - data layers to hold PyObject references.
+ * These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
+ const int cd_poly_pyptr = CustomData_get_offset(&bm->pdata, CD_BM_ELEM_PYPTR);
+
+ /* Init the old-to-new vert pointers mapping */
+ fptr_map = BLI_ghash_ptr_new_ex("BM_mesh_remap face pointers mapping", bm->totface);
+
+ /* Make a copy of all vertices. */
+ faces_pool = bm->ftable;
+ faces_copy = MEM_mallocN(sizeof(BMFace) * totface, "BM_mesh_remap faces copy");
+ void **pyptrs = (cd_poly_pyptr != -1) ? MEM_mallocN(sizeof(void *) * totface, __func__) : NULL;
+ for (i = totface, fa = faces_copy + totface - 1, fap = faces_pool + totface - 1; i--;
+ fa--, fap--) {
+ *fa = **fap;
+ if (cd_poly_pyptr != -1) {
+ void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)fa), cd_poly_pyptr);
+ pyptrs[i] = *pyptr;
+ }
+ }
+
+ /* Copy back verts to their new place, and update old2new pointers mapping. */
+ new_idx = face_idx + totface - 1;
+ fa = faces_copy + totface - 1;
+ fap = faces_pool + totface - 1; /* old, org pointer */
+ for (i = totface; i--; new_idx--, fa--, fap--) {
+ BMFace *new_fap = faces_pool[*new_idx];
+ *new_fap = *fa;
+ BLI_ghash_insert(fptr_map, *fap, new_fap);
+ if (cd_poly_pyptr != -1) {
+ void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_fap), cd_poly_pyptr);
+ *pyptr = pyptrs[*new_idx];
+ }
+ }
+
+ bm->elem_index_dirty |= BM_FACE | BM_LOOP;
+ bm->elem_table_dirty |= BM_FACE;
+
+ MEM_freeN(faces_copy);
+ if (pyptrs) {
+ MEM_freeN(pyptrs);
+ }
+ }
+
+ /* And now, fix all vertices/edges/faces/loops pointers! */
+ /* Verts' pointers, only edge pointers... */
+ if (eptr_map) {
+ BM_ITER_MESH (ve, &iter, bm, BM_VERTS_OF_MESH) {
+ /* printf("Vert e: %p -> %p\n", ve->e, BLI_ghash_lookup(eptr_map, ve->e));*/
+ if (ve->e) {
+ ve->e = BLI_ghash_lookup(eptr_map, ve->e);
+ BLI_assert(ve->e);
+ }
+ }
+ }
+
+ /* Edges' pointers, only vert pointers (as we don't mess with loops!), and - ack! - edge pointers,
+ * as we have to handle disklinks... */
+ if (vptr_map || eptr_map) {
+ BM_ITER_MESH (ed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (vptr_map) {
+ /* printf("Edge v1: %p -> %p\n", ed->v1, BLI_ghash_lookup(vptr_map, ed->v1));*/
+ /* printf("Edge v2: %p -> %p\n", ed->v2, BLI_ghash_lookup(vptr_map, ed->v2));*/
+ ed->v1 = BLI_ghash_lookup(vptr_map, ed->v1);
+ ed->v2 = BLI_ghash_lookup(vptr_map, ed->v2);
+ BLI_assert(ed->v1);
+ BLI_assert(ed->v2);
+ }
+ if (eptr_map) {
+ /* printf("Edge v1_disk_link prev: %p -> %p\n", ed->v1_disk_link.prev,*/
+ /* BLI_ghash_lookup(eptr_map, ed->v1_disk_link.prev));*/
+ /* printf("Edge v1_disk_link next: %p -> %p\n", ed->v1_disk_link.next,*/
+ /* BLI_ghash_lookup(eptr_map, ed->v1_disk_link.next));*/
+ /* printf("Edge v2_disk_link prev: %p -> %p\n", ed->v2_disk_link.prev,*/
+ /* BLI_ghash_lookup(eptr_map, ed->v2_disk_link.prev));*/
+ /* printf("Edge v2_disk_link next: %p -> %p\n", ed->v2_disk_link.next,*/
+ /* BLI_ghash_lookup(eptr_map, ed->v2_disk_link.next));*/
+ ed->v1_disk_link.prev = BLI_ghash_lookup(eptr_map, ed->v1_disk_link.prev);
+ ed->v1_disk_link.next = BLI_ghash_lookup(eptr_map, ed->v1_disk_link.next);
+ ed->v2_disk_link.prev = BLI_ghash_lookup(eptr_map, ed->v2_disk_link.prev);
+ ed->v2_disk_link.next = BLI_ghash_lookup(eptr_map, ed->v2_disk_link.next);
+ BLI_assert(ed->v1_disk_link.prev);
+ BLI_assert(ed->v1_disk_link.next);
+ BLI_assert(ed->v2_disk_link.prev);
+ BLI_assert(ed->v2_disk_link.next);
+ }
+ }
+ }
+
+ /* Faces' pointers (loops, in fact), always needed... */
+ BM_ITER_MESH (fa, &iter, bm, BM_FACES_OF_MESH) {
+ BM_ITER_ELEM (lo, &iterl, fa, BM_LOOPS_OF_FACE) {
+ if (vptr_map) {
+ /* printf("Loop v: %p -> %p\n", lo->v, BLI_ghash_lookup(vptr_map, lo->v));*/
+ lo->v = BLI_ghash_lookup(vptr_map, lo->v);
+ BLI_assert(lo->v);
+ }
+ if (eptr_map) {
+ /* printf("Loop e: %p -> %p\n", lo->e, BLI_ghash_lookup(eptr_map, lo->e));*/
+ lo->e = BLI_ghash_lookup(eptr_map, lo->e);
+ BLI_assert(lo->e);
+ }
+ if (fptr_map) {
+ /* printf("Loop f: %p -> %p\n", lo->f, BLI_ghash_lookup(fptr_map, lo->f));*/
+ lo->f = BLI_ghash_lookup(fptr_map, lo->f);
+ BLI_assert(lo->f);
+ }
+ }
+ }
+
+ /* Selection history */
+ {
+ BMEditSelection *ese;
+ for (ese = bm->selected.first; ese; ese = ese->next) {
+ switch (ese->htype) {
+ case BM_VERT:
+ if (vptr_map) {
+ ese->ele = BLI_ghash_lookup(vptr_map, ese->ele);
+ BLI_assert(ese->ele);
+ }
+ break;
+ case BM_EDGE:
+ if (eptr_map) {
+ ese->ele = BLI_ghash_lookup(eptr_map, ese->ele);
+ BLI_assert(ese->ele);
+ }
+ break;
+ case BM_FACE:
+ if (fptr_map) {
+ ese->ele = BLI_ghash_lookup(fptr_map, ese->ele);
+ BLI_assert(ese->ele);
+ }
+ break;
+ }
+ }
+ }
+
+ if (fptr_map) {
+ if (bm->act_face) {
+ bm->act_face = BLI_ghash_lookup(fptr_map, bm->act_face);
+ BLI_assert(bm->act_face);
+ }
+ }
+
+ if (vptr_map) {
+ BLI_ghash_free(vptr_map, NULL, NULL);
+ }
+ if (eptr_map) {
+ BLI_ghash_free(eptr_map, NULL, NULL);
+ }
+ if (fptr_map) {
+ BLI_ghash_free(fptr_map, NULL, NULL);
+ }
}
/**
@@ -2297,168 +2355,202 @@ void BM_mesh_remap(
* \note needed for re-sizing elements (adding/removing tool flags)
* but could also be used for packing fragmented bmeshes.
*/
-void BM_mesh_rebuild(
- BMesh *bm, const struct BMeshCreateParams *params,
- BLI_mempool *vpool_dst, BLI_mempool *epool_dst, BLI_mempool *lpool_dst, BLI_mempool *fpool_dst)
+void BM_mesh_rebuild(BMesh *bm,
+ const struct BMeshCreateParams *params,
+ BLI_mempool *vpool_dst,
+ BLI_mempool *epool_dst,
+ BLI_mempool *lpool_dst,
+ BLI_mempool *fpool_dst)
{
- const char remap =
- (vpool_dst ? BM_VERT : 0) |
- (epool_dst ? BM_EDGE : 0) |
- (lpool_dst ? BM_LOOP : 0) |
- (fpool_dst ? BM_FACE : 0);
-
- BMVert **vtable_dst = (remap & BM_VERT) ? MEM_mallocN(bm->totvert * sizeof(BMVert *), __func__) : NULL;
- BMEdge **etable_dst = (remap & BM_EDGE) ? MEM_mallocN(bm->totedge * sizeof(BMEdge *), __func__) : NULL;
- BMLoop **ltable_dst = (remap & BM_LOOP) ? MEM_mallocN(bm->totloop * sizeof(BMLoop *), __func__) : NULL;
- BMFace **ftable_dst = (remap & BM_FACE) ? MEM_mallocN(bm->totface * sizeof(BMFace *), __func__) : NULL;
-
- const bool use_toolflags = params->use_toolflags;
-
- if (remap & BM_VERT) {
- BMIter iter;
- int index;
- BMVert *v_src;
- BM_ITER_MESH_INDEX (v_src, &iter, bm, BM_VERTS_OF_MESH, index) {
- BMVert *v_dst = BLI_mempool_alloc(vpool_dst);
- memcpy(v_dst, v_src, sizeof(BMVert));
- if (use_toolflags) {
- ((BMVert_OFlag *)v_dst)->oflags = bm->vtoolflagpool ? BLI_mempool_calloc(bm->vtoolflagpool) : NULL;
- }
-
- vtable_dst[index] = v_dst;
- BM_elem_index_set(v_src, index); /* set_ok */
- }
- }
-
- if (remap & BM_EDGE) {
- BMIter iter;
- int index;
- BMEdge *e_src;
- BM_ITER_MESH_INDEX (e_src, &iter, bm, BM_EDGES_OF_MESH, index) {
- BMEdge *e_dst = BLI_mempool_alloc(epool_dst);
- memcpy(e_dst, e_src, sizeof(BMEdge));
- if (use_toolflags) {
- ((BMEdge_OFlag *)e_dst)->oflags = bm->etoolflagpool ? BLI_mempool_calloc(bm->etoolflagpool) : NULL;
- }
-
- etable_dst[index] = e_dst;
- BM_elem_index_set(e_src, index); /* set_ok */
- }
- }
-
- if (remap & (BM_LOOP | BM_FACE)) {
- BMIter iter;
- int index, index_loop = 0;
- BMFace *f_src;
- BM_ITER_MESH_INDEX (f_src, &iter, bm, BM_FACES_OF_MESH, index) {
-
- if (remap & BM_FACE) {
- BMFace *f_dst = BLI_mempool_alloc(fpool_dst);
- memcpy(f_dst, f_src, sizeof(BMFace));
- if (use_toolflags) {
- ((BMFace_OFlag *)f_dst)->oflags = bm->ftoolflagpool ? BLI_mempool_calloc(bm->ftoolflagpool) : NULL;
- }
-
- ftable_dst[index] = f_dst;
- BM_elem_index_set(f_src, index); /* set_ok */
- }
-
- /* handle loops */
- if (remap & BM_LOOP) {
- BMLoop *l_iter_src, *l_first_src;
- l_iter_src = l_first_src = BM_FACE_FIRST_LOOP((BMFace *)f_src);
- do {
- BMLoop *l_dst = BLI_mempool_alloc(lpool_dst);
- memcpy(l_dst, l_iter_src, sizeof(BMLoop));
- ltable_dst[index_loop] = l_dst;
- BM_elem_index_set(l_iter_src, index_loop++); /* set_ok */
- } while ((l_iter_src = l_iter_src->next) != l_first_src);
- }
- }
- }
+ const char remap = (vpool_dst ? BM_VERT : 0) | (epool_dst ? BM_EDGE : 0) |
+ (lpool_dst ? BM_LOOP : 0) | (fpool_dst ? BM_FACE : 0);
+
+ BMVert **vtable_dst = (remap & BM_VERT) ? MEM_mallocN(bm->totvert * sizeof(BMVert *), __func__) :
+ NULL;
+ BMEdge **etable_dst = (remap & BM_EDGE) ? MEM_mallocN(bm->totedge * sizeof(BMEdge *), __func__) :
+ NULL;
+ BMLoop **ltable_dst = (remap & BM_LOOP) ? MEM_mallocN(bm->totloop * sizeof(BMLoop *), __func__) :
+ NULL;
+ BMFace **ftable_dst = (remap & BM_FACE) ? MEM_mallocN(bm->totface * sizeof(BMFace *), __func__) :
+ NULL;
+
+ const bool use_toolflags = params->use_toolflags;
+
+ if (remap & BM_VERT) {
+ BMIter iter;
+ int index;
+ BMVert *v_src;
+ BM_ITER_MESH_INDEX (v_src, &iter, bm, BM_VERTS_OF_MESH, index) {
+ BMVert *v_dst = BLI_mempool_alloc(vpool_dst);
+ memcpy(v_dst, v_src, sizeof(BMVert));
+ if (use_toolflags) {
+ ((BMVert_OFlag *)v_dst)->oflags = bm->vtoolflagpool ?
+ BLI_mempool_calloc(bm->vtoolflagpool) :
+ NULL;
+ }
+
+ vtable_dst[index] = v_dst;
+ BM_elem_index_set(v_src, index); /* set_ok */
+ }
+ }
+
+ if (remap & BM_EDGE) {
+ BMIter iter;
+ int index;
+ BMEdge *e_src;
+ BM_ITER_MESH_INDEX (e_src, &iter, bm, BM_EDGES_OF_MESH, index) {
+ BMEdge *e_dst = BLI_mempool_alloc(epool_dst);
+ memcpy(e_dst, e_src, sizeof(BMEdge));
+ if (use_toolflags) {
+ ((BMEdge_OFlag *)e_dst)->oflags = bm->etoolflagpool ?
+ BLI_mempool_calloc(bm->etoolflagpool) :
+ NULL;
+ }
+
+ etable_dst[index] = e_dst;
+ BM_elem_index_set(e_src, index); /* set_ok */
+ }
+ }
+
+ if (remap & (BM_LOOP | BM_FACE)) {
+ BMIter iter;
+ int index, index_loop = 0;
+ BMFace *f_src;
+ BM_ITER_MESH_INDEX (f_src, &iter, bm, BM_FACES_OF_MESH, index) {
+
+ if (remap & BM_FACE) {
+ BMFace *f_dst = BLI_mempool_alloc(fpool_dst);
+ memcpy(f_dst, f_src, sizeof(BMFace));
+ if (use_toolflags) {
+ ((BMFace_OFlag *)f_dst)->oflags = bm->ftoolflagpool ?
+ BLI_mempool_calloc(bm->ftoolflagpool) :
+ NULL;
+ }
+
+ ftable_dst[index] = f_dst;
+ BM_elem_index_set(f_src, index); /* set_ok */
+ }
+
+ /* handle loops */
+ if (remap & BM_LOOP) {
+ BMLoop *l_iter_src, *l_first_src;
+ l_iter_src = l_first_src = BM_FACE_FIRST_LOOP((BMFace *)f_src);
+ do {
+ BMLoop *l_dst = BLI_mempool_alloc(lpool_dst);
+ memcpy(l_dst, l_iter_src, sizeof(BMLoop));
+ ltable_dst[index_loop] = l_dst;
+ BM_elem_index_set(l_iter_src, index_loop++); /* set_ok */
+ } while ((l_iter_src = l_iter_src->next) != l_first_src);
+ }
+ }
+ }
#define MAP_VERT(ele) vtable_dst[BM_elem_index_get(ele)]
#define MAP_EDGE(ele) etable_dst[BM_elem_index_get(ele)]
#define MAP_LOOP(ele) ltable_dst[BM_elem_index_get(ele)]
#define MAP_FACE(ele) ftable_dst[BM_elem_index_get(ele)]
-#define REMAP_VERT(ele) { if (remap & BM_VERT) { ele = MAP_VERT(ele); }} ((void)0)
-#define REMAP_EDGE(ele) { if (remap & BM_EDGE) { ele = MAP_EDGE(ele); }} ((void)0)
-#define REMAP_LOOP(ele) { if (remap & BM_LOOP) { ele = MAP_LOOP(ele); }} ((void)0)
-#define REMAP_FACE(ele) { if (remap & BM_FACE) { ele = MAP_FACE(ele); }} ((void)0)
-
- /* verts */
- {
- for (int i = 0; i < bm->totvert; i++) {
- BMVert *v = vtable_dst[i];
- if (v->e) {
- REMAP_EDGE(v->e);
- }
- }
- }
-
- /* edges */
- {
- for (int i = 0; i < bm->totedge; i++) {
- BMEdge *e = etable_dst[i];
- REMAP_VERT(e->v1);
- REMAP_VERT(e->v2);
- REMAP_EDGE(e->v1_disk_link.next);
- REMAP_EDGE(e->v1_disk_link.prev);
- REMAP_EDGE(e->v2_disk_link.next);
- REMAP_EDGE(e->v2_disk_link.prev);
- if (e->l) {
- REMAP_LOOP(e->l);
- }
- }
- }
-
- /* faces */
- {
- for (int i = 0; i < bm->totface; i++) {
- BMFace *f = ftable_dst[i];
- REMAP_LOOP(f->l_first);
-
- {
- BMLoop *l_iter, *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP((BMFace *)f);
- do {
- REMAP_VERT(l_iter->v);
- REMAP_EDGE(l_iter->e);
- REMAP_FACE(l_iter->f);
-
- REMAP_LOOP(l_iter->radial_next);
- REMAP_LOOP(l_iter->radial_prev);
- REMAP_LOOP(l_iter->next);
- REMAP_LOOP(l_iter->prev);
- } while ((l_iter = l_iter->next) != l_first);
- }
- }
- }
-
- for (BMEditSelection *ese = bm->selected.first; ese; ese = ese->next) {
- switch (ese->htype) {
- case BM_VERT:
- if (remap & BM_VERT) {
- ese->ele = (BMElem *)MAP_VERT(ese->ele);
- }
- break;
- case BM_EDGE:
- if (remap & BM_EDGE) {
- ese->ele = (BMElem *)MAP_EDGE(ese->ele);
- }
- break;
- case BM_FACE:
- if (remap & BM_FACE) {
- ese->ele = (BMElem *)MAP_FACE(ese->ele);
- }
- break;
- }
- }
-
- if (bm->act_face) {
- REMAP_FACE(bm->act_face);
- }
+#define REMAP_VERT(ele) \
+ { \
+ if (remap & BM_VERT) { \
+ ele = MAP_VERT(ele); \
+ } \
+ } \
+ ((void)0)
+#define REMAP_EDGE(ele) \
+ { \
+ if (remap & BM_EDGE) { \
+ ele = MAP_EDGE(ele); \
+ } \
+ } \
+ ((void)0)
+#define REMAP_LOOP(ele) \
+ { \
+ if (remap & BM_LOOP) { \
+ ele = MAP_LOOP(ele); \
+ } \
+ } \
+ ((void)0)
+#define REMAP_FACE(ele) \
+ { \
+ if (remap & BM_FACE) { \
+ ele = MAP_FACE(ele); \
+ } \
+ } \
+ ((void)0)
+
+ /* verts */
+ {
+ for (int i = 0; i < bm->totvert; i++) {
+ BMVert *v = vtable_dst[i];
+ if (v->e) {
+ REMAP_EDGE(v->e);
+ }
+ }
+ }
+
+ /* edges */
+ {
+ for (int i = 0; i < bm->totedge; i++) {
+ BMEdge *e = etable_dst[i];
+ REMAP_VERT(e->v1);
+ REMAP_VERT(e->v2);
+ REMAP_EDGE(e->v1_disk_link.next);
+ REMAP_EDGE(e->v1_disk_link.prev);
+ REMAP_EDGE(e->v2_disk_link.next);
+ REMAP_EDGE(e->v2_disk_link.prev);
+ if (e->l) {
+ REMAP_LOOP(e->l);
+ }
+ }
+ }
+
+ /* faces */
+ {
+ for (int i = 0; i < bm->totface; i++) {
+ BMFace *f = ftable_dst[i];
+ REMAP_LOOP(f->l_first);
+
+ {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP((BMFace *)f);
+ do {
+ REMAP_VERT(l_iter->v);
+ REMAP_EDGE(l_iter->e);
+ REMAP_FACE(l_iter->f);
+
+ REMAP_LOOP(l_iter->radial_next);
+ REMAP_LOOP(l_iter->radial_prev);
+ REMAP_LOOP(l_iter->next);
+ REMAP_LOOP(l_iter->prev);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+ }
+
+ for (BMEditSelection *ese = bm->selected.first; ese; ese = ese->next) {
+ switch (ese->htype) {
+ case BM_VERT:
+ if (remap & BM_VERT) {
+ ese->ele = (BMElem *)MAP_VERT(ese->ele);
+ }
+ break;
+ case BM_EDGE:
+ if (remap & BM_EDGE) {
+ ese->ele = (BMElem *)MAP_EDGE(ese->ele);
+ }
+ break;
+ case BM_FACE:
+ if (remap & BM_FACE) {
+ ese->ele = (BMElem *)MAP_FACE(ese->ele);
+ }
+ break;
+ }
+ }
+
+ if (bm->act_face) {
+ REMAP_FACE(bm->act_face);
+ }
#undef MAP_VERT
#undef MAP_EDGE
@@ -2470,47 +2562,47 @@ void BM_mesh_rebuild(
#undef REMAP_LOOP
#undef REMAP_EDGE
- /* Cleanup, re-use local tables if the current mesh had tables allocated.
- * could use irrespective but it may use more memory then the caller wants (and not be needed). */
- if (remap & BM_VERT) {
- if (bm->vtable) {
- SWAP(BMVert **, vtable_dst, bm->vtable);
- bm->vtable_tot = bm->totvert;
- bm->elem_table_dirty &= ~BM_VERT;
- }
- MEM_freeN(vtable_dst);
- BLI_mempool_destroy(bm->vpool);
- bm->vpool = vpool_dst;
- }
-
- if (remap & BM_EDGE) {
- if (bm->etable) {
- SWAP(BMEdge **, etable_dst, bm->etable);
- bm->etable_tot = bm->totedge;
- bm->elem_table_dirty &= ~BM_EDGE;
- }
- MEM_freeN(etable_dst);
- BLI_mempool_destroy(bm->epool);
- bm->epool = epool_dst;
- }
-
- if (remap & BM_LOOP) {
- /* no loop table */
- MEM_freeN(ltable_dst);
- BLI_mempool_destroy(bm->lpool);
- bm->lpool = lpool_dst;
- }
-
- if (remap & BM_FACE) {
- if (bm->ftable) {
- SWAP(BMFace **, ftable_dst, bm->ftable);
- bm->ftable_tot = bm->totface;
- bm->elem_table_dirty &= ~BM_FACE;
- }
- MEM_freeN(ftable_dst);
- BLI_mempool_destroy(bm->fpool);
- bm->fpool = fpool_dst;
- }
+ /* Cleanup, re-use local tables if the current mesh had tables allocated.
+ * could use irrespective but it may use more memory then the caller wants (and not be needed). */
+ if (remap & BM_VERT) {
+ if (bm->vtable) {
+ SWAP(BMVert **, vtable_dst, bm->vtable);
+ bm->vtable_tot = bm->totvert;
+ bm->elem_table_dirty &= ~BM_VERT;
+ }
+ MEM_freeN(vtable_dst);
+ BLI_mempool_destroy(bm->vpool);
+ bm->vpool = vpool_dst;
+ }
+
+ if (remap & BM_EDGE) {
+ if (bm->etable) {
+ SWAP(BMEdge **, etable_dst, bm->etable);
+ bm->etable_tot = bm->totedge;
+ bm->elem_table_dirty &= ~BM_EDGE;
+ }
+ MEM_freeN(etable_dst);
+ BLI_mempool_destroy(bm->epool);
+ bm->epool = epool_dst;
+ }
+
+ if (remap & BM_LOOP) {
+ /* no loop table */
+ MEM_freeN(ltable_dst);
+ BLI_mempool_destroy(bm->lpool);
+ bm->lpool = lpool_dst;
+ }
+
+ if (remap & BM_FACE) {
+ if (bm->ftable) {
+ SWAP(BMFace **, ftable_dst, bm->ftable);
+ bm->ftable_tot = bm->totface;
+ bm->elem_table_dirty &= ~BM_FACE;
+ }
+ MEM_freeN(ftable_dst);
+ BLI_mempool_destroy(bm->fpool);
+ bm->fpool = fpool_dst;
+ }
}
/**
@@ -2518,34 +2610,36 @@ void BM_mesh_rebuild(
*/
void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags)
{
- if (bm->use_toolflags == use_toolflags) {
- return;
- }
-
- const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_BM(bm);
-
- BLI_mempool *vpool_dst = NULL;
- BLI_mempool *epool_dst = NULL;
- BLI_mempool *fpool_dst = NULL;
-
- bm_mempool_init_ex(
- &allocsize, use_toolflags,
- &vpool_dst, &epool_dst, NULL, &fpool_dst);
-
- if (use_toolflags == false) {
- BLI_mempool_destroy(bm->vtoolflagpool);
- BLI_mempool_destroy(bm->etoolflagpool);
- BLI_mempool_destroy(bm->ftoolflagpool);
-
- bm->vtoolflagpool = NULL;
- bm->etoolflagpool = NULL;
- bm->ftoolflagpool = NULL;
- }
-
- BM_mesh_rebuild(
- bm,
- &((struct BMeshCreateParams){.use_toolflags = use_toolflags,}),
- vpool_dst, epool_dst, NULL, fpool_dst);
-
- bm->use_toolflags = use_toolflags;
+ if (bm->use_toolflags == use_toolflags) {
+ return;
+ }
+
+ const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_BM(bm);
+
+ BLI_mempool *vpool_dst = NULL;
+ BLI_mempool *epool_dst = NULL;
+ BLI_mempool *fpool_dst = NULL;
+
+ bm_mempool_init_ex(&allocsize, use_toolflags, &vpool_dst, &epool_dst, NULL, &fpool_dst);
+
+ if (use_toolflags == false) {
+ BLI_mempool_destroy(bm->vtoolflagpool);
+ BLI_mempool_destroy(bm->etoolflagpool);
+ BLI_mempool_destroy(bm->ftoolflagpool);
+
+ bm->vtoolflagpool = NULL;
+ bm->etoolflagpool = NULL;
+ bm->ftoolflagpool = NULL;
+ }
+
+ BM_mesh_rebuild(bm,
+ &((struct BMeshCreateParams){
+ .use_toolflags = use_toolflags,
+ }),
+ vpool_dst,
+ epool_dst,
+ NULL,
+ fpool_dst);
+
+ bm->use_toolflags = use_toolflags;
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 6f340411b00..d0cf50a7894 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -25,31 +25,39 @@ struct BMAllocTemplate;
struct BMLoopNorEditDataArray;
struct MLoopNorSpaceArray;
-void BM_mesh_elem_toolflags_ensure(BMesh *bm);
-void BM_mesh_elem_toolflags_clear(BMesh *bm);
+void BM_mesh_elem_toolflags_ensure(BMesh *bm);
+void BM_mesh_elem_toolflags_clear(BMesh *bm);
struct BMeshCreateParams {
- uint use_toolflags : 1;
+ uint use_toolflags : 1;
};
-BMesh *BM_mesh_create(
- const struct BMAllocTemplate *allocsize,
- const struct BMeshCreateParams *params);
+BMesh *BM_mesh_create(const struct BMAllocTemplate *allocsize,
+ const struct BMeshCreateParams *params);
-void BM_mesh_free(BMesh *bm);
-void BM_mesh_data_free(BMesh *bm);
-void BM_mesh_clear(BMesh *bm);
+void BM_mesh_free(BMesh *bm);
+void BM_mesh_data_free(BMesh *bm);
+void BM_mesh_clear(BMesh *bm);
void BM_mesh_normals_update(BMesh *bm);
-void BM_verts_calc_normal_vcos(BMesh *bm, const float (*fnos)[3], const float (*vcos)[3], float (*vnos)[3]);
-void BM_loops_calc_normal_vcos(
- BMesh *bm, const float(*vcos)[3], const float(*vnos)[3], const float(*pnos)[3],
- const bool use_split_normals, const float split_angle, float(*r_lnos)[3],
- struct MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2],
- const int cd_loop_clnors_offset, const bool do_rebuild);
+void BM_verts_calc_normal_vcos(BMesh *bm,
+ const float (*fnos)[3],
+ const float (*vcos)[3],
+ float (*vnos)[3]);
+void BM_loops_calc_normal_vcos(BMesh *bm,
+ const float (*vcos)[3],
+ const float (*vnos)[3],
+ const float (*pnos)[3],
+ const bool use_split_normals,
+ const float split_angle,
+ float (*r_lnos)[3],
+ struct MLoopNorSpaceArray *r_lnors_spacearr,
+ short (*clnors_data)[2],
+ const int cd_loop_clnors_offset,
+ const bool do_rebuild);
bool BM_loop_check_cyclic_smooth_fan(BMLoop *l_curr);
-void BM_lnorspacearr_store(BMesh *bm, float(*r_lnors)[3]);
+void BM_lnorspacearr_store(BMesh *bm, float (*r_lnors)[3]);
void BM_lnorspace_invalidate(BMesh *bm, const bool do_invalidate_all);
void BM_lnorspace_rebuild(BMesh *bm, bool preserve_clnor);
void BM_lnorspace_update(BMesh *bm);
@@ -63,7 +71,6 @@ struct BMLoopNorEditDataArray *BM_loop_normal_editdata_array_init(BMesh *bm);
void BM_loop_normal_editdata_array_free(struct BMLoopNorEditDataArray *lnors_ed_arr);
int BM_total_loop_select(BMesh *bm);
-
void BM_edges_sharp_from_angle_set(BMesh *bm, const float split_angle);
void bmesh_edit_begin(BMesh *bm, const BMOpTypeFlag type_flag);
@@ -72,8 +79,7 @@ void bmesh_edit_end(BMesh *bm, const BMOpTypeFlag type_flag);
void BM_mesh_elem_index_ensure_ex(BMesh *bm, const char htype, int elem_offset[4]);
void BM_mesh_elem_index_ensure(BMesh *bm, const char hflag);
void BM_mesh_elem_index_validate(
- BMesh *bm, const char *location, const char *func,
- const char *msg_a, const char *msg_b);
+ BMesh *bm, const char *location, const char *func, const char *msg_a, const char *msg_b);
void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags);
@@ -81,27 +87,27 @@ void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags);
bool BM_mesh_elem_table_check(BMesh *bm);
#endif
-void BM_mesh_elem_table_ensure(BMesh *bm, const char htype);
-void BM_mesh_elem_table_init(BMesh *bm, const char htype);
-void BM_mesh_elem_table_free(BMesh *bm, const char htype);
+void BM_mesh_elem_table_ensure(BMesh *bm, const char htype);
+void BM_mesh_elem_table_init(BMesh *bm, const char htype);
+void BM_mesh_elem_table_free(BMesh *bm, const char htype);
BLI_INLINE BMVert *BM_vert_at_index(BMesh *bm, const int index)
{
- BLI_assert((index >= 0) && (index < bm->totvert));
- BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
- return bm->vtable[index];
+ BLI_assert((index >= 0) && (index < bm->totvert));
+ BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
+ return bm->vtable[index];
}
BLI_INLINE BMEdge *BM_edge_at_index(BMesh *bm, const int index)
{
- BLI_assert((index >= 0) && (index < bm->totedge));
- BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0);
- return bm->etable[index];
+ BLI_assert((index >= 0) && (index < bm->totedge));
+ BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0);
+ return bm->etable[index];
}
BLI_INLINE BMFace *BM_face_at_index(BMesh *bm, const int index)
{
- BLI_assert((index >= 0) && (index < bm->totface));
- BLI_assert((bm->elem_table_dirty & BM_FACE) == 0);
- return bm->ftable[index];
+ BLI_assert((index >= 0) && (index < bm->totface));
+ BLI_assert((bm->elem_table_dirty & BM_FACE) == 0);
+ return bm->ftable[index];
}
BMVert *BM_vert_at_index_find(BMesh *bm, const int index);
@@ -114,43 +120,42 @@ BMFace *BM_face_at_index_find_or_table(BMesh *bm, const int index);
// XXX
-int BM_mesh_elem_count(BMesh *bm, const char htype);
+int BM_mesh_elem_count(BMesh *bm, const char htype);
-void BM_mesh_remap(
- BMesh *bm,
- const uint *vert_idx,
- const uint *edge_idx,
- const uint *face_idx);
+void BM_mesh_remap(BMesh *bm, const uint *vert_idx, const uint *edge_idx, const uint *face_idx);
-void BM_mesh_rebuild(
- BMesh *bm, const struct BMeshCreateParams *params,
- struct BLI_mempool *vpool, struct BLI_mempool *epool, struct BLI_mempool *lpool, struct BLI_mempool *fpool);
+void BM_mesh_rebuild(BMesh *bm,
+ const struct BMeshCreateParams *params,
+ struct BLI_mempool *vpool,
+ struct BLI_mempool *epool,
+ struct BLI_mempool *lpool,
+ struct BLI_mempool *fpool);
typedef struct BMAllocTemplate {
- int totvert, totedge, totloop, totface;
+ int totvert, totedge, totloop, totface;
} BMAllocTemplate;
extern const BMAllocTemplate bm_mesh_allocsize_default;
extern const BMAllocTemplate bm_mesh_chunksize_default;
-#define BMALLOC_TEMPLATE_FROM_BM(bm) { (CHECK_TYPE_INLINE(bm, BMesh *), \
- (bm)->totvert), (bm)->totedge, (bm)->totloop, (bm)->totface}
-
-#define _VA_BMALLOC_TEMPLATE_FROM_ME_1(me) { \
- (CHECK_TYPE_INLINE(me, Mesh *), \
- (me)->totvert), \
- (me)->totedge, \
- (me)->totloop, \
- (me)->totpoly, \
-}
-#define _VA_BMALLOC_TEMPLATE_FROM_ME_2(me_a, me_b) { \
- (CHECK_TYPE_INLINE(me_a, Mesh *), \
- CHECK_TYPE_INLINE(me_b, Mesh *), \
- (me_a)->totvert + (me_b)->totvert), \
- (me_a)->totedge + (me_b)->totedge, \
- (me_a)->totloop + (me_b)->totloop, \
- (me_a)->totpoly + (me_b)->totpoly, \
-}
-#define BMALLOC_TEMPLATE_FROM_ME(...) VA_NARGS_CALL_OVERLOAD(_VA_BMALLOC_TEMPLATE_FROM_ME_, __VA_ARGS__)
+#define BMALLOC_TEMPLATE_FROM_BM(bm) \
+ { \
+ (CHECK_TYPE_INLINE(bm, BMesh *), (bm)->totvert), (bm)->totedge, (bm)->totloop, (bm)->totface \
+ }
+
+#define _VA_BMALLOC_TEMPLATE_FROM_ME_1(me) \
+ { \
+ (CHECK_TYPE_INLINE(me, Mesh *), (me)->totvert), (me)->totedge, (me)->totloop, (me)->totpoly, \
+ }
+#define _VA_BMALLOC_TEMPLATE_FROM_ME_2(me_a, me_b) \
+ { \
+ (CHECK_TYPE_INLINE(me_a, Mesh *), \
+ CHECK_TYPE_INLINE(me_b, Mesh *), \
+ (me_a)->totvert + (me_b)->totvert), \
+ (me_a)->totedge + (me_b)->totedge, (me_a)->totloop + (me_b)->totloop, \
+ (me_a)->totpoly + (me_b)->totpoly, \
+ }
+#define BMALLOC_TEMPLATE_FROM_ME(...) \
+ VA_NARGS_CALL_OVERLOAD(_VA_BMALLOC_TEMPLATE_FROM_ME_, __VA_ARGS__)
#endif /* __BMESH_MESH_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c
index 66cd3a0b30c..f2db451888a 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c
@@ -87,87 +87,85 @@
void BM_mesh_cd_flag_ensure(BMesh *bm, Mesh *mesh, const char cd_flag)
{
- const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag;
- BM_mesh_cd_flag_apply(bm, cd_flag_all);
- if (mesh) {
- mesh->cd_flag = cd_flag_all;
- }
+ const char cd_flag_all = BM_mesh_cd_flag_from_bmesh(bm) | cd_flag;
+ BM_mesh_cd_flag_apply(bm, cd_flag_all);
+ if (mesh) {
+ mesh->cd_flag = cd_flag_all;
+ }
}
void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag)
{
- /* CustomData_bmesh_init_pool() must run first */
- BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL);
- BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL);
- BLI_assert(bm->pdata.totlayer == 0 || bm->pdata.pool != NULL);
-
- if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
- if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
- BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
- }
- }
- else {
- if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
- BM_data_layer_free(bm, &bm->vdata, CD_BWEIGHT);
- }
- }
-
- if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
- if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
- BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
- }
- }
- else {
- if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
- BM_data_layer_free(bm, &bm->edata, CD_BWEIGHT);
- }
- }
-
- if (cd_flag & ME_CDFLAG_EDGE_CREASE) {
- if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
- BM_data_layer_add(bm, &bm->edata, CD_CREASE);
- }
- }
- else {
- if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
- BM_data_layer_free(bm, &bm->edata, CD_CREASE);
- }
- }
+ /* CustomData_bmesh_init_pool() must run first */
+ BLI_assert(bm->vdata.totlayer == 0 || bm->vdata.pool != NULL);
+ BLI_assert(bm->edata.totlayer == 0 || bm->edata.pool != NULL);
+ BLI_assert(bm->pdata.totlayer == 0 || bm->pdata.pool != NULL);
+
+ if (cd_flag & ME_CDFLAG_VERT_BWEIGHT) {
+ if (!CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ BM_data_layer_free(bm, &bm->vdata, CD_BWEIGHT);
+ }
+ }
+
+ if (cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
+ if (!CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ BM_data_layer_free(bm, &bm->edata, CD_BWEIGHT);
+ }
+ }
+
+ if (cd_flag & ME_CDFLAG_EDGE_CREASE) {
+ if (!CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ BM_data_layer_add(bm, &bm->edata, CD_CREASE);
+ }
+ }
+ else {
+ if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ BM_data_layer_free(bm, &bm->edata, CD_CREASE);
+ }
+ }
}
char BM_mesh_cd_flag_from_bmesh(BMesh *bm)
{
- char cd_flag = 0;
- if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
- cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
- }
- if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
- cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
- }
- if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
- cd_flag |= ME_CDFLAG_EDGE_CREASE;
- }
- return cd_flag;
+ char cd_flag = 0;
+ if (CustomData_has_layer(&bm->vdata, CD_BWEIGHT)) {
+ cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
+ }
+ if (CustomData_has_layer(&bm->edata, CD_BWEIGHT)) {
+ cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
+ }
+ if (CustomData_has_layer(&bm->edata, CD_CREASE)) {
+ cd_flag |= ME_CDFLAG_EDGE_CREASE;
+ }
+ return cd_flag;
}
/* Static function for alloc (duplicate in modifiers_bmesh.c) */
static BMFace *bm_face_create_from_mpoly(
- MPoly *mp, MLoop *ml,
- BMesh *bm, BMVert **vtable, BMEdge **etable)
+ MPoly *mp, MLoop *ml, BMesh *bm, BMVert **vtable, BMEdge **etable)
{
- BMVert **verts = BLI_array_alloca(verts, mp->totloop);
- BMEdge **edges = BLI_array_alloca(edges, mp->totloop);
- int j;
+ BMVert **verts = BLI_array_alloca(verts, mp->totloop);
+ BMEdge **edges = BLI_array_alloca(edges, mp->totloop);
+ int j;
- for (j = 0; j < mp->totloop; j++, ml++) {
- verts[j] = vtable[ml->v];
- edges[j] = etable[ml->e];
- }
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ verts[j] = vtable[ml->v];
+ edges[j] = etable[ml->e];
+ }
- return BM_face_create(bm, verts, edges, mp->totloop, NULL, BM_CREATE_SKIP_CD);
+ return BM_face_create(bm, verts, edges, mp->totloop, NULL, BM_CREATE_SKIP_CD);
}
-
/**
* \brief Mesh -> BMesh
* \param bm: The mesh to write into, while this is typically a newly created BMesh,
@@ -178,340 +176,338 @@ static BMFace *bm_face_create_from_mpoly(
*
* \warning This function doesn't calculate face normals.
*/
-void BM_mesh_bm_from_me(
- BMesh *bm, const Mesh *me,
- const struct BMeshFromMeshParams *params)
+void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
{
- const bool is_new =
- !(bm->totvert ||
- (bm->vdata.totlayer || bm->edata.totlayer || bm->pdata.totlayer || bm->ldata.totlayer));
- MVert *mvert;
- MEdge *medge;
- MLoop *mloop;
- MPoly *mp;
- KeyBlock *actkey, *block;
- BMVert *v, **vtable = NULL;
- BMEdge *e, **etable = NULL;
- BMFace *f, **ftable = NULL;
- float (*keyco)[3] = NULL;
- int totloops, i;
- CustomData_MeshMasks mask = CD_MASK_BMESH;
- CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
-
- if (!me || !me->totvert) {
- if (me && is_new) { /*no verts? still copy customdata layout*/
- CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_ASSIGN, 0);
- CustomData_copy(&me->edata, &bm->edata, mask.emask, CD_ASSIGN, 0);
- CustomData_copy(&me->ldata, &bm->ldata, mask.lmask, CD_ASSIGN, 0);
- CustomData_copy(&me->pdata, &bm->pdata, mask.pmask, CD_ASSIGN, 0);
-
- CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
- CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
- CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
- CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
- }
- return; /* sanity check */
- }
-
- if (is_new) {
- CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, 0);
- CustomData_copy(&me->edata, &bm->edata, mask.emask, CD_CALLOC, 0);
- CustomData_copy(&me->ldata, &bm->ldata, mask.lmask, CD_CALLOC, 0);
- CustomData_copy(&me->pdata, &bm->pdata, mask.pmask, CD_CALLOC, 0);
- }
- else {
- CustomData_bmesh_merge(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, bm, BM_VERT);
- CustomData_bmesh_merge(&me->edata, &bm->edata, mask.emask, CD_CALLOC, bm, BM_EDGE);
- CustomData_bmesh_merge(&me->ldata, &bm->ldata, mask.lmask, CD_CALLOC, bm, BM_LOOP);
- CustomData_bmesh_merge(&me->pdata, &bm->pdata, mask.pmask, CD_CALLOC, bm, BM_FACE);
- }
-
- /* -------------------------------------------------------------------- */
- /* Shape Key */
- int tot_shape_keys = me->key ? BLI_listbase_count(&me->key->block) : 0;
- if (is_new == false) {
- tot_shape_keys = min_ii(tot_shape_keys, CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY));
- }
- const float (**shape_key_table)[3] = tot_shape_keys ? BLI_array_alloca(shape_key_table, tot_shape_keys) : NULL;
-
- if ((params->active_shapekey != 0) && (me->key != NULL)) {
- actkey = BLI_findlink(&me->key->block, params->active_shapekey - 1);
- }
- else {
- actkey = NULL;
- }
-
- if (is_new) {
- if (tot_shape_keys || params->add_key_index) {
- CustomData_add_layer(&bm->vdata, CD_SHAPE_KEYINDEX, CD_ASSIGN, NULL, 0);
- }
- }
-
- if (tot_shape_keys) {
- if (is_new) {
- /* check if we need to generate unique ids for the shapekeys.
- * this also exists in the file reading code, but is here for
- * a sanity check */
- if (!me->key->uidgen) {
- fprintf(stderr,
- "%s had to generate shape key uid's in a situation we shouldn't need to! "
- "(bmesh internal error)\n",
- __func__);
-
- me->key->uidgen = 1;
- for (block = me->key->block.first; block; block = block->next) {
- block->uid = me->key->uidgen++;
- }
- }
- }
-
- if (actkey && actkey->totelem == me->totvert) {
- keyco = params->use_shapekey ? actkey->data : NULL;
- if (is_new) {
- bm->shapenr = params->active_shapekey;
- }
- }
-
- for (i = 0, block = me->key->block.first; i < tot_shape_keys; block = block->next, i++) {
- if (is_new) {
- CustomData_add_layer_named(&bm->vdata, CD_SHAPEKEY,
- CD_ASSIGN, NULL, 0, block->name);
- int j = CustomData_get_layer_index_n(&bm->vdata, CD_SHAPEKEY, i);
- bm->vdata.layers[j].uid = block->uid;
- }
- shape_key_table[i] = (const float (*)[3])block->data;
- }
- }
-
- if (is_new) {
- CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
- CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
- CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
- CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
-
- BM_mesh_cd_flag_apply(bm, me->cd_flag);
- }
-
- const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
- const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
- const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
- const int cd_shape_key_offset = me->key ? CustomData_get_offset(&bm->vdata, CD_SHAPEKEY) : -1;
- const int cd_shape_keyindex_offset = is_new && (tot_shape_keys || params->add_key_index) ?
- CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) : -1;
-
- vtable = MEM_mallocN(sizeof(BMVert **) * me->totvert, __func__);
-
- for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
- v = vtable[i] = BM_vert_create(bm, keyco ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
- BM_elem_index_set(v, i); /* set_ok */
-
- /* transfer flag */
- v->head.hflag = BM_vert_flag_from_mflag(mvert->flag & ~SELECT);
-
- /* this is necessary for selection counts to work properly */
- if (mvert->flag & SELECT) {
- BM_vert_select_set(bm, v, true);
- }
-
- normal_short_to_float_v3(v->no, mvert->no);
-
- /* Copy Custom Data */
- CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);
-
- if (cd_vert_bweight_offset != -1) {
- BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f);
- }
-
- /* set shape key original index */
- if (cd_shape_keyindex_offset != -1) {
- BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, i);
- }
-
- /* set shapekey data */
- if (tot_shape_keys) {
- float (*co_dst)[3] = BM_ELEM_CD_GET_VOID_P(v, cd_shape_key_offset);
- for (int j = 0; j < tot_shape_keys; j++, co_dst++) {
- copy_v3_v3(*co_dst, shape_key_table[j][i]);
- }
- }
- }
- if (is_new) {
- bm->elem_index_dirty &= ~BM_VERT; /* added in order, clear dirty flag */
- }
-
- etable = MEM_mallocN(sizeof(BMEdge **) * me->totedge, __func__);
-
- medge = me->medge;
- for (i = 0; i < me->totedge; i++, medge++) {
- e = etable[i] = BM_edge_create(bm, vtable[medge->v1], vtable[medge->v2], NULL, BM_CREATE_SKIP_CD);
- BM_elem_index_set(e, i); /* set_ok */
-
- /* transfer flags */
- e->head.hflag = BM_edge_flag_from_mflag(medge->flag & ~SELECT);
-
- /* this is necessary for selection counts to work properly */
- if (medge->flag & SELECT) {
- BM_edge_select_set(bm, e, true);
- }
-
- /* Copy Custom Data */
- CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);
-
- if (cd_edge_bweight_offset != -1) {
- BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge->bweight / 255.0f);
- }
- if (cd_edge_crease_offset != -1) {
- BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge->crease / 255.0f);
- }
-
- }
- if (is_new) {
- bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */
- }
-
- /* only needed for selection. */
- if (me->mselect && me->totselect != 0) {
- ftable = MEM_mallocN(sizeof(BMFace **) * me->totpoly, __func__);
- }
-
- mloop = me->mloop;
- mp = me->mpoly;
- for (i = 0, totloops = 0; i < me->totpoly; i++, mp++) {
- BMLoop *l_iter;
- BMLoop *l_first;
-
- f = bm_face_create_from_mpoly(mp, mloop + mp->loopstart,
- bm, vtable, etable);
- if (ftable != NULL) {
- ftable[i] = f;
- }
-
- if (UNLIKELY(f == NULL)) {
- printf("%s: Warning! Bad face in mesh"
- " \"%s\" at index %d!, skipping\n",
- __func__, me->id.name + 2, i);
- continue;
- }
-
- /* don't use 'i' since we may have skipped the face */
- BM_elem_index_set(f, bm->totface - 1); /* set_ok */
-
- /* transfer flag */
- f->head.hflag = BM_face_flag_from_mflag(mp->flag & ~ME_FACE_SEL);
-
- /* this is necessary for selection counts to work properly */
- if (mp->flag & ME_FACE_SEL) {
- BM_face_select_set(bm, f, true);
- }
-
- f->mat_nr = mp->mat_nr;
- if (i == me->act_face) {
- bm->act_face = f;
- }
-
- int j = mp->loopstart;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- /* don't use 'j' since we may have skipped some faces, hence some loops. */
- BM_elem_index_set(l_iter, totloops++); /* set_ok */
-
- /* Save index of correspsonding MLoop */
- CustomData_to_bmesh_block(&me->ldata, &bm->ldata, j++, &l_iter->head.data, true);
- } while ((l_iter = l_iter->next) != l_first);
-
- /* Copy Custom Data */
- CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
-
- if (params->calc_face_normal) {
- BM_face_normal_update(f);
- }
- }
- if (is_new) {
- bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); /* added in order, clear dirty flag */
- }
-
- /* -------------------------------------------------------------------- */
- /* MSelect clears the array elements (avoid adding multiple times).
- *
- * Take care to keep this last and not use (v/e/ftable) after this.
- */
-
- if (me->mselect && me->totselect != 0) {
- MSelect *msel;
- for (i = 0, msel = me->mselect; i < me->totselect; i++, msel++) {
- BMElem **ele_p;
- switch (msel->type) {
- case ME_VSEL:
- ele_p = (BMElem **)&vtable[msel->index];
- break;
- case ME_ESEL:
- ele_p = (BMElem **)&etable[msel->index];
- break;
- case ME_FSEL:
- ele_p = (BMElem **)&ftable[msel->index];
- break;
- default:
- continue;
- }
-
- if (*ele_p != NULL) {
- BM_select_history_store_notest(bm, *ele_p);
- *ele_p = NULL;
- }
- }
- }
- else {
- BM_select_history_clear(bm);
- }
-
- MEM_freeN(vtable);
- MEM_freeN(etable);
- if (ftable) {
- MEM_freeN(ftable);
- }
+ const bool is_new = !(bm->totvert || (bm->vdata.totlayer || bm->edata.totlayer ||
+ bm->pdata.totlayer || bm->ldata.totlayer));
+ MVert *mvert;
+ MEdge *medge;
+ MLoop *mloop;
+ MPoly *mp;
+ KeyBlock *actkey, *block;
+ BMVert *v, **vtable = NULL;
+ BMEdge *e, **etable = NULL;
+ BMFace *f, **ftable = NULL;
+ float(*keyco)[3] = NULL;
+ int totloops, i;
+ CustomData_MeshMasks mask = CD_MASK_BMESH;
+ CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
+
+ if (!me || !me->totvert) {
+ if (me && is_new) { /*no verts? still copy customdata layout*/
+ CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_ASSIGN, 0);
+ CustomData_copy(&me->edata, &bm->edata, mask.emask, CD_ASSIGN, 0);
+ CustomData_copy(&me->ldata, &bm->ldata, mask.lmask, CD_ASSIGN, 0);
+ CustomData_copy(&me->pdata, &bm->pdata, mask.pmask, CD_ASSIGN, 0);
+
+ CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
+ CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
+ CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
+ CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
+ }
+ return; /* sanity check */
+ }
+
+ if (is_new) {
+ CustomData_copy(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, 0);
+ CustomData_copy(&me->edata, &bm->edata, mask.emask, CD_CALLOC, 0);
+ CustomData_copy(&me->ldata, &bm->ldata, mask.lmask, CD_CALLOC, 0);
+ CustomData_copy(&me->pdata, &bm->pdata, mask.pmask, CD_CALLOC, 0);
+ }
+ else {
+ CustomData_bmesh_merge(&me->vdata, &bm->vdata, mask.vmask, CD_CALLOC, bm, BM_VERT);
+ CustomData_bmesh_merge(&me->edata, &bm->edata, mask.emask, CD_CALLOC, bm, BM_EDGE);
+ CustomData_bmesh_merge(&me->ldata, &bm->ldata, mask.lmask, CD_CALLOC, bm, BM_LOOP);
+ CustomData_bmesh_merge(&me->pdata, &bm->pdata, mask.pmask, CD_CALLOC, bm, BM_FACE);
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Shape Key */
+ int tot_shape_keys = me->key ? BLI_listbase_count(&me->key->block) : 0;
+ if (is_new == false) {
+ tot_shape_keys = min_ii(tot_shape_keys, CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY));
+ }
+ const float(**shape_key_table)[3] = tot_shape_keys ?
+ BLI_array_alloca(shape_key_table, tot_shape_keys) :
+ NULL;
+
+ if ((params->active_shapekey != 0) && (me->key != NULL)) {
+ actkey = BLI_findlink(&me->key->block, params->active_shapekey - 1);
+ }
+ else {
+ actkey = NULL;
+ }
+
+ if (is_new) {
+ if (tot_shape_keys || params->add_key_index) {
+ CustomData_add_layer(&bm->vdata, CD_SHAPE_KEYINDEX, CD_ASSIGN, NULL, 0);
+ }
+ }
+
+ if (tot_shape_keys) {
+ if (is_new) {
+ /* check if we need to generate unique ids for the shapekeys.
+ * this also exists in the file reading code, but is here for
+ * a sanity check */
+ if (!me->key->uidgen) {
+ fprintf(stderr,
+ "%s had to generate shape key uid's in a situation we shouldn't need to! "
+ "(bmesh internal error)\n",
+ __func__);
+
+ me->key->uidgen = 1;
+ for (block = me->key->block.first; block; block = block->next) {
+ block->uid = me->key->uidgen++;
+ }
+ }
+ }
+
+ if (actkey && actkey->totelem == me->totvert) {
+ keyco = params->use_shapekey ? actkey->data : NULL;
+ if (is_new) {
+ bm->shapenr = params->active_shapekey;
+ }
+ }
+
+ for (i = 0, block = me->key->block.first; i < tot_shape_keys; block = block->next, i++) {
+ if (is_new) {
+ CustomData_add_layer_named(&bm->vdata, CD_SHAPEKEY, CD_ASSIGN, NULL, 0, block->name);
+ int j = CustomData_get_layer_index_n(&bm->vdata, CD_SHAPEKEY, i);
+ bm->vdata.layers[j].uid = block->uid;
+ }
+ shape_key_table[i] = (const float(*)[3])block->data;
+ }
+ }
+
+ if (is_new) {
+ CustomData_bmesh_init_pool(&bm->vdata, me->totvert, BM_VERT);
+ CustomData_bmesh_init_pool(&bm->edata, me->totedge, BM_EDGE);
+ CustomData_bmesh_init_pool(&bm->ldata, me->totloop, BM_LOOP);
+ CustomData_bmesh_init_pool(&bm->pdata, me->totpoly, BM_FACE);
+
+ BM_mesh_cd_flag_apply(bm, me->cd_flag);
+ }
+
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+ const int cd_shape_key_offset = me->key ? CustomData_get_offset(&bm->vdata, CD_SHAPEKEY) : -1;
+ const int cd_shape_keyindex_offset = is_new && (tot_shape_keys || params->add_key_index) ?
+ CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX) :
+ -1;
+
+ vtable = MEM_mallocN(sizeof(BMVert **) * me->totvert, __func__);
+
+ for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
+ v = vtable[i] = BM_vert_create(bm, keyco ? keyco[i] : mvert->co, NULL, BM_CREATE_SKIP_CD);
+ BM_elem_index_set(v, i); /* set_ok */
+
+ /* transfer flag */
+ v->head.hflag = BM_vert_flag_from_mflag(mvert->flag & ~SELECT);
+
+ /* this is necessary for selection counts to work properly */
+ if (mvert->flag & SELECT) {
+ BM_vert_select_set(bm, v, true);
+ }
+
+ normal_short_to_float_v3(v->no, mvert->no);
+
+ /* Copy Custom Data */
+ CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data, true);
+
+ if (cd_vert_bweight_offset != -1) {
+ BM_ELEM_CD_SET_FLOAT(v, cd_vert_bweight_offset, (float)mvert->bweight / 255.0f);
+ }
+
+ /* set shape key original index */
+ if (cd_shape_keyindex_offset != -1) {
+ BM_ELEM_CD_SET_INT(v, cd_shape_keyindex_offset, i);
+ }
+
+ /* set shapekey data */
+ if (tot_shape_keys) {
+ float(*co_dst)[3] = BM_ELEM_CD_GET_VOID_P(v, cd_shape_key_offset);
+ for (int j = 0; j < tot_shape_keys; j++, co_dst++) {
+ copy_v3_v3(*co_dst, shape_key_table[j][i]);
+ }
+ }
+ }
+ if (is_new) {
+ bm->elem_index_dirty &= ~BM_VERT; /* added in order, clear dirty flag */
+ }
+
+ etable = MEM_mallocN(sizeof(BMEdge **) * me->totedge, __func__);
+
+ medge = me->medge;
+ for (i = 0; i < me->totedge; i++, medge++) {
+ e = etable[i] = BM_edge_create(
+ bm, vtable[medge->v1], vtable[medge->v2], NULL, BM_CREATE_SKIP_CD);
+ BM_elem_index_set(e, i); /* set_ok */
+
+ /* transfer flags */
+ e->head.hflag = BM_edge_flag_from_mflag(medge->flag & ~SELECT);
+
+ /* this is necessary for selection counts to work properly */
+ if (medge->flag & SELECT) {
+ BM_edge_select_set(bm, e, true);
+ }
+
+ /* Copy Custom Data */
+ CustomData_to_bmesh_block(&me->edata, &bm->edata, i, &e->head.data, true);
+
+ if (cd_edge_bweight_offset != -1) {
+ BM_ELEM_CD_SET_FLOAT(e, cd_edge_bweight_offset, (float)medge->bweight / 255.0f);
+ }
+ if (cd_edge_crease_offset != -1) {
+ BM_ELEM_CD_SET_FLOAT(e, cd_edge_crease_offset, (float)medge->crease / 255.0f);
+ }
+ }
+ if (is_new) {
+ bm->elem_index_dirty &= ~BM_EDGE; /* added in order, clear dirty flag */
+ }
+
+ /* only needed for selection. */
+ if (me->mselect && me->totselect != 0) {
+ ftable = MEM_mallocN(sizeof(BMFace **) * me->totpoly, __func__);
+ }
+
+ mloop = me->mloop;
+ mp = me->mpoly;
+ for (i = 0, totloops = 0; i < me->totpoly; i++, mp++) {
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ f = bm_face_create_from_mpoly(mp, mloop + mp->loopstart, bm, vtable, etable);
+ if (ftable != NULL) {
+ ftable[i] = f;
+ }
+
+ if (UNLIKELY(f == NULL)) {
+ printf(
+ "%s: Warning! Bad face in mesh"
+ " \"%s\" at index %d!, skipping\n",
+ __func__,
+ me->id.name + 2,
+ i);
+ continue;
+ }
+
+ /* don't use 'i' since we may have skipped the face */
+ BM_elem_index_set(f, bm->totface - 1); /* set_ok */
+
+ /* transfer flag */
+ f->head.hflag = BM_face_flag_from_mflag(mp->flag & ~ME_FACE_SEL);
+
+ /* this is necessary for selection counts to work properly */
+ if (mp->flag & ME_FACE_SEL) {
+ BM_face_select_set(bm, f, true);
+ }
+
+ f->mat_nr = mp->mat_nr;
+ if (i == me->act_face) {
+ bm->act_face = f;
+ }
+
+ int j = mp->loopstart;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ /* don't use 'j' since we may have skipped some faces, hence some loops. */
+ BM_elem_index_set(l_iter, totloops++); /* set_ok */
+
+ /* Save index of correspsonding MLoop */
+ CustomData_to_bmesh_block(&me->ldata, &bm->ldata, j++, &l_iter->head.data, true);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ /* Copy Custom Data */
+ CustomData_to_bmesh_block(&me->pdata, &bm->pdata, i, &f->head.data, true);
+
+ if (params->calc_face_normal) {
+ BM_face_normal_update(f);
+ }
+ }
+ if (is_new) {
+ bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); /* added in order, clear dirty flag */
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* MSelect clears the array elements (avoid adding multiple times).
+ *
+ * Take care to keep this last and not use (v/e/ftable) after this.
+ */
+
+ if (me->mselect && me->totselect != 0) {
+ MSelect *msel;
+ for (i = 0, msel = me->mselect; i < me->totselect; i++, msel++) {
+ BMElem **ele_p;
+ switch (msel->type) {
+ case ME_VSEL:
+ ele_p = (BMElem **)&vtable[msel->index];
+ break;
+ case ME_ESEL:
+ ele_p = (BMElem **)&etable[msel->index];
+ break;
+ case ME_FSEL:
+ ele_p = (BMElem **)&ftable[msel->index];
+ break;
+ default:
+ continue;
+ }
+
+ if (*ele_p != NULL) {
+ BM_select_history_store_notest(bm, *ele_p);
+ *ele_p = NULL;
+ }
+ }
+ }
+ else {
+ BM_select_history_clear(bm);
+ }
+
+ MEM_freeN(vtable);
+ MEM_freeN(etable);
+ if (ftable) {
+ MEM_freeN(ftable);
+ }
}
-
/**
* \brief BMesh -> Mesh
*/
static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
{
- const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
- BMVert **vertMap = NULL;
- BMVert *eve;
- int i = 0;
- BMIter iter;
-
- /* caller needs to ensure this */
- BLI_assert(ototvert > 0);
-
- vertMap = MEM_callocN(sizeof(*vertMap) * ototvert, "vertMap");
- if (cd_shape_keyindex_offset != -1) {
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
- if ((keyi != ORIGINDEX_NONE) &&
- (keyi < ototvert) &&
- /* not fool-proof, but chances are if we have many verts with the same index,
- * we will want to use the first one, since the second is more likely to be a duplicate. */
- (vertMap[keyi] == NULL))
- {
- vertMap[keyi] = eve;
- }
- }
- }
- else {
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- if (i < ototvert) {
- vertMap[i] = eve;
- }
- else {
- break;
- }
- }
- }
-
- return vertMap;
+ const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
+ BMVert **vertMap = NULL;
+ BMVert *eve;
+ int i = 0;
+ BMIter iter;
+
+ /* caller needs to ensure this */
+ BLI_assert(ototvert > 0);
+
+ vertMap = MEM_callocN(sizeof(*vertMap) * ototvert, "vertMap");
+ if (cd_shape_keyindex_offset != -1) {
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
+ if ((keyi != ORIGINDEX_NONE) && (keyi < ototvert) &&
+ /* not fool-proof, but chances are if we have many verts with the same index,
+ * we will want to use the first one, since the second is more likely to be a duplicate. */
+ (vertMap[keyi] == NULL)) {
+ vertMap[keyi] = eve;
+ }
+ }
+ }
+ else {
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ if (i < ototvert) {
+ vertMap[i] = eve;
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ return vertMap;
}
/**
@@ -519,475 +515,465 @@ static BMVert **bm_to_mesh_vertex_map(BMesh *bm, int ototvert)
* \note could split this out into a more generic function */
static int bm_to_mesh_shape_layer_index_from_kb(BMesh *bm, KeyBlock *currkey)
{
- int i;
- int j = 0;
-
- for (i = 0; i < bm->vdata.totlayer; i++) {
- if (bm->vdata.layers[i].type == CD_SHAPEKEY) {
- if (currkey->uid == bm->vdata.layers[i].uid) {
- return j;
- }
- j++;
- }
- }
- return -1;
+ int i;
+ int j = 0;
+
+ for (i = 0; i < bm->vdata.totlayer; i++) {
+ if (bm->vdata.layers[i].type == CD_SHAPEKEY) {
+ if (currkey->uid == bm->vdata.layers[i].uid) {
+ return j;
+ }
+ j++;
+ }
+ }
+ return -1;
}
BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
{
- /* this is a cheap way to set the edge draw, its not precise and will
- * pick the first 2 faces an edge uses.
- * The dot comparison is a little arbitrary, but set so that a 5 subd
- * IcoSphere won't vanish but subd 6 will (as with pre-bmesh blender) */
-
-
- if ( /* (med->flag & ME_EDGEDRAW) && */ /* assume to be true */
- (e->l && (e->l != e->l->radial_next)) &&
- (dot_v3v3(e->l->f->no, e->l->radial_next->f->no) > 0.9995f))
- {
- med->flag &= ~ME_EDGEDRAW;
- }
- else {
- med->flag |= ME_EDGEDRAW;
- }
+ /* this is a cheap way to set the edge draw, its not precise and will
+ * pick the first 2 faces an edge uses.
+ * The dot comparison is a little arbitrary, but set so that a 5 subd
+ * IcoSphere won't vanish but subd 6 will (as with pre-bmesh blender) */
+
+ if (/* (med->flag & ME_EDGEDRAW) && */ /* assume to be true */
+ (e->l && (e->l != e->l->radial_next)) &&
+ (dot_v3v3(e->l->f->no, e->l->radial_next->f->no) > 0.9995f)) {
+ med->flag &= ~ME_EDGEDRAW;
+ }
+ else {
+ med->flag |= ME_EDGEDRAW;
+ }
}
/**
*
* \param bmain: May be NULL in case \a calc_object_remap parameter option is not set.
*/
-void BM_mesh_bm_to_me(
- Main *bmain, BMesh *bm, Mesh *me,
- const struct BMeshToMeshParams *params)
+void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
{
- MLoop *mloop;
- MPoly *mpoly;
- MVert *mvert, *oldverts;
- MEdge *med, *medge;
- BMVert *v, *eve;
- BMEdge *e;
- BMFace *f;
- BMIter iter;
- int i, j, ototvert;
-
- const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
- const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
- const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
-
- ototvert = me->totvert;
-
- /* new vertex block */
- if (bm->totvert == 0) {
- mvert = NULL;
- }
- else {
- mvert = MEM_callocN(bm->totvert * sizeof(MVert), "loadeditbMesh vert");
- }
-
- /* new edge block */
- if (bm->totedge == 0) {
- medge = NULL;
- }
- else {
- medge = MEM_callocN(bm->totedge * sizeof(MEdge), "loadeditbMesh edge");
- }
-
- /* new ngon face block */
- if (bm->totface == 0) {
- mpoly = NULL;
- }
- else {
- mpoly = MEM_callocN(bm->totface * sizeof(MPoly), "loadeditbMesh poly");
- }
-
- /* new loop block */
- if (bm->totloop == 0) {
- mloop = NULL;
- }
- else {
- mloop = MEM_callocN(bm->totloop * sizeof(MLoop), "loadeditbMesh loop");
- }
-
- /* lets save the old verts just in case we are actually working on
- * a key ... we now do processing of the keys at the end */
- oldverts = me->mvert;
-
- /* don't free this yet */
- if (oldverts) {
- CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
- }
-
- /* free custom data */
- CustomData_free(&me->vdata, me->totvert);
- CustomData_free(&me->edata, me->totedge);
- CustomData_free(&me->fdata, me->totface);
- CustomData_free(&me->ldata, me->totloop);
- CustomData_free(&me->pdata, me->totpoly);
-
- /* add new custom data */
- me->totvert = bm->totvert;
- me->totedge = bm->totedge;
- me->totloop = bm->totloop;
- me->totpoly = bm->totface;
- /* will be overwritten with a valid value if 'dotess' is set, otherwise we
- * end up with 'me->totface' and me->mface == NULL which can crash [#28625]
- */
- me->totface = 0;
- me->act_face = -1;
-
- {
- CustomData_MeshMasks mask = CD_MASK_MESH;
- CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
- CustomData_copy(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert);
- CustomData_copy(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge);
- CustomData_copy(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop);
- CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly);
- }
-
- CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
- CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
- CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop);
- CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly);
-
- me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
-
- /* this is called again, 'dotess' arg is used there */
- BKE_mesh_update_customdata_pointers(me, 0);
-
- i = 0;
- BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- copy_v3_v3(mvert->co, v->co);
- normal_float_to_short_v3(mvert->no, v->no);
-
- mvert->flag = BM_vert_flag_to_mflag(v);
-
- BM_elem_index_set(v, i); /* set_inline */
-
- /* copy over customdat */
- CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
-
- if (cd_vert_bweight_offset != -1) {
- mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset);
- }
-
- i++;
- mvert++;
-
- BM_CHECK_ELEMENT(v);
- }
- bm->elem_index_dirty &= ~BM_VERT;
-
- med = medge;
- i = 0;
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- med->v1 = BM_elem_index_get(e->v1);
- med->v2 = BM_elem_index_get(e->v2);
-
- med->flag = BM_edge_flag_to_mflag(e);
-
- BM_elem_index_set(e, i); /* set_inline */
-
- /* copy over customdata */
- CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i);
-
- bmesh_quick_edgedraw_flag(med, e);
-
- if (cd_edge_crease_offset != -1) {
- med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset);
- }
- if (cd_edge_bweight_offset != -1) {
- med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset);
- }
-
- i++;
- med++;
- BM_CHECK_ELEMENT(e);
- }
- bm->elem_index_dirty &= ~BM_EDGE;
-
- i = 0;
- j = 0;
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- BMLoop *l_iter, *l_first;
- mpoly->loopstart = j;
- mpoly->totloop = f->len;
- mpoly->mat_nr = f->mat_nr;
- mpoly->flag = BM_face_flag_to_mflag(f);
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- mloop->e = BM_elem_index_get(l_iter->e);
- mloop->v = BM_elem_index_get(l_iter->v);
-
- /* copy over customdata */
- CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j);
-
- j++;
- mloop++;
- BM_CHECK_ELEMENT(l_iter);
- BM_CHECK_ELEMENT(l_iter->e);
- BM_CHECK_ELEMENT(l_iter->v);
- } while ((l_iter = l_iter->next) != l_first);
-
- if (f == bm->act_face) {
- me->act_face = i;
- }
-
- /* copy over customdata */
- CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i);
-
- i++;
- mpoly++;
- BM_CHECK_ELEMENT(f);
- }
-
- /* patch hook indices and vertex parents */
- if (params->calc_object_remap && (ototvert > 0)) {
- BLI_assert(bmain != NULL);
- Object *ob;
- ModifierData *md;
- BMVert **vertMap = NULL;
-
- for (ob = bmain->objects.first; ob; ob = ob->id.next) {
- if ((ob->parent) && (ob->parent->data == me) && ELEM(ob->partype, PARVERT1, PARVERT3)) {
-
- if (vertMap == NULL) {
- vertMap = bm_to_mesh_vertex_map(bm, ototvert);
- }
-
- if (ob->par1 < ototvert) {
- eve = vertMap[ob->par1];
- if (eve) {
- ob->par1 = BM_elem_index_get(eve);
- }
- }
- if (ob->par2 < ototvert) {
- eve = vertMap[ob->par2];
- if (eve) {
- ob->par2 = BM_elem_index_get(eve);
- }
- }
- if (ob->par3 < ototvert) {
- eve = vertMap[ob->par3];
- if (eve) {
- ob->par3 = BM_elem_index_get(eve);
- }
- }
-
- }
- if (ob->data == me) {
- for (md = ob->modifiers.first; md; md = md->next) {
- if (md->type == eModifierType_Hook) {
- HookModifierData *hmd = (HookModifierData *) md;
-
- if (vertMap == NULL) {
- vertMap = bm_to_mesh_vertex_map(bm, ototvert);
- }
-
- for (i = j = 0; i < hmd->totindex; i++) {
- if (hmd->indexar[i] < ototvert) {
- eve = vertMap[hmd->indexar[i]];
-
- if (eve) {
- hmd->indexar[j++] = BM_elem_index_get(eve);
- }
- }
- else {
- j++;
- }
- }
-
- hmd->totindex = j;
- }
- }
- }
- }
-
- if (vertMap) {
- MEM_freeN(vertMap);
- }
- }
-
- BKE_mesh_update_customdata_pointers(me, false);
-
- {
- BMEditSelection *selected;
- me->totselect = BLI_listbase_count(&(bm->selected));
-
- MEM_SAFE_FREE(me->mselect);
- if (me->totselect != 0) {
- me->mselect = MEM_mallocN(sizeof(MSelect) * me->totselect, "Mesh selection history");
- }
-
- for (i = 0, selected = bm->selected.first; selected; i++, selected = selected->next) {
- if (selected->htype == BM_VERT) {
- me->mselect[i].type = ME_VSEL;
-
- }
- else if (selected->htype == BM_EDGE) {
- me->mselect[i].type = ME_ESEL;
-
- }
- else if (selected->htype == BM_FACE) {
- me->mselect[i].type = ME_FSEL;
- }
-
- me->mselect[i].index = BM_elem_index_get(selected->ele);
- }
- }
-
- /* see comment below, this logic is in twice */
-
- if (me->key) {
- const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
-
- KeyBlock *currkey;
- KeyBlock *actkey = BLI_findlink(&me->key->block, bm->shapenr - 1);
-
- float (*ofs)[3] = NULL;
-
- /* go through and find any shapekey customdata layers
- * that might not have corresponding KeyBlocks, and add them if
- * necessary */
- j = 0;
- for (i = 0; i < bm->vdata.totlayer; i++) {
- if (bm->vdata.layers[i].type != CD_SHAPEKEY) {
- continue;
- }
-
- for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
- if (currkey->uid == bm->vdata.layers[i].uid) {
- break;
- }
- }
-
- if (!currkey) {
- currkey = BKE_keyblock_add(me->key, bm->vdata.layers[i].name);
- currkey->uid = bm->vdata.layers[i].uid;
- }
-
- j++;
- }
-
-
- /* editing the base key should update others */
- if ((me->key->type == KEY_RELATIVE) && /* only need offsets for relative shape keys */
- (actkey != NULL) && /* unlikely, but the active key may not be valid if the
- * bmesh and the mesh are out of sync */
- (oldverts != NULL)) /* not used here, but 'oldverts' is used later for applying 'ofs' */
- {
- const bool act_is_basis = BKE_keyblock_is_basis(me->key, bm->shapenr - 1);
-
- /* active key is a base */
- if (act_is_basis && (cd_shape_keyindex_offset != -1)) {
- float (*fp)[3] = actkey->data;
-
- ofs = MEM_callocN(sizeof(float) * 3 * bm->totvert, "currkey->data");
- mvert = me->mvert;
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
-
- if (keyi != ORIGINDEX_NONE) {
- sub_v3_v3v3(ofs[i], mvert->co, fp[keyi]);
- }
- else {
- /* if there are new vertices in the mesh, we can't propagate the offset
- * because it will only work for the existing vertices and not the new
- * ones, creating a mess when doing e.g. subdivide + translate */
- MEM_freeN(ofs);
- ofs = NULL;
- break;
- }
-
- mvert++;
- }
- }
- }
-
- for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
- const bool apply_offset = (ofs && (currkey != actkey) && (bm->shapenr - 1 == currkey->relative));
- int cd_shape_offset;
- int keyi;
- float (*ofs_pt)[3] = ofs;
- float *newkey, (*oldkey)[3], *fp;
-
- j = bm_to_mesh_shape_layer_index_from_kb(bm, currkey);
- cd_shape_offset = CustomData_get_n_offset(&bm->vdata, CD_SHAPEKEY, j);
-
-
- fp = newkey = MEM_callocN(me->key->elemsize * bm->totvert, "currkey->data");
- oldkey = currkey->data;
-
- mvert = me->mvert;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-
- if (currkey == actkey) {
- copy_v3_v3(fp, eve->co);
-
- if (actkey != me->key->refkey) { /* important see bug [#30771] */
- if (cd_shape_keyindex_offset != -1) {
- if (oldverts) {
- keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
- if (keyi != ORIGINDEX_NONE && keyi < currkey->totelem) { /* valid old vertex */
- copy_v3_v3(mvert->co, oldverts[keyi].co);
- }
- }
- }
- }
- }
- else if (j != -1) {
- /* in most cases this runs */
- copy_v3_v3(fp, BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset));
- }
- else if ((oldkey != NULL) &&
- (cd_shape_keyindex_offset != -1) &&
- ((keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset)) != ORIGINDEX_NONE) &&
- (keyi < currkey->totelem))
- {
- /* old method of reconstructing keys via vertice's original key indices,
- * currently used if the new method above fails (which is theoretically
- * possible in certain cases of undo) */
- copy_v3_v3(fp, oldkey[keyi]);
- }
- else {
- /* fail! fill in with dummy value */
- copy_v3_v3(fp, mvert->co);
- }
-
- /* propagate edited basis offsets to other shapes */
- if (apply_offset) {
- add_v3_v3(fp, *ofs_pt++);
- /* Apply back new coordinates of offsetted shapekeys into BMesh.
- * Otherwise, in case we call again BM_mesh_bm_to_me on same BMesh, we'll apply diff from previous
- * call to BM_mesh_bm_to_me, to shapekey values from *original creation of the BMesh*. See T50524. */
- copy_v3_v3(BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset), fp);
- }
-
- fp += 3;
- mvert++;
- }
-
- currkey->totelem = bm->totvert;
- if (currkey->data) {
- MEM_freeN(currkey->data);
- }
- currkey->data = newkey;
- }
-
- if (ofs) {
- MEM_freeN(ofs);
- }
- }
-
- if (oldverts) {
- MEM_freeN(oldverts);
- }
-
- /* topology could be changed, ensure mdisps are ok */
- multires_topology_changed(me);
-
- /* to be removed as soon as COW is enabled by default. */
- BKE_mesh_runtime_clear_geometry(me);
+ MLoop *mloop;
+ MPoly *mpoly;
+ MVert *mvert, *oldverts;
+ MEdge *med, *medge;
+ BMVert *v, *eve;
+ BMEdge *e;
+ BMFace *f;
+ BMIter iter;
+ int i, j, ototvert;
+
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
+ ototvert = me->totvert;
+
+ /* new vertex block */
+ if (bm->totvert == 0) {
+ mvert = NULL;
+ }
+ else {
+ mvert = MEM_callocN(bm->totvert * sizeof(MVert), "loadeditbMesh vert");
+ }
+
+ /* new edge block */
+ if (bm->totedge == 0) {
+ medge = NULL;
+ }
+ else {
+ medge = MEM_callocN(bm->totedge * sizeof(MEdge), "loadeditbMesh edge");
+ }
+
+ /* new ngon face block */
+ if (bm->totface == 0) {
+ mpoly = NULL;
+ }
+ else {
+ mpoly = MEM_callocN(bm->totface * sizeof(MPoly), "loadeditbMesh poly");
+ }
+
+ /* new loop block */
+ if (bm->totloop == 0) {
+ mloop = NULL;
+ }
+ else {
+ mloop = MEM_callocN(bm->totloop * sizeof(MLoop), "loadeditbMesh loop");
+ }
+
+ /* lets save the old verts just in case we are actually working on
+ * a key ... we now do processing of the keys at the end */
+ oldverts = me->mvert;
+
+ /* don't free this yet */
+ if (oldverts) {
+ CustomData_set_layer(&me->vdata, CD_MVERT, NULL);
+ }
+
+ /* free custom data */
+ CustomData_free(&me->vdata, me->totvert);
+ CustomData_free(&me->edata, me->totedge);
+ CustomData_free(&me->fdata, me->totface);
+ CustomData_free(&me->ldata, me->totloop);
+ CustomData_free(&me->pdata, me->totpoly);
+
+ /* add new custom data */
+ me->totvert = bm->totvert;
+ me->totedge = bm->totedge;
+ me->totloop = bm->totloop;
+ me->totpoly = bm->totface;
+ /* will be overwritten with a valid value if 'dotess' is set, otherwise we
+ * end up with 'me->totface' and me->mface == NULL which can crash [#28625]
+ */
+ me->totface = 0;
+ me->act_face = -1;
+
+ {
+ CustomData_MeshMasks mask = CD_MASK_MESH;
+ CustomData_MeshMasks_update(&mask, &params->cd_mask_extra);
+ CustomData_copy(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert);
+ CustomData_copy(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge);
+ CustomData_copy(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop);
+ CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly);
+ }
+
+ CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, mvert, me->totvert);
+ CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, me->totedge);
+ CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, mloop, me->totloop);
+ CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, mpoly, me->totpoly);
+
+ me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
+
+ /* this is called again, 'dotess' arg is used there */
+ BKE_mesh_update_customdata_pointers(me, 0);
+
+ i = 0;
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ copy_v3_v3(mvert->co, v->co);
+ normal_float_to_short_v3(mvert->no, v->no);
+
+ mvert->flag = BM_vert_flag_to_mflag(v);
+
+ BM_elem_index_set(v, i); /* set_inline */
+
+ /* copy over customdat */
+ CustomData_from_bmesh_block(&bm->vdata, &me->vdata, v->head.data, i);
+
+ if (cd_vert_bweight_offset != -1) {
+ mvert->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(v, cd_vert_bweight_offset);
+ }
+
+ i++;
+ mvert++;
+
+ BM_CHECK_ELEMENT(v);
+ }
+ bm->elem_index_dirty &= ~BM_VERT;
+
+ med = medge;
+ i = 0;
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ med->v1 = BM_elem_index_get(e->v1);
+ med->v2 = BM_elem_index_get(e->v2);
+
+ med->flag = BM_edge_flag_to_mflag(e);
+
+ BM_elem_index_set(e, i); /* set_inline */
+
+ /* copy over customdata */
+ CustomData_from_bmesh_block(&bm->edata, &me->edata, e->head.data, i);
+
+ bmesh_quick_edgedraw_flag(med, e);
+
+ if (cd_edge_crease_offset != -1) {
+ med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_crease_offset);
+ }
+ if (cd_edge_bweight_offset != -1) {
+ med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(e, cd_edge_bweight_offset);
+ }
+
+ i++;
+ med++;
+ BM_CHECK_ELEMENT(e);
+ }
+ bm->elem_index_dirty &= ~BM_EDGE;
+
+ i = 0;
+ j = 0;
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ BMLoop *l_iter, *l_first;
+ mpoly->loopstart = j;
+ mpoly->totloop = f->len;
+ mpoly->mat_nr = f->mat_nr;
+ mpoly->flag = BM_face_flag_to_mflag(f);
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ mloop->e = BM_elem_index_get(l_iter->e);
+ mloop->v = BM_elem_index_get(l_iter->v);
+
+ /* copy over customdata */
+ CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j);
+
+ j++;
+ mloop++;
+ BM_CHECK_ELEMENT(l_iter);
+ BM_CHECK_ELEMENT(l_iter->e);
+ BM_CHECK_ELEMENT(l_iter->v);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (f == bm->act_face) {
+ me->act_face = i;
+ }
+
+ /* copy over customdata */
+ CustomData_from_bmesh_block(&bm->pdata, &me->pdata, f->head.data, i);
+
+ i++;
+ mpoly++;
+ BM_CHECK_ELEMENT(f);
+ }
+
+ /* patch hook indices and vertex parents */
+ if (params->calc_object_remap && (ototvert > 0)) {
+ BLI_assert(bmain != NULL);
+ Object *ob;
+ ModifierData *md;
+ BMVert **vertMap = NULL;
+
+ for (ob = bmain->objects.first; ob; ob = ob->id.next) {
+ if ((ob->parent) && (ob->parent->data == me) && ELEM(ob->partype, PARVERT1, PARVERT3)) {
+
+ if (vertMap == NULL) {
+ vertMap = bm_to_mesh_vertex_map(bm, ototvert);
+ }
+
+ if (ob->par1 < ototvert) {
+ eve = vertMap[ob->par1];
+ if (eve) {
+ ob->par1 = BM_elem_index_get(eve);
+ }
+ }
+ if (ob->par2 < ototvert) {
+ eve = vertMap[ob->par2];
+ if (eve) {
+ ob->par2 = BM_elem_index_get(eve);
+ }
+ }
+ if (ob->par3 < ototvert) {
+ eve = vertMap[ob->par3];
+ if (eve) {
+ ob->par3 = BM_elem_index_get(eve);
+ }
+ }
+ }
+ if (ob->data == me) {
+ for (md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Hook) {
+ HookModifierData *hmd = (HookModifierData *)md;
+
+ if (vertMap == NULL) {
+ vertMap = bm_to_mesh_vertex_map(bm, ototvert);
+ }
+
+ for (i = j = 0; i < hmd->totindex; i++) {
+ if (hmd->indexar[i] < ototvert) {
+ eve = vertMap[hmd->indexar[i]];
+
+ if (eve) {
+ hmd->indexar[j++] = BM_elem_index_get(eve);
+ }
+ }
+ else {
+ j++;
+ }
+ }
+
+ hmd->totindex = j;
+ }
+ }
+ }
+ }
+
+ if (vertMap) {
+ MEM_freeN(vertMap);
+ }
+ }
+
+ BKE_mesh_update_customdata_pointers(me, false);
+
+ {
+ BMEditSelection *selected;
+ me->totselect = BLI_listbase_count(&(bm->selected));
+
+ MEM_SAFE_FREE(me->mselect);
+ if (me->totselect != 0) {
+ me->mselect = MEM_mallocN(sizeof(MSelect) * me->totselect, "Mesh selection history");
+ }
+
+ for (i = 0, selected = bm->selected.first; selected; i++, selected = selected->next) {
+ if (selected->htype == BM_VERT) {
+ me->mselect[i].type = ME_VSEL;
+ }
+ else if (selected->htype == BM_EDGE) {
+ me->mselect[i].type = ME_ESEL;
+ }
+ else if (selected->htype == BM_FACE) {
+ me->mselect[i].type = ME_FSEL;
+ }
+
+ me->mselect[i].index = BM_elem_index_get(selected->ele);
+ }
+ }
+
+ /* see comment below, this logic is in twice */
+
+ if (me->key) {
+ const int cd_shape_keyindex_offset = CustomData_get_offset(&bm->vdata, CD_SHAPE_KEYINDEX);
+
+ KeyBlock *currkey;
+ KeyBlock *actkey = BLI_findlink(&me->key->block, bm->shapenr - 1);
+
+ float(*ofs)[3] = NULL;
+
+ /* go through and find any shapekey customdata layers
+ * that might not have corresponding KeyBlocks, and add them if
+ * necessary */
+ j = 0;
+ for (i = 0; i < bm->vdata.totlayer; i++) {
+ if (bm->vdata.layers[i].type != CD_SHAPEKEY) {
+ continue;
+ }
+
+ for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
+ if (currkey->uid == bm->vdata.layers[i].uid) {
+ break;
+ }
+ }
+
+ if (!currkey) {
+ currkey = BKE_keyblock_add(me->key, bm->vdata.layers[i].name);
+ currkey->uid = bm->vdata.layers[i].uid;
+ }
+
+ j++;
+ }
+
+ /* editing the base key should update others */
+ if ((me->key->type == KEY_RELATIVE) && /* only need offsets for relative shape keys */
+ (actkey != NULL) && /* unlikely, but the active key may not be valid if the
+ * bmesh and the mesh are out of sync */
+ (oldverts != NULL)) /* not used here, but 'oldverts' is used later for applying 'ofs' */
+ {
+ const bool act_is_basis = BKE_keyblock_is_basis(me->key, bm->shapenr - 1);
+
+ /* active key is a base */
+ if (act_is_basis && (cd_shape_keyindex_offset != -1)) {
+ float(*fp)[3] = actkey->data;
+
+ ofs = MEM_callocN(sizeof(float) * 3 * bm->totvert, "currkey->data");
+ mvert = me->mvert;
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ const int keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
+
+ if (keyi != ORIGINDEX_NONE) {
+ sub_v3_v3v3(ofs[i], mvert->co, fp[keyi]);
+ }
+ else {
+ /* if there are new vertices in the mesh, we can't propagate the offset
+ * because it will only work for the existing vertices and not the new
+ * ones, creating a mess when doing e.g. subdivide + translate */
+ MEM_freeN(ofs);
+ ofs = NULL;
+ break;
+ }
+
+ mvert++;
+ }
+ }
+ }
+
+ for (currkey = me->key->block.first; currkey; currkey = currkey->next) {
+ const bool apply_offset = (ofs && (currkey != actkey) &&
+ (bm->shapenr - 1 == currkey->relative));
+ int cd_shape_offset;
+ int keyi;
+ float(*ofs_pt)[3] = ofs;
+ float *newkey, (*oldkey)[3], *fp;
+
+ j = bm_to_mesh_shape_layer_index_from_kb(bm, currkey);
+ cd_shape_offset = CustomData_get_n_offset(&bm->vdata, CD_SHAPEKEY, j);
+
+ fp = newkey = MEM_callocN(me->key->elemsize * bm->totvert, "currkey->data");
+ oldkey = currkey->data;
+
+ mvert = me->mvert;
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+
+ if (currkey == actkey) {
+ copy_v3_v3(fp, eve->co);
+
+ if (actkey != me->key->refkey) { /* important see bug [#30771] */
+ if (cd_shape_keyindex_offset != -1) {
+ if (oldverts) {
+ keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset);
+ if (keyi != ORIGINDEX_NONE && keyi < currkey->totelem) { /* valid old vertex */
+ copy_v3_v3(mvert->co, oldverts[keyi].co);
+ }
+ }
+ }
+ }
+ }
+ else if (j != -1) {
+ /* in most cases this runs */
+ copy_v3_v3(fp, BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset));
+ }
+ else if ((oldkey != NULL) && (cd_shape_keyindex_offset != -1) &&
+ ((keyi = BM_ELEM_CD_GET_INT(eve, cd_shape_keyindex_offset)) != ORIGINDEX_NONE) &&
+ (keyi < currkey->totelem)) {
+ /* old method of reconstructing keys via vertice's original key indices,
+ * currently used if the new method above fails (which is theoretically
+ * possible in certain cases of undo) */
+ copy_v3_v3(fp, oldkey[keyi]);
+ }
+ else {
+ /* fail! fill in with dummy value */
+ copy_v3_v3(fp, mvert->co);
+ }
+
+ /* propagate edited basis offsets to other shapes */
+ if (apply_offset) {
+ add_v3_v3(fp, *ofs_pt++);
+ /* Apply back new coordinates of offsetted shapekeys into BMesh.
+ * Otherwise, in case we call again BM_mesh_bm_to_me on same BMesh, we'll apply diff from previous
+ * call to BM_mesh_bm_to_me, to shapekey values from *original creation of the BMesh*. See T50524. */
+ copy_v3_v3(BM_ELEM_CD_GET_VOID_P(eve, cd_shape_offset), fp);
+ }
+
+ fp += 3;
+ mvert++;
+ }
+
+ currkey->totelem = bm->totvert;
+ if (currkey->data) {
+ MEM_freeN(currkey->data);
+ }
+ currkey->data = newkey;
+ }
+
+ if (ofs) {
+ MEM_freeN(ofs);
+ }
+ }
+
+ if (oldverts) {
+ MEM_freeN(oldverts);
+ }
+
+ /* topology could be changed, ensure mdisps are ok */
+ multires_topology_changed(me);
+
+ /* to be removed as soon as COW is enabled by default. */
+ BKE_mesh_runtime_clear_geometry(me);
}
/**
@@ -1007,150 +993,150 @@ void BM_mesh_bm_to_me(
*/
void BM_mesh_bm_to_me_for_eval(BMesh *bm, Mesh *me, const CustomData_MeshMasks *cd_mask_extra)
{
- /* must be an empty mesh. */
- BLI_assert(me->totvert == 0);
- BLI_assert(cd_mask_extra == NULL || (cd_mask_extra->vmask & CD_MASK_SHAPEKEY) == 0);
-
- me->totvert = bm->totvert;
- me->totedge = bm->totedge;
- me->totface = 0;
- me->totloop = bm->totloop;
- me->totpoly = bm->totface;
-
- CustomData_add_layer(&me->vdata, CD_ORIGINDEX, CD_CALLOC, NULL, bm->totvert);
- CustomData_add_layer(&me->edata, CD_ORIGINDEX, CD_CALLOC, NULL, bm->totedge);
- CustomData_add_layer(&me->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, bm->totface);
-
- CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, bm->totvert);
- CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, bm->totedge);
- CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, bm->totloop);
- CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, bm->totface);
-
- /* don't process shapekeys, we only feed them through the modifier stack as needed,
- * e.g. for applying modifiers or the like*/
- CustomData_MeshMasks mask = CD_MASK_DERIVEDMESH;
- if (cd_mask_extra != NULL) {
- CustomData_MeshMasks_update(&mask, cd_mask_extra);
- }
- mask.vmask &= ~CD_MASK_SHAPEKEY;
- CustomData_merge(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert);
- CustomData_merge(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge);
- CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop);
- CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly);
-
- BKE_mesh_update_customdata_pointers(me, false);
-
- BMIter iter;
- BMVert *eve;
- BMEdge *eed;
- BMFace *efa;
- MVert *mvert = me->mvert;
- MEdge *medge = me->medge;
- MLoop *mloop = me->mloop;
- MPoly *mpoly = me->mpoly;
- int *index, add_orig;
- unsigned int i, j;
-
- const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
- const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
- const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
-
- me->runtime.deformed_only = true;
-
- /* don't add origindex layer if one already exists */
- add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
-
- index = CustomData_get_layer(&me->vdata, CD_ORIGINDEX);
-
- BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
- MVert *mv = &mvert[i];
-
- copy_v3_v3(mv->co, eve->co);
-
- BM_elem_index_set(eve, i); /* set_inline */
-
- normal_float_to_short_v3(mv->no, eve->no);
-
- mv->flag = BM_vert_flag_to_mflag(eve);
-
- if (cd_vert_bweight_offset != -1) {
- mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
- }
-
- if (add_orig) {
- *index++ = i;
- }
-
- CustomData_from_bmesh_block(&bm->vdata, &me->vdata, eve->head.data, i);
- }
- bm->elem_index_dirty &= ~BM_VERT;
-
- index = CustomData_get_layer(&me->edata, CD_ORIGINDEX);
- BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
- MEdge *med = &medge[i];
-
- BM_elem_index_set(eed, i); /* set_inline */
-
- med->v1 = BM_elem_index_get(eed->v1);
- med->v2 = BM_elem_index_get(eed->v2);
-
- med->flag = BM_edge_flag_to_mflag(eed);
-
- /* handle this differently to editmode switching,
- * only enable draw for single user edges rather then calculating angle */
- if ((med->flag & ME_EDGEDRAW) == 0) {
- if (eed->l && eed->l == eed->l->radial_next) {
- med->flag |= ME_EDGEDRAW;
- }
- }
-
- if (cd_edge_crease_offset != -1) {
- med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
- }
- if (cd_edge_bweight_offset != -1) {
- med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
- }
-
- CustomData_from_bmesh_block(&bm->edata, &me->edata, eed->head.data, i);
- if (add_orig) {
- *index++ = i;
- }
- }
- bm->elem_index_dirty &= ~BM_EDGE;
-
- index = CustomData_get_layer(&me->pdata, CD_ORIGINDEX);
- j = 0;
- BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
- BMLoop *l_iter;
- BMLoop *l_first;
- MPoly *mp = &mpoly[i];
-
- BM_elem_index_set(efa, i); /* set_inline */
-
- mp->totloop = efa->len;
- mp->flag = BM_face_flag_to_mflag(efa);
- mp->loopstart = j;
- mp->mat_nr = efa->mat_nr;
+ /* must be an empty mesh. */
+ BLI_assert(me->totvert == 0);
+ BLI_assert(cd_mask_extra == NULL || (cd_mask_extra->vmask & CD_MASK_SHAPEKEY) == 0);
+
+ me->totvert = bm->totvert;
+ me->totedge = bm->totedge;
+ me->totface = 0;
+ me->totloop = bm->totloop;
+ me->totpoly = bm->totface;
+
+ CustomData_add_layer(&me->vdata, CD_ORIGINDEX, CD_CALLOC, NULL, bm->totvert);
+ CustomData_add_layer(&me->edata, CD_ORIGINDEX, CD_CALLOC, NULL, bm->totedge);
+ CustomData_add_layer(&me->pdata, CD_ORIGINDEX, CD_CALLOC, NULL, bm->totface);
+
+ CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, bm->totvert);
+ CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, bm->totedge);
+ CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, bm->totloop);
+ CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, bm->totface);
+
+ /* don't process shapekeys, we only feed them through the modifier stack as needed,
+ * e.g. for applying modifiers or the like*/
+ CustomData_MeshMasks mask = CD_MASK_DERIVEDMESH;
+ if (cd_mask_extra != NULL) {
+ CustomData_MeshMasks_update(&mask, cd_mask_extra);
+ }
+ mask.vmask &= ~CD_MASK_SHAPEKEY;
+ CustomData_merge(&bm->vdata, &me->vdata, mask.vmask, CD_CALLOC, me->totvert);
+ CustomData_merge(&bm->edata, &me->edata, mask.emask, CD_CALLOC, me->totedge);
+ CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_CALLOC, me->totloop);
+ CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_CALLOC, me->totpoly);
+
+ BKE_mesh_update_customdata_pointers(me, false);
+
+ BMIter iter;
+ BMVert *eve;
+ BMEdge *eed;
+ BMFace *efa;
+ MVert *mvert = me->mvert;
+ MEdge *medge = me->medge;
+ MLoop *mloop = me->mloop;
+ MPoly *mpoly = me->mpoly;
+ int *index, add_orig;
+ unsigned int i, j;
+
+ const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
+ const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
+ const int cd_edge_crease_offset = CustomData_get_offset(&bm->edata, CD_CREASE);
+
+ me->runtime.deformed_only = true;
+
+ /* don't add origindex layer if one already exists */
+ add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
+
+ index = CustomData_get_layer(&me->vdata, CD_ORIGINDEX);
+
+ BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
+ MVert *mv = &mvert[i];
+
+ copy_v3_v3(mv->co, eve->co);
+
+ BM_elem_index_set(eve, i); /* set_inline */
+
+ normal_float_to_short_v3(mv->no, eve->no);
+
+ mv->flag = BM_vert_flag_to_mflag(eve);
+
+ if (cd_vert_bweight_offset != -1) {
+ mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
+ }
+
+ if (add_orig) {
+ *index++ = i;
+ }
+
+ CustomData_from_bmesh_block(&bm->vdata, &me->vdata, eve->head.data, i);
+ }
+ bm->elem_index_dirty &= ~BM_VERT;
+
+ index = CustomData_get_layer(&me->edata, CD_ORIGINDEX);
+ BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
+ MEdge *med = &medge[i];
+
+ BM_elem_index_set(eed, i); /* set_inline */
+
+ med->v1 = BM_elem_index_get(eed->v1);
+ med->v2 = BM_elem_index_get(eed->v2);
+
+ med->flag = BM_edge_flag_to_mflag(eed);
+
+ /* handle this differently to editmode switching,
+ * only enable draw for single user edges rather then calculating angle */
+ if ((med->flag & ME_EDGEDRAW) == 0) {
+ if (eed->l && eed->l == eed->l->radial_next) {
+ med->flag |= ME_EDGEDRAW;
+ }
+ }
+
+ if (cd_edge_crease_offset != -1) {
+ med->crease = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
+ }
+ if (cd_edge_bweight_offset != -1) {
+ med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
+ }
+
+ CustomData_from_bmesh_block(&bm->edata, &me->edata, eed->head.data, i);
+ if (add_orig) {
+ *index++ = i;
+ }
+ }
+ bm->elem_index_dirty &= ~BM_EDGE;
+
+ index = CustomData_get_layer(&me->pdata, CD_ORIGINDEX);
+ j = 0;
+ BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ MPoly *mp = &mpoly[i];
+
+ BM_elem_index_set(efa, i); /* set_inline */
+
+ mp->totloop = efa->len;
+ mp->flag = BM_face_flag_to_mflag(efa);
+ mp->loopstart = j;
+ mp->mat_nr = efa->mat_nr;
- l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
- do {
- mloop->v = BM_elem_index_get(l_iter->v);
- mloop->e = BM_elem_index_get(l_iter->e);
- CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ mloop->v = BM_elem_index_get(l_iter->v);
+ mloop->e = BM_elem_index_get(l_iter->e);
+ CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j);
- BM_elem_index_set(l_iter, j); /* set_inline */
+ BM_elem_index_set(l_iter, j); /* set_inline */
- j++;
- mloop++;
- } while ((l_iter = l_iter->next) != l_first);
+ j++;
+ mloop++;
+ } while ((l_iter = l_iter->next) != l_first);
- CustomData_from_bmesh_block(&bm->pdata, &me->pdata, efa->head.data, i);
+ CustomData_from_bmesh_block(&bm->pdata, &me->pdata, efa->head.data, i);
- if (add_orig) {
- *index++ = i;
- }
- }
- bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
+ if (add_orig) {
+ *index++ = i;
+ }
+ }
+ bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
- me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
+ me->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
}
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h
index 30a1e8bffd5..f0302764a5f 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h
@@ -33,33 +33,31 @@ void BM_mesh_cd_flag_apply(BMesh *bm, const char cd_flag);
char BM_mesh_cd_flag_from_bmesh(BMesh *bm);
struct BMeshFromMeshParams {
- uint calc_face_normal : 1;
- /* add a vertex CD_SHAPE_KEYINDEX layer */
- uint add_key_index : 1;
- /* set vertex coordinates from the shapekey */
- uint use_shapekey : 1;
- /* define the active shape key (index + 1) */
- int active_shapekey;
- struct CustomData_MeshMasks cd_mask_extra;
+ uint calc_face_normal : 1;
+ /* add a vertex CD_SHAPE_KEYINDEX layer */
+ uint add_key_index : 1;
+ /* set vertex coordinates from the shapekey */
+ uint use_shapekey : 1;
+ /* define the active shape key (index + 1) */
+ int active_shapekey;
+ struct CustomData_MeshMasks cd_mask_extra;
};
-void BM_mesh_bm_from_me(
- BMesh *bm, const struct Mesh *me,
- const struct BMeshFromMeshParams *params)
-ATTR_NONNULL(1, 3);
+void BM_mesh_bm_from_me(BMesh *bm, const struct Mesh *me, const struct BMeshFromMeshParams *params)
+ ATTR_NONNULL(1, 3);
struct BMeshToMeshParams {
- /** Update object hook indices & vertex parents. */
- uint calc_object_remap : 1;
- struct CustomData_MeshMasks cd_mask_extra;
+ /** Update object hook indices & vertex parents. */
+ uint calc_object_remap : 1;
+ struct CustomData_MeshMasks cd_mask_extra;
};
-void BM_mesh_bm_to_me(
- struct Main *bmain, BMesh *bm, struct Mesh *me,
- const struct BMeshToMeshParams *params)
-ATTR_NONNULL(2, 3, 4);
-
-void BM_mesh_bm_to_me_for_eval(
- BMesh *bm, struct Mesh *me, const struct CustomData_MeshMasks *cd_mask_extra)
-ATTR_NONNULL(1, 2);
-
+void BM_mesh_bm_to_me(struct Main *bmain,
+ BMesh *bm,
+ struct Mesh *me,
+ const struct BMeshToMeshParams *params) ATTR_NONNULL(2, 3, 4);
+
+void BM_mesh_bm_to_me_for_eval(BMesh *bm,
+ struct Mesh *me,
+ const struct CustomData_MeshMasks *cd_mask_extra)
+ ATTR_NONNULL(1, 2);
#endif /* __BMESH_MESH_CONV_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_mesh_validate.c b/source/blender/bmesh/intern/bmesh_mesh_validate.c
index de0554c0cc2..3b6f63df089 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_validate.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_validate.c
@@ -26,20 +26,29 @@
/* debug builds only */
#ifdef DEBUG
-#include "BLI_utildefines.h"
-#include "BLI_edgehash.h"
+# include "BLI_utildefines.h"
+# include "BLI_edgehash.h"
-#include "bmesh.h"
-
-#include "bmesh_mesh_validate.h"
+# include "bmesh.h"
+# include "bmesh_mesh_validate.h"
/* macro which inserts the function name */
-#if defined __GNUC__
-# define ERRMSG(format, args...) { fprintf(stderr, "%s: " format ", " AT "\n", __func__, ##args); errtot++; } (void)0
-#else
-# define ERRMSG(format, ...) { fprintf(stderr, "%s: " format ", " AT "\n", __func__, __VA_ARGS__); errtot++; } (void)0
-#endif
+# if defined __GNUC__
+# define ERRMSG(format, args...) \
+ { \
+ fprintf(stderr, "%s: " format ", " AT "\n", __func__, ##args); \
+ errtot++; \
+ } \
+ (void)0
+# else
+# define ERRMSG(format, ...) \
+ { \
+ fprintf(stderr, "%s: " format ", " AT "\n", __func__, __VA_ARGS__); \
+ errtot++; \
+ } \
+ (void)0
+# endif
/**
* Check of this BMesh is valid, this function can be slow since its intended to help with debugging.
@@ -48,156 +57,166 @@
*/
bool BM_mesh_validate(BMesh *bm)
{
- EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, bm->totedge);
- int errtot;
-
- BMIter iter;
- BMVert *v;
- BMEdge *e;
- BMFace *f;
-
- int i, j;
-
- errtot = -1; /* 'ERRMSG' next line will set at zero */
- fprintf(stderr, "\n");
- ERRMSG("This is a debugging function and not intended for general use, running slow test!");
-
- /* force recalc, even if tagged as valid, since this mesh is suspect! */
- bm->elem_index_dirty |= BM_ALL;
- BM_mesh_elem_index_ensure(bm, BM_ALL);
-
- BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
- if (BM_elem_flag_test(v, BM_ELEM_SELECT | BM_ELEM_HIDDEN) == (BM_ELEM_SELECT | BM_ELEM_HIDDEN)) {
- ERRMSG("vert %d: is hidden and selected", i);
- }
-
- if (v->e) {
- if (!BM_vert_in_edge(v->e, v)) {
- ERRMSG("vert %d: is not in its referenced edge: %d", i, BM_elem_index_get(v->e));
- }
- }
- }
-
- /* check edges */
- BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
- void **val_p;
-
- if (e->v1 == e->v2) {
- ERRMSG("edge %d: duplicate index: %d", i, BM_elem_index_get(e->v1));
- }
-
- /* build edgehash at the same time */
- if (BLI_edgehash_ensure_p(edge_hash, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2), &val_p)) {
- BMEdge *e_other = *val_p;
- ERRMSG("edge %d, %d: are duplicates", i, BM_elem_index_get(e_other));
- }
- else {
- *val_p = e;
- }
- }
-
- /* edge radial structure */
- BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
- if (BM_elem_flag_test(e, BM_ELEM_SELECT | BM_ELEM_HIDDEN) == (BM_ELEM_SELECT | BM_ELEM_HIDDEN)) {
- ERRMSG("edge %d: is hidden and selected", i);
- }
-
- if (e->l) {
- BMLoop *l_iter;
- BMLoop *l_first;
-
- j = 0;
-
- l_iter = l_first = e->l;
- /* we could do more checks here, but save for face checks */
- do {
- if (l_iter->e != e) {
- ERRMSG("edge %d: has invalid loop, loop is of face %d", i, BM_elem_index_get(l_iter->f));
- }
- else if (BM_vert_in_edge(e, l_iter->v) == false) {
- ERRMSG("edge %d: has invalid loop with vert not in edge, loop is of face %d",
- i, BM_elem_index_get(l_iter->f));
- }
- else if (BM_vert_in_edge(e, l_iter->next->v) == false) {
- ERRMSG("edge %d: has invalid loop with next vert not in edge, loop is of face %d",
- i, BM_elem_index_get(l_iter->f));
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
- }
-
- /* face structure */
- BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
- BMLoop *l_iter;
- BMLoop *l_first;
-
- if (BM_elem_flag_test(f, BM_ELEM_SELECT | BM_ELEM_HIDDEN) == (BM_ELEM_SELECT | BM_ELEM_HIDDEN)) {
- ERRMSG("face %d: is hidden and selected", i);
- }
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
-
- do {
- BM_elem_flag_disable(l_iter, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_disable(l_iter->e, BM_ELEM_INTERNAL_TAG);
- } while ((l_iter = l_iter->next) != l_first);
-
- j = 0;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (BM_elem_flag_test(l_iter, BM_ELEM_INTERNAL_TAG)) {
- ERRMSG("face %d: has duplicate loop at corner: %d", i, j);
- }
- if (BM_elem_flag_test(l_iter->v, BM_ELEM_INTERNAL_TAG)) {
- ERRMSG("face %d: has duplicate vert: %d, at corner: %d", i, BM_elem_index_get(l_iter->v), j);
- }
- if (BM_elem_flag_test(l_iter->e, BM_ELEM_INTERNAL_TAG)) {
- ERRMSG("face %d: has duplicate edge: %d, at corner: %d", i, BM_elem_index_get(l_iter->e), j);
- }
-
- /* adjacent data checks */
- if (l_iter->f != f) {
- ERRMSG("face %d: has loop that points to face: %d at corner: %d", i, BM_elem_index_get(l_iter->f), j);
- }
- if (l_iter != l_iter->prev->next) {
- ERRMSG("face %d: has invalid 'prev/next' at corner: %d", i, j);
- }
- if (l_iter != l_iter->next->prev) {
- ERRMSG("face %d: has invalid 'next/prev' at corner: %d", i, j);
- }
- if (l_iter != l_iter->radial_prev->radial_next) {
- ERRMSG("face %d: has invalid 'radial_prev/radial_next' at corner: %d", i, j);
- }
- if (l_iter != l_iter->radial_next->radial_prev) {
- ERRMSG("face %d: has invalid 'radial_next/radial_prev' at corner: %d", i, j);
- }
-
- BM_elem_flag_enable(l_iter, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_enable(l_iter->v, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_enable(l_iter->e, BM_ELEM_INTERNAL_TAG);
- j++;
- } while ((l_iter = l_iter->next) != l_first);
-
- if (j != f->len) {
- ERRMSG("face %d: has length of %d but should be %d", i, f->len, j);
- }
-
- /* leave elements un-tagged, not essential but nice to avoid unintended dirty tag use later. */
- do {
- BM_elem_flag_disable(l_iter, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_disable(l_iter->e, BM_ELEM_INTERNAL_TAG);
- } while ((l_iter = l_iter->next) != l_first);
- }
-
- BLI_edgehash_free(edge_hash, NULL);
-
- const bool is_valid = (errtot == 0);
- ERRMSG("Finished - errors %d", errtot);
- return is_valid;
+ EdgeHash *edge_hash = BLI_edgehash_new_ex(__func__, bm->totedge);
+ int errtot;
+
+ BMIter iter;
+ BMVert *v;
+ BMEdge *e;
+ BMFace *f;
+
+ int i, j;
+
+ errtot = -1; /* 'ERRMSG' next line will set at zero */
+ fprintf(stderr, "\n");
+ ERRMSG("This is a debugging function and not intended for general use, running slow test!");
+
+ /* force recalc, even if tagged as valid, since this mesh is suspect! */
+ bm->elem_index_dirty |= BM_ALL;
+ BM_mesh_elem_index_ensure(bm, BM_ALL);
+
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ if (BM_elem_flag_test(v, BM_ELEM_SELECT | BM_ELEM_HIDDEN) ==
+ (BM_ELEM_SELECT | BM_ELEM_HIDDEN)) {
+ ERRMSG("vert %d: is hidden and selected", i);
+ }
+
+ if (v->e) {
+ if (!BM_vert_in_edge(v->e, v)) {
+ ERRMSG("vert %d: is not in its referenced edge: %d", i, BM_elem_index_get(v->e));
+ }
+ }
+ }
+
+ /* check edges */
+ BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
+ void **val_p;
+
+ if (e->v1 == e->v2) {
+ ERRMSG("edge %d: duplicate index: %d", i, BM_elem_index_get(e->v1));
+ }
+
+ /* build edgehash at the same time */
+ if (BLI_edgehash_ensure_p(
+ edge_hash, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2), &val_p)) {
+ BMEdge *e_other = *val_p;
+ ERRMSG("edge %d, %d: are duplicates", i, BM_elem_index_get(e_other));
+ }
+ else {
+ *val_p = e;
+ }
+ }
+
+ /* edge radial structure */
+ BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
+ if (BM_elem_flag_test(e, BM_ELEM_SELECT | BM_ELEM_HIDDEN) ==
+ (BM_ELEM_SELECT | BM_ELEM_HIDDEN)) {
+ ERRMSG("edge %d: is hidden and selected", i);
+ }
+
+ if (e->l) {
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ j = 0;
+
+ l_iter = l_first = e->l;
+ /* we could do more checks here, but save for face checks */
+ do {
+ if (l_iter->e != e) {
+ ERRMSG("edge %d: has invalid loop, loop is of face %d", i, BM_elem_index_get(l_iter->f));
+ }
+ else if (BM_vert_in_edge(e, l_iter->v) == false) {
+ ERRMSG("edge %d: has invalid loop with vert not in edge, loop is of face %d",
+ i,
+ BM_elem_index_get(l_iter->f));
+ }
+ else if (BM_vert_in_edge(e, l_iter->next->v) == false) {
+ ERRMSG("edge %d: has invalid loop with next vert not in edge, loop is of face %d",
+ i,
+ BM_elem_index_get(l_iter->f));
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ }
+
+ /* face structure */
+ BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ if (BM_elem_flag_test(f, BM_ELEM_SELECT | BM_ELEM_HIDDEN) ==
+ (BM_ELEM_SELECT | BM_ELEM_HIDDEN)) {
+ ERRMSG("face %d: is hidden and selected", i);
+ }
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+
+ do {
+ BM_elem_flag_disable(l_iter, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_disable(l_iter->e, BM_ELEM_INTERNAL_TAG);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ j = 0;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter, BM_ELEM_INTERNAL_TAG)) {
+ ERRMSG("face %d: has duplicate loop at corner: %d", i, j);
+ }
+ if (BM_elem_flag_test(l_iter->v, BM_ELEM_INTERNAL_TAG)) {
+ ERRMSG(
+ "face %d: has duplicate vert: %d, at corner: %d", i, BM_elem_index_get(l_iter->v), j);
+ }
+ if (BM_elem_flag_test(l_iter->e, BM_ELEM_INTERNAL_TAG)) {
+ ERRMSG(
+ "face %d: has duplicate edge: %d, at corner: %d", i, BM_elem_index_get(l_iter->e), j);
+ }
+
+ /* adjacent data checks */
+ if (l_iter->f != f) {
+ ERRMSG("face %d: has loop that points to face: %d at corner: %d",
+ i,
+ BM_elem_index_get(l_iter->f),
+ j);
+ }
+ if (l_iter != l_iter->prev->next) {
+ ERRMSG("face %d: has invalid 'prev/next' at corner: %d", i, j);
+ }
+ if (l_iter != l_iter->next->prev) {
+ ERRMSG("face %d: has invalid 'next/prev' at corner: %d", i, j);
+ }
+ if (l_iter != l_iter->radial_prev->radial_next) {
+ ERRMSG("face %d: has invalid 'radial_prev/radial_next' at corner: %d", i, j);
+ }
+ if (l_iter != l_iter->radial_next->radial_prev) {
+ ERRMSG("face %d: has invalid 'radial_next/radial_prev' at corner: %d", i, j);
+ }
+
+ BM_elem_flag_enable(l_iter, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_enable(l_iter->v, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_enable(l_iter->e, BM_ELEM_INTERNAL_TAG);
+ j++;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (j != f->len) {
+ ERRMSG("face %d: has length of %d but should be %d", i, f->len, j);
+ }
+
+ /* leave elements un-tagged, not essential but nice to avoid unintended dirty tag use later. */
+ do {
+ BM_elem_flag_disable(l_iter, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_disable(l_iter->v, BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_disable(l_iter->e, BM_ELEM_INTERNAL_TAG);
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ BLI_edgehash_free(edge_hash, NULL);
+
+ const bool is_valid = (errtot == 0);
+ ERRMSG("Finished - errors %d", errtot);
+ return is_valid;
}
-
#endif
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index e1aa5fcfee1..1075b3753da 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -58,39 +58,39 @@
*/
bool BM_vert_dissolve(BMesh *bm, BMVert *v)
{
- /* logic for 3 or more is identical */
- const int len = BM_vert_edge_count_at_most(v, 3);
-
- if (len == 1) {
- BM_vert_kill(bm, v); /* will kill edges too */
- return true;
- }
- else if (!BM_vert_is_manifold(v)) {
- if (!v->e) {
- BM_vert_kill(bm, v);
- return true;
- }
- else if (!v->e->l) {
- if (len == 2) {
- return (BM_vert_collapse_edge(bm, v->e, v, true, true) != NULL);
- }
- else {
- /* used to kill the vertex here, but it may be connected to faces.
- * so better do nothing */
- return false;
- }
- }
- else {
- return false;
- }
- }
- else if (len == 2 && BM_vert_face_count_is_equal(v, 1)) {
- /* boundary vertex on a face */
- return (BM_vert_collapse_edge(bm, v->e, v, true, true) != NULL);
- }
- else {
- return BM_disk_dissolve(bm, v);
- }
+ /* logic for 3 or more is identical */
+ const int len = BM_vert_edge_count_at_most(v, 3);
+
+ if (len == 1) {
+ BM_vert_kill(bm, v); /* will kill edges too */
+ return true;
+ }
+ else if (!BM_vert_is_manifold(v)) {
+ if (!v->e) {
+ BM_vert_kill(bm, v);
+ return true;
+ }
+ else if (!v->e->l) {
+ if (len == 2) {
+ return (BM_vert_collapse_edge(bm, v->e, v, true, true) != NULL);
+ }
+ else {
+ /* used to kill the vertex here, but it may be connected to faces.
+ * so better do nothing */
+ return false;
+ }
+ }
+ else {
+ return false;
+ }
+ }
+ else if (len == 2 && BM_vert_face_count_is_equal(v, 1)) {
+ /* boundary vertex on a face */
+ return (BM_vert_collapse_edge(bm, v->e, v, true, true) != NULL);
+ }
+ else {
+ return BM_disk_dissolve(bm, v);
+ }
}
/**
@@ -98,115 +98,115 @@ bool BM_vert_dissolve(BMesh *bm, BMVert *v)
*/
bool BM_disk_dissolve(BMesh *bm, BMVert *v)
{
- BMEdge *e, *keepedge = NULL, *baseedge = NULL;
- int len = 0;
-
- if (!BM_vert_is_manifold(v)) {
- return false;
- }
-
- if (v->e) {
- /* v->e we keep, what else */
- e = v->e;
- do {
- e = bmesh_disk_edge_next(e, v);
- if (!(BM_edge_share_face_check(e, v->e))) {
- keepedge = e;
- baseedge = v->e;
- break;
- }
- len++;
- } while (e != v->e);
- }
-
- /* this code for handling 2 and 3-valence verts
- * may be totally bad */
- if (keepedge == NULL && len == 3) {
+ BMEdge *e, *keepedge = NULL, *baseedge = NULL;
+ int len = 0;
+
+ if (!BM_vert_is_manifold(v)) {
+ return false;
+ }
+
+ if (v->e) {
+ /* v->e we keep, what else */
+ e = v->e;
+ do {
+ e = bmesh_disk_edge_next(e, v);
+ if (!(BM_edge_share_face_check(e, v->e))) {
+ keepedge = e;
+ baseedge = v->e;
+ break;
+ }
+ len++;
+ } while (e != v->e);
+ }
+
+ /* this code for handling 2 and 3-valence verts
+ * may be totally bad */
+ if (keepedge == NULL && len == 3) {
#if 0
- /* handle specific case for three-valence. solve it by
- * increasing valence to four. this may be hackish. . */
- BMLoop *l_a = BM_face_vert_share_loop(e->l->f, v);
- BMLoop *l_b = (e->l->v == v) ? e->l->next : e->l;
+ /* handle specific case for three-valence. solve it by
+ * increasing valence to four. this may be hackish. . */
+ BMLoop *l_a = BM_face_vert_share_loop(e->l->f, v);
+ BMLoop *l_b = (e->l->v == v) ? e->l->next : e->l;
- if (!BM_face_split(bm, e->l->f, l_a, l_b, NULL, NULL, false))
- return false;
+ if (!BM_face_split(bm, e->l->f, l_a, l_b, NULL, NULL, false))
+ return false;
- if (!BM_disk_dissolve(bm, v)) {
- return false;
- }
+ if (!BM_disk_dissolve(bm, v)) {
+ return false;
+ }
#else
- if (UNLIKELY(!BM_faces_join_pair(bm, e->l, e->l->radial_next, true))) {
- return false;
- }
- else if (UNLIKELY(!BM_vert_collapse_faces(bm, v->e, v, 1.0, true, false, true))) {
- return false;
- }
+ if (UNLIKELY(!BM_faces_join_pair(bm, e->l, e->l->radial_next, true))) {
+ return false;
+ }
+ else if (UNLIKELY(!BM_vert_collapse_faces(bm, v->e, v, 1.0, true, false, true))) {
+ return false;
+ }
#endif
- return true;
- }
- else if (keepedge == NULL && len == 2) {
- /* collapse the vertex */
- e = BM_vert_collapse_faces(bm, v->e, v, 1.0, true, true, true);
-
- if (!e) {
- return false;
- }
-
- /* handle two-valence */
- if (e->l != e->l->radial_next) {
- if (!BM_faces_join_pair(bm, e->l, e->l->radial_next, true)) {
- return false;
- }
- }
-
- return true;
- }
-
- if (keepedge) {
- bool done = false;
-
- while (!done) {
- done = true;
- e = v->e;
- do {
- BMFace *f = NULL;
- if (BM_edge_is_manifold(e) && (e != baseedge) && (e != keepedge)) {
- f = BM_faces_join_pair(bm, e->l, e->l->radial_next, true);
- /* return if couldn't join faces in manifold
- * conditions */
- /* !disabled for testing why bad things happen */
- if (!f) {
- return false;
- }
- }
-
- if (f) {
- done = false;
- break;
- }
- } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
- }
-
- /* collapse the vertex */
- /* note, the baseedge can be a boundary of manifold, use this as join_faces arg */
- e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, true, !BM_edge_is_boundary(baseedge), true);
-
- if (!e) {
- return false;
- }
-
- if (e->l) {
- /* get remaining two faces */
- if (e->l != e->l->radial_next) {
- /* join two remaining faces */
- if (!BM_faces_join_pair(bm, e->l, e->l->radial_next, true)) {
- return false;
- }
- }
- }
- }
-
- return true;
+ return true;
+ }
+ else if (keepedge == NULL && len == 2) {
+ /* collapse the vertex */
+ e = BM_vert_collapse_faces(bm, v->e, v, 1.0, true, true, true);
+
+ if (!e) {
+ return false;
+ }
+
+ /* handle two-valence */
+ if (e->l != e->l->radial_next) {
+ if (!BM_faces_join_pair(bm, e->l, e->l->radial_next, true)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ if (keepedge) {
+ bool done = false;
+
+ while (!done) {
+ done = true;
+ e = v->e;
+ do {
+ BMFace *f = NULL;
+ if (BM_edge_is_manifold(e) && (e != baseedge) && (e != keepedge)) {
+ f = BM_faces_join_pair(bm, e->l, e->l->radial_next, true);
+ /* return if couldn't join faces in manifold
+ * conditions */
+ /* !disabled for testing why bad things happen */
+ if (!f) {
+ return false;
+ }
+ }
+
+ if (f) {
+ done = false;
+ break;
+ }
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
+ }
+
+ /* collapse the vertex */
+ /* note, the baseedge can be a boundary of manifold, use this as join_faces arg */
+ e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, true, !BM_edge_is_boundary(baseedge), true);
+
+ if (!e) {
+ return false;
+ }
+
+ if (e->l) {
+ /* get remaining two faces */
+ if (e->l != e->l->radial_next) {
+ /* join two remaining faces */
+ if (!BM_faces_join_pair(bm, e->l, e->l->radial_next, true)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
}
/**
@@ -224,15 +224,15 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v)
*/
BMFace *BM_faces_join_pair(BMesh *bm, BMLoop *l_a, BMLoop *l_b, const bool do_del)
{
- BLI_assert((l_a != l_b) && (l_a->e == l_b->e));
+ BLI_assert((l_a != l_b) && (l_a->e == l_b->e));
- if (l_a->v == l_b->v) {
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
- bmesh_kernel_loop_reverse(bm, l_b->f, cd_loop_mdisp_offset, true);
- }
+ if (l_a->v == l_b->v) {
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+ bmesh_kernel_loop_reverse(bm, l_b->f, cd_loop_mdisp_offset, true);
+ }
- BMFace *faces[2] = {l_a->f, l_b->f};
- return BM_faces_join(bm, faces, 2, do_del);
+ BMFace *faces[2] = {l_a->f, l_b->f};
+ return BM_faces_join(bm, faces, 2, do_del);
}
/**
@@ -253,67 +253,68 @@ BMFace *BM_faces_join_pair(BMesh *bm, BMLoop *l_a, BMLoop *l_b, const bool do_de
* if the split is successful (and the original original face will be the
* other side). NULL if the split fails.
*/
-BMFace *BM_face_split(
- BMesh *bm, BMFace *f,
- BMLoop *l_a, BMLoop *l_b,
- BMLoop **r_l, BMEdge *example,
- const bool no_double)
+BMFace *BM_face_split(BMesh *bm,
+ BMFace *f,
+ BMLoop *l_a,
+ BMLoop *l_b,
+ BMLoop **r_l,
+ BMEdge *example,
+ const bool no_double)
{
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
- BMFace *f_new, *f_tmp;
-
- BLI_assert(l_a != l_b);
- BLI_assert(f == l_a->f && f == l_b->f);
- BLI_assert(!BM_loop_is_adjacent(l_a, l_b));
-
- /* could be an assert */
- if (UNLIKELY(BM_loop_is_adjacent(l_a, l_b)) ||
- UNLIKELY((f != l_a->f || f != l_b->f)))
- {
- if (r_l) {
- *r_l = NULL;
- }
- return NULL;
- }
-
- /* do we have a multires layer? */
- if (cd_loop_mdisp_offset != -1) {
- f_tmp = BM_face_copy(bm, bm, f, false, false);
- }
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+ BMFace *f_new, *f_tmp;
+
+ BLI_assert(l_a != l_b);
+ BLI_assert(f == l_a->f && f == l_b->f);
+ BLI_assert(!BM_loop_is_adjacent(l_a, l_b));
+
+ /* could be an assert */
+ if (UNLIKELY(BM_loop_is_adjacent(l_a, l_b)) || UNLIKELY((f != l_a->f || f != l_b->f))) {
+ if (r_l) {
+ *r_l = NULL;
+ }
+ return NULL;
+ }
+
+ /* do we have a multires layer? */
+ if (cd_loop_mdisp_offset != -1) {
+ f_tmp = BM_face_copy(bm, bm, f, false, false);
+ }
#ifdef USE_BMESH_HOLES
- f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, r_l, NULL, example, no_double);
+ f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, r_l, NULL, example, no_double);
#else
- f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, r_l, example, no_double);
+ f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, r_l, example, no_double);
#endif
- if (f_new) {
- /* handle multires update */
- if (cd_loop_mdisp_offset != -1) {
- float f_dst_center[3];
- float f_src_center[3];
+ if (f_new) {
+ /* handle multires update */
+ if (cd_loop_mdisp_offset != -1) {
+ float f_dst_center[3];
+ float f_src_center[3];
- BM_face_calc_center_median(f_tmp, f_src_center);
+ BM_face_calc_center_median(f_tmp, f_src_center);
- BM_face_calc_center_median(f, f_dst_center);
- BM_face_interp_multires_ex(bm, f, f_tmp, f_dst_center, f_src_center, cd_loop_mdisp_offset);
+ BM_face_calc_center_median(f, f_dst_center);
+ BM_face_interp_multires_ex(bm, f, f_tmp, f_dst_center, f_src_center, cd_loop_mdisp_offset);
- BM_face_calc_center_median(f_new, f_dst_center);
- BM_face_interp_multires_ex(bm, f_new, f_tmp, f_dst_center, f_src_center, cd_loop_mdisp_offset);
+ BM_face_calc_center_median(f_new, f_dst_center);
+ BM_face_interp_multires_ex(
+ bm, f_new, f_tmp, f_dst_center, f_src_center, cd_loop_mdisp_offset);
#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, f_new);
+ /* BM_face_multires_bounds_smooth doesn't flip displacement correct */
+ BM_face_multires_bounds_smooth(bm, f);
+ BM_face_multires_bounds_smooth(bm, f_new);
#endif
- }
- }
+ }
+ }
- if (cd_loop_mdisp_offset != -1) {
- BM_face_kill(bm, f_tmp);
- }
+ if (cd_loop_mdisp_offset != -1) {
+ BM_face_kill(bm, f_tmp);
+ }
- return f_new;
+ return f_new;
}
/**
@@ -333,74 +334,75 @@ BMFace *BM_face_split(
* if the split is successful (and the original original face will be the
* other side). NULL if the split fails.
*/
-BMFace *BM_face_split_n(
- BMesh *bm, BMFace *f,
- BMLoop *l_a, BMLoop *l_b,
- float cos[][3], int n,
- BMLoop **r_l, BMEdge *example)
+BMFace *BM_face_split_n(BMesh *bm,
+ BMFace *f,
+ BMLoop *l_a,
+ BMLoop *l_b,
+ float cos[][3],
+ int n,
+ BMLoop **r_l,
+ BMEdge *example)
{
- BMFace *f_new, *f_tmp;
- BMLoop *l_new;
- BMEdge *e, *e_new;
- BMVert *v_new;
- // BMVert *v_a = l_a->v; /* UNUSED */
- BMVert *v_b = l_b->v;
- int i, j;
-
- BLI_assert(l_a != l_b);
- BLI_assert(f == l_a->f && f == l_b->f);
- BLI_assert(!((n == 0) && BM_loop_is_adjacent(l_a, l_b)));
-
- /* could be an assert */
- if (UNLIKELY((n == 0) && BM_loop_is_adjacent(l_a, l_b)) ||
- UNLIKELY(l_a->f != l_b->f))
- {
- if (r_l) {
- *r_l = NULL;
- }
- return NULL;
- }
-
- f_tmp = BM_face_copy(bm, bm, f, true, true);
+ BMFace *f_new, *f_tmp;
+ BMLoop *l_new;
+ BMEdge *e, *e_new;
+ BMVert *v_new;
+ // BMVert *v_a = l_a->v; /* UNUSED */
+ BMVert *v_b = l_b->v;
+ int i, j;
+
+ BLI_assert(l_a != l_b);
+ BLI_assert(f == l_a->f && f == l_b->f);
+ BLI_assert(!((n == 0) && BM_loop_is_adjacent(l_a, l_b)));
+
+ /* could be an assert */
+ if (UNLIKELY((n == 0) && BM_loop_is_adjacent(l_a, l_b)) || UNLIKELY(l_a->f != l_b->f)) {
+ if (r_l) {
+ *r_l = NULL;
+ }
+ return NULL;
+ }
+
+ f_tmp = BM_face_copy(bm, bm, f, true, true);
#ifdef USE_BMESH_HOLES
- f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, &l_new, NULL, example, false);
+ f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, &l_new, NULL, example, false);
#else
- f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, &l_new, example, false);
+ f_new = bmesh_kernel_split_face_make_edge(bm, f, l_a, l_b, &l_new, example, false);
#endif
- /* bmesh_kernel_split_face_make_edge returns in 'l_new' a Loop for f_new going from 'v_a' to 'v_b'.
- * The radial_next is for 'f' and goes from 'v_b' to 'v_a' */
-
- if (f_new) {
- e = l_new->e;
- for (i = 0; i < n; i++) {
- v_new = bmesh_kernel_split_edge_make_vert(bm, v_b, e, &e_new);
- BLI_assert(v_new != NULL);
- /* bmesh_kernel_split_edge_make_vert returns in 'e_new' the edge going from 'v_new' to 'v_b' */
- copy_v3_v3(v_new->co, cos[i]);
-
- /* 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 : e_new;
- BMLoop *l_iter = e_iter->l;
- do {
- if (l_iter->v == v_new) {
- /* this interpolates both loop and vertex data */
- BM_loop_interp_from_face(bm, l_iter, f_tmp, true, true);
- }
- } while ((l_iter = l_iter->radial_next) != e_iter->l);
- }
- e = e_new;
- }
- }
-
- BM_face_verts_kill(bm, f_tmp);
-
- if (r_l) {
- *r_l = l_new;
- }
-
- return f_new;
+ /* bmesh_kernel_split_face_make_edge returns in 'l_new' a Loop for f_new going from 'v_a' to 'v_b'.
+ * The radial_next is for 'f' and goes from 'v_b' to 'v_a' */
+
+ if (f_new) {
+ e = l_new->e;
+ for (i = 0; i < n; i++) {
+ v_new = bmesh_kernel_split_edge_make_vert(bm, v_b, e, &e_new);
+ BLI_assert(v_new != NULL);
+ /* bmesh_kernel_split_edge_make_vert returns in 'e_new' the edge going from 'v_new' to 'v_b' */
+ copy_v3_v3(v_new->co, cos[i]);
+
+ /* 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 : e_new;
+ BMLoop *l_iter = e_iter->l;
+ do {
+ if (l_iter->v == v_new) {
+ /* this interpolates both loop and vertex data */
+ BM_loop_interp_from_face(bm, l_iter, f_tmp, true, true);
+ }
+ } while ((l_iter = l_iter->radial_next) != e_iter->l);
+ }
+ e = e_new;
+ }
+ }
+
+ BM_face_verts_kill(bm, f_tmp);
+
+ if (r_l) {
+ *r_l = l_new;
+ }
+
+ return f_new;
}
/**
@@ -426,89 +428,90 @@ BMFace *BM_face_split_n(
*
* \returns The New Edge
*/
-BMEdge *BM_vert_collapse_faces(
- BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float fac,
- const bool do_del, const bool join_faces, const bool kill_degenerate_faces)
+BMEdge *BM_vert_collapse_faces(BMesh *bm,
+ BMEdge *e_kill,
+ BMVert *v_kill,
+ float fac,
+ const bool do_del,
+ const bool join_faces,
+ const bool kill_degenerate_faces)
{
- BMEdge *e_new = NULL;
- BMVert *tv = BM_edge_other_vert(e_kill, v_kill);
-
- BMEdge *e2;
- BMVert *tv2;
-
- /* Only intended to be called for 2-valence vertices */
- BLI_assert(bmesh_disk_count(v_kill) <= 2);
-
-
- /* first modify the face loop data */
-
- if (e_kill->l) {
- BMLoop *l_iter;
- const float w[2] = {1.0f - fac, fac};
-
- l_iter = e_kill->l;
- do {
- if (l_iter->v == tv && l_iter->next->v == v_kill) {
- const void *src[2];
- BMLoop *tvloop = l_iter;
- BMLoop *kvloop = l_iter->next;
-
- src[0] = kvloop->head.data;
- src[1] = tvloop->head.data;
- CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, kvloop->head.data);
- }
- } while ((l_iter = l_iter->radial_next) != e_kill->l);
- }
-
- /* now interpolate the vertex data */
- BM_data_interp_from_verts(bm, v_kill, tv, v_kill, fac);
-
- e2 = bmesh_disk_edge_next(e_kill, v_kill);
- tv2 = BM_edge_other_vert(e2, v_kill);
-
- if (join_faces) {
- BMIter fiter;
- BMFace **faces = NULL;
- BMFace *f;
- BLI_array_staticdeclare(faces, BM_DEFAULT_ITER_STACK_SIZE);
-
- BM_ITER_ELEM (f, &fiter, v_kill, BM_FACES_OF_VERT) {
- BLI_array_append(faces, f);
- }
-
- if (BLI_array_len(faces) >= 2) {
- BMFace *f2 = BM_faces_join(bm, faces, BLI_array_len(faces), true);
- if (f2) {
- BMLoop *l_a, *l_b;
-
- if ((l_a = BM_face_vert_share_loop(f2, tv)) &&
- (l_b = BM_face_vert_share_loop(f2, tv2)))
- {
- BMLoop *l_new;
-
- if (BM_face_split(bm, f2, l_a, l_b, &l_new, NULL, false)) {
- e_new = l_new->e;
- }
- }
- }
- }
-
- BLI_assert(BLI_array_len(faces) < 8);
-
- BLI_array_free(faces);
- }
- else {
- /* single face or no faces */
- /* same as BM_vert_collapse_edge() however we already
- * have vars to perform this operation so don't call. */
- e_new = bmesh_kernel_join_edge_kill_vert(bm, e_kill, v_kill, do_del, true, kill_degenerate_faces);
- /* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */
- }
-
- return e_new;
+ BMEdge *e_new = NULL;
+ BMVert *tv = BM_edge_other_vert(e_kill, v_kill);
+
+ BMEdge *e2;
+ BMVert *tv2;
+
+ /* Only intended to be called for 2-valence vertices */
+ BLI_assert(bmesh_disk_count(v_kill) <= 2);
+
+ /* first modify the face loop data */
+
+ if (e_kill->l) {
+ BMLoop *l_iter;
+ const float w[2] = {1.0f - fac, fac};
+
+ l_iter = e_kill->l;
+ do {
+ if (l_iter->v == tv && l_iter->next->v == v_kill) {
+ const void *src[2];
+ BMLoop *tvloop = l_iter;
+ BMLoop *kvloop = l_iter->next;
+
+ src[0] = kvloop->head.data;
+ src[1] = tvloop->head.data;
+ CustomData_bmesh_interp(&bm->ldata, src, w, NULL, 2, kvloop->head.data);
+ }
+ } while ((l_iter = l_iter->radial_next) != e_kill->l);
+ }
+
+ /* now interpolate the vertex data */
+ BM_data_interp_from_verts(bm, v_kill, tv, v_kill, fac);
+
+ e2 = bmesh_disk_edge_next(e_kill, v_kill);
+ tv2 = BM_edge_other_vert(e2, v_kill);
+
+ if (join_faces) {
+ BMIter fiter;
+ BMFace **faces = NULL;
+ BMFace *f;
+ BLI_array_staticdeclare(faces, BM_DEFAULT_ITER_STACK_SIZE);
+
+ BM_ITER_ELEM (f, &fiter, v_kill, BM_FACES_OF_VERT) {
+ BLI_array_append(faces, f);
+ }
+
+ if (BLI_array_len(faces) >= 2) {
+ BMFace *f2 = BM_faces_join(bm, faces, BLI_array_len(faces), true);
+ if (f2) {
+ BMLoop *l_a, *l_b;
+
+ if ((l_a = BM_face_vert_share_loop(f2, tv)) && (l_b = BM_face_vert_share_loop(f2, tv2))) {
+ BMLoop *l_new;
+
+ if (BM_face_split(bm, f2, l_a, l_b, &l_new, NULL, false)) {
+ e_new = l_new->e;
+ }
+ }
+ }
+ }
+
+ BLI_assert(BLI_array_len(faces) < 8);
+
+ BLI_array_free(faces);
+ }
+ else {
+ /* single face or no faces */
+ /* same as BM_vert_collapse_edge() however we already
+ * have vars to perform this operation so don't call. */
+ e_new = bmesh_kernel_join_edge_kill_vert(
+ bm, e_kill, v_kill, do_del, true, kill_degenerate_faces);
+ /* e_new = BM_edge_exists(tv, tv2); */ /* same as return above */
+ }
+
+ return e_new;
}
-
/**
* \brief Vert Collapse Faces
*
@@ -517,35 +520,34 @@ BMEdge *BM_vert_collapse_faces(
* \return The New Edge
*/
BMEdge *BM_vert_collapse_edge(
- BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
- const bool do_del, const bool kill_degenerate_faces)
+ BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool do_del, const bool kill_degenerate_faces)
{
- /* nice example implementation but we want loops to have their customdata
- * accounted for */
+ /* nice example implementation but we want loops to have their customdata
+ * accounted for */
#if 0
- 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 = BM_edge_other_vert(e_kill, v_kill);
- if (tv) {
- BMEdge *e2 = bmesh_disk_edge_next(e_kill, v_kill);
- if (e2) {
- BMVert *tv2 = BM_edge_other_vert(e2, v_kill);
- if (tv2) {
- /* only action, other calls here only get the edge to return */
- e_new = bmesh_kernel_join_edge_kill_vert(bm, e_kill, v_kill, do_del, true, kill_degenerate_faces);
- }
- }
- }
-
- return e_new;
+ 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 = BM_edge_other_vert(e_kill, v_kill);
+ if (tv) {
+ BMEdge *e2 = bmesh_disk_edge_next(e_kill, v_kill);
+ if (e2) {
+ BMVert *tv2 = BM_edge_other_vert(e2, v_kill);
+ if (tv2) {
+ /* only action, other calls here only get the edge to return */
+ e_new = bmesh_kernel_join_edge_kill_vert(bm, e_kill, v_kill, do_del, true, kill_degenerate_faces);
+ }
+ }
+ }
+
+ 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, e_kill, v_kill, 1.0f, do_del, false, kill_degenerate_faces);
+ /* with these args faces are never joined, same as above
+ * but account for loop customdata */
+ return BM_vert_collapse_faces(bm, e_kill, v_kill, 1.0f, do_del, false, kill_degenerate_faces);
#endif
}
@@ -555,10 +557,9 @@ BMEdge *BM_vert_collapse_edge(
* Collapse and edge into a single vertex.
*/
BMVert *BM_edge_collapse(
- BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
- const bool do_del, const bool kill_degenerate_faces)
+ BMesh *bm, BMEdge *e_kill, BMVert *v_kill, const bool do_del, const bool kill_degenerate_faces)
{
- return bmesh_kernel_join_vert_kill_edge(bm, e_kill, v_kill, do_del, true, kill_degenerate_faces);
+ return bmesh_kernel_join_vert_kill_edge(bm, e_kill, v_kill, do_del, true, kill_degenerate_faces);
}
/**
@@ -582,116 +583,117 @@ BMVert *BM_edge_collapse(
*/
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
{
- BMVert *v_new, *v_other;
- BMEdge *e_new;
- BMFace **oldfaces = NULL;
- BLI_array_staticdeclare(oldfaces, 32);
- const int cd_loop_mdisp_offset = BM_edge_is_wire(e) ? -1 : CustomData_get_offset(&bm->ldata, CD_MDISPS);
-
- BLI_assert(BM_vert_in_edge(e, v) == true);
-
- /* do we have a multi-res layer? */
- if (cd_loop_mdisp_offset != -1) {
- BMLoop *l;
- int i;
-
- l = e->l;
- do {
- BLI_array_append(oldfaces, l->f);
- l = l->radial_next;
- } while (l != e->l);
-
- /* flag existing faces so we can differentiate oldfaces from new faces */
- for (i = 0; i < BLI_array_len(oldfaces); i++) {
- BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP);
- oldfaces[i] = BM_face_copy(bm, bm, oldfaces[i], true, true);
- BM_ELEM_API_FLAG_DISABLE(oldfaces[i], _FLAG_OVERLAP);
- }
- }
-
- v_other = BM_edge_other_vert(e, v);
- v_new = bmesh_kernel_split_edge_make_vert(bm, v, e, &e_new);
- if (r_e != NULL) {
- *r_e = e_new;
- }
-
- BLI_assert(v_new != NULL);
- BLI_assert(BM_vert_in_edge(e_new, v) && BM_vert_in_edge(e_new, v_new));
- BLI_assert(BM_vert_in_edge(e, v_new) && BM_vert_in_edge(e, v_other));
-
- sub_v3_v3v3(v_new->co, v_other->co, v->co);
- madd_v3_v3v3fl(v_new->co, v->co, v_new->co, fac);
-
- e_new->head.hflag = e->head.hflag;
- BM_elem_attrs_copy(bm, bm, e, e_new);
-
- /* v->v_new->v2 */
- BM_data_interp_face_vert_edge(bm, v_other, v, v_new, e, fac);
- BM_data_interp_from_verts(bm, v, v_other, v_new, fac);
-
- if (cd_loop_mdisp_offset != -1) {
- int i, j;
-
- /* interpolate new/changed loop data from copied old faces */
- for (i = 0; i < BLI_array_len(oldfaces); i++) {
- float f_center_old[3];
-
- BM_face_calc_center_median(oldfaces[i], f_center_old);
-
- for (j = 0; j < 2; j++) {
- BMEdge *e1 = j ? e_new : e;
- BMLoop *l;
-
- l = e1->l;
-
- if (UNLIKELY(!l)) {
- BMESH_ASSERT(0);
- break;
- }
-
- do {
- /* check this is an old face */
- if (BM_ELEM_API_FLAG_TEST(l->f, _FLAG_OVERLAP)) {
- float f_center[3];
-
- BM_face_calc_center_median(l->f, f_center);
- BM_face_interp_multires_ex(
- bm, l->f, oldfaces[i],
- f_center, f_center_old, cd_loop_mdisp_offset);
- }
- l = l->radial_next;
- } while (l != e1->l);
- }
- }
-
- /* destroy the old faces */
- for (i = 0; i < BLI_array_len(oldfaces); i++) {
- BM_face_verts_kill(bm, oldfaces[i]);
- }
-
- /* fix boundaries a bit, doesn't work too well quite yet */
+ BMVert *v_new, *v_other;
+ BMEdge *e_new;
+ BMFace **oldfaces = NULL;
+ BLI_array_staticdeclare(oldfaces, 32);
+ const int cd_loop_mdisp_offset = BM_edge_is_wire(e) ?
+ -1 :
+ CustomData_get_offset(&bm->ldata, CD_MDISPS);
+
+ BLI_assert(BM_vert_in_edge(e, v) == true);
+
+ /* do we have a multi-res layer? */
+ if (cd_loop_mdisp_offset != -1) {
+ BMLoop *l;
+ int i;
+
+ l = e->l;
+ do {
+ BLI_array_append(oldfaces, l->f);
+ l = l->radial_next;
+ } while (l != e->l);
+
+ /* flag existing faces so we can differentiate oldfaces from new faces */
+ for (i = 0; i < BLI_array_len(oldfaces); i++) {
+ BM_ELEM_API_FLAG_ENABLE(oldfaces[i], _FLAG_OVERLAP);
+ oldfaces[i] = BM_face_copy(bm, bm, oldfaces[i], true, true);
+ BM_ELEM_API_FLAG_DISABLE(oldfaces[i], _FLAG_OVERLAP);
+ }
+ }
+
+ v_other = BM_edge_other_vert(e, v);
+ v_new = bmesh_kernel_split_edge_make_vert(bm, v, e, &e_new);
+ if (r_e != NULL) {
+ *r_e = e_new;
+ }
+
+ BLI_assert(v_new != NULL);
+ BLI_assert(BM_vert_in_edge(e_new, v) && BM_vert_in_edge(e_new, v_new));
+ BLI_assert(BM_vert_in_edge(e, v_new) && BM_vert_in_edge(e, v_other));
+
+ sub_v3_v3v3(v_new->co, v_other->co, v->co);
+ madd_v3_v3v3fl(v_new->co, v->co, v_new->co, fac);
+
+ e_new->head.hflag = e->head.hflag;
+ BM_elem_attrs_copy(bm, bm, e, e_new);
+
+ /* v->v_new->v2 */
+ BM_data_interp_face_vert_edge(bm, v_other, v, v_new, e, fac);
+ BM_data_interp_from_verts(bm, v, v_other, v_new, fac);
+
+ if (cd_loop_mdisp_offset != -1) {
+ int i, j;
+
+ /* interpolate new/changed loop data from copied old faces */
+ for (i = 0; i < BLI_array_len(oldfaces); i++) {
+ float f_center_old[3];
+
+ BM_face_calc_center_median(oldfaces[i], f_center_old);
+
+ for (j = 0; j < 2; j++) {
+ BMEdge *e1 = j ? e_new : e;
+ BMLoop *l;
+
+ l = e1->l;
+
+ if (UNLIKELY(!l)) {
+ BMESH_ASSERT(0);
+ break;
+ }
+
+ do {
+ /* check this is an old face */
+ if (BM_ELEM_API_FLAG_TEST(l->f, _FLAG_OVERLAP)) {
+ float f_center[3];
+
+ BM_face_calc_center_median(l->f, f_center);
+ BM_face_interp_multires_ex(
+ bm, l->f, oldfaces[i], f_center, f_center_old, cd_loop_mdisp_offset);
+ }
+ l = l->radial_next;
+ } while (l != e1->l);
+ }
+ }
+
+ /* destroy the old faces */
+ for (i = 0; i < BLI_array_len(oldfaces); i++) {
+ BM_face_verts_kill(bm, oldfaces[i]);
+ }
+
+ /* fix boundaries a bit, doesn't work too well quite yet */
#if 0
- for (j = 0; j < 2; j++) {
- BMEdge *e1 = j ? e_new : e;
- BMLoop *l, *l2;
-
- l = e1->l;
- if (UNLIKELY(!l)) {
- BMESH_ASSERT(0);
- break;
- }
-
- do {
- BM_face_multires_bounds_smooth(bm, l->f);
- l = l->radial_next;
- } while (l != e1->l);
- }
+ for (j = 0; j < 2; j++) {
+ BMEdge *e1 = j ? e_new : e;
+ BMLoop *l, *l2;
+
+ l = e1->l;
+ if (UNLIKELY(!l)) {
+ BMESH_ASSERT(0);
+ break;
+ }
+
+ do {
+ BM_face_multires_bounds_smooth(bm, l->f);
+ l = l->radial_next;
+ } while (l != e1->l);
+ }
#endif
- BLI_array_free(oldfaces);
- }
+ BLI_array_free(oldfaces);
+ }
- return v_new;
+ return v_new;
}
/**
@@ -699,21 +701,21 @@ BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float fac)
*
* \param r_varr: Optional array, verts in between (v1 -> v2)
*/
-BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts, BMVert **r_varr)
+BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts, BMVert **r_varr)
{
- int i;
- float percent;
- BMVert *v_new = NULL;
-
- for (i = 0; i < numcuts; i++) {
- percent = 1.0f / (float)(numcuts + 1 - i);
- v_new = BM_edge_split(bm, e, e->v2, NULL, percent);
- if (r_varr) {
- /* fill in reverse order (v1 -> v2) */
- r_varr[numcuts - i - 1] = v_new;
- }
- }
- return v_new;
+ int i;
+ float percent;
+ BMVert *v_new = NULL;
+
+ for (i = 0; i < numcuts; i++) {
+ percent = 1.0f / (float)(numcuts + 1 - i);
+ v_new = BM_edge_split(bm, e, e->v2, NULL, percent);
+ if (r_varr) {
+ /* fill in reverse order (v1 -> v2) */
+ r_varr[numcuts - i - 1] = v_new;
+ }
+ }
+ return v_new;
}
/**
@@ -723,8 +725,8 @@ BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts, BMVert **r_varr)
*/
void BM_edge_verts_swap(BMEdge *e)
{
- SWAP(BMVert *, e->v1, e->v2);
- SWAP(BMDiskLink, e->v1_disk_link, e->v2_disk_link);
+ SWAP(BMVert *, e->v1, e->v2);
+ SWAP(BMDiskLink, e->v1_disk_link, e->v2_disk_link);
}
#if 0
@@ -733,46 +735,46 @@ void BM_edge_verts_swap(BMEdge *e)
*/
bool BM_face_validate(BMFace *face, FILE *err)
{
- BMIter iter;
- BLI_array_declare(verts);
- BMVert **verts = NULL;
- BMLoop *l;
- int i, j;
- bool ret = true;
-
- if (face->len == 2) {
- fprintf(err, "warning: found two-edged face. face ptr: %p\n", face);
- fflush(err);
- }
-
- BLI_array_grow_items(verts, face->len);
- BM_ITER_ELEM_INDEX (l, &iter, face, BM_LOOPS_OF_FACE, i) {
- verts[i] = l->v;
- if (l->e->v1 == l->e->v2) {
- fprintf(err, "Found bmesh edge with identical verts!\n");
- fprintf(err, " edge ptr: %p, vert: %p\n", l->e, l->e->v1);
- fflush(err);
- ret = false;
- }
- }
-
- for (i = 0; i < face->len; i++) {
- for (j = 0; j < face->len; j++) {
- if (j == i) {
- continue;
- }
-
- if (verts[i] == verts[j]) {
- fprintf(err, "Found duplicate verts in bmesh face!\n");
- fprintf(err, " face ptr: %p, vert: %p\n", face, verts[i]);
- fflush(err);
- ret = false;
- }
- }
- }
-
- BLI_array_free(verts);
- return ret;
+ BMIter iter;
+ BLI_array_declare(verts);
+ BMVert **verts = NULL;
+ BMLoop *l;
+ int i, j;
+ bool ret = true;
+
+ if (face->len == 2) {
+ fprintf(err, "warning: found two-edged face. face ptr: %p\n", face);
+ fflush(err);
+ }
+
+ BLI_array_grow_items(verts, face->len);
+ BM_ITER_ELEM_INDEX (l, &iter, face, BM_LOOPS_OF_FACE, i) {
+ verts[i] = l->v;
+ if (l->e->v1 == l->e->v2) {
+ fprintf(err, "Found bmesh edge with identical verts!\n");
+ fprintf(err, " edge ptr: %p, vert: %p\n", l->e, l->e->v1);
+ fflush(err);
+ ret = false;
+ }
+ }
+
+ for (i = 0; i < face->len; i++) {
+ for (j = 0; j < face->len; j++) {
+ if (j == i) {
+ continue;
+ }
+
+ if (verts[i] == verts[j]) {
+ fprintf(err, "Found duplicate verts in bmesh face!\n");
+ fprintf(err, " face ptr: %p, vert: %p\n", face, verts[i]);
+ fflush(err);
+ ret = false;
+ }
+ }
+ }
+
+ BLI_array_free(verts);
+ return ret;
}
#endif
@@ -790,32 +792,30 @@ bool BM_face_validate(BMFace *face, FILE *err)
*
* \note #BM_edge_rotate_check must have already run.
*/
-void BM_edge_calc_rotate(
- BMEdge *e, const bool ccw,
- BMLoop **r_l1, BMLoop **r_l2)
+void BM_edge_calc_rotate(BMEdge *e, const bool ccw, BMLoop **r_l1, BMLoop **r_l2)
{
- BMVert *v1, *v2;
- BMFace *fa, *fb;
+ BMVert *v1, *v2;
+ BMFace *fa, *fb;
- /* this should have already run */
- BLI_assert(BM_edge_rotate_check(e) == true);
+ /* this should have already run */
+ BLI_assert(BM_edge_rotate_check(e) == true);
- /* we know this will work */
- BM_edge_face_pair(e, &fa, &fb);
+ /* we know this will work */
+ BM_edge_face_pair(e, &fa, &fb);
- /* so we can use ccw variable correctly,
- * otherwise we could use the edges verts direct */
- BM_edge_ordered_verts(e, &v1, &v2);
+ /* so we can use ccw variable correctly,
+ * otherwise we could use the edges verts direct */
+ BM_edge_ordered_verts(e, &v1, &v2);
- /* we could swap the verts _or_ the faces, swapping faces
- * gives more predictable results since that way the next vert
- * just stitches from face fa / fb */
- if (!ccw) {
- SWAP(BMFace *, fa, fb);
- }
+ /* we could swap the verts _or_ the faces, swapping faces
+ * gives more predictable results since that way the next vert
+ * just stitches from face fa / fb */
+ if (!ccw) {
+ SWAP(BMFace *, fa, fb);
+ }
- *r_l1 = BM_face_other_vert_loop(fb, v2, v1);
- *r_l2 = BM_face_other_vert_loop(fa, v1, v2);
+ *r_l1 = BM_face_other_vert_loop(fb, v2, v1);
+ *r_l2 = BM_face_other_vert_loop(fa, v1, v2);
}
/**
@@ -826,33 +826,33 @@ void BM_edge_calc_rotate(
*/
bool BM_edge_rotate_check(BMEdge *e)
{
- BMFace *fa, *fb;
- if (BM_edge_face_pair(e, &fa, &fb)) {
- BMLoop *la, *lb;
-
- la = BM_face_other_vert_loop(fa, e->v2, e->v1);
- lb = BM_face_other_vert_loop(fb, e->v2, e->v1);
-
- /* check that the next vert in both faces isn't the same
- * (ie - the next edge doesn't share the same faces).
- * since we can't rotate usefully in this case. */
- if (la->v == lb->v) {
- return false;
- }
-
- /* mirror of the check above but in the opposite direction */
- la = BM_face_other_vert_loop(fa, e->v1, e->v2);
- lb = BM_face_other_vert_loop(fb, e->v1, e->v2);
-
- if (la->v == lb->v) {
- return false;
- }
-
- return true;
- }
- else {
- return false;
- }
+ BMFace *fa, *fb;
+ if (BM_edge_face_pair(e, &fa, &fb)) {
+ BMLoop *la, *lb;
+
+ la = BM_face_other_vert_loop(fa, e->v2, e->v1);
+ lb = BM_face_other_vert_loop(fb, e->v2, e->v1);
+
+ /* check that the next vert in both faces isn't the same
+ * (ie - the next edge doesn't share the same faces).
+ * since we can't rotate usefully in this case. */
+ if (la->v == lb->v) {
+ return false;
+ }
+
+ /* mirror of the check above but in the opposite direction */
+ la = BM_face_other_vert_loop(fa, e->v1, e->v2);
+ lb = BM_face_other_vert_loop(fb, e->v1, e->v2);
+
+ if (la->v == lb->v) {
+ return false;
+ }
+
+ return true;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -868,101 +868,97 @@ bool BM_edge_rotate_check(BMEdge *e)
*/
bool BM_edge_rotate_check_degenerate(BMEdge *e, BMLoop *l1, BMLoop *l2)
{
- /* note: for these vars 'old' just means initial edge state. */
+ /* note: for these vars 'old' just means initial edge state. */
- float ed_dir_old[3]; /* edge vector */
- float ed_dir_new[3]; /* edge vector */
- float ed_dir_new_flip[3]; /* edge vector */
+ float ed_dir_old[3]; /* edge vector */
+ float ed_dir_new[3]; /* edge vector */
+ float ed_dir_new_flip[3]; /* edge vector */
- float ed_dir_v1_old[3];
- float ed_dir_v2_old[3];
+ float ed_dir_v1_old[3];
+ float ed_dir_v2_old[3];
- float ed_dir_v1_new[3];
- float ed_dir_v2_new[3];
+ float ed_dir_v1_new[3];
+ float ed_dir_v2_new[3];
- float cross_old[3];
- float cross_new[3];
+ float cross_old[3];
+ float cross_new[3];
- /* original verts - these will be in the edge 'e' */
- BMVert *v1_old, *v2_old;
+ /* original verts - these will be in the edge 'e' */
+ BMVert *v1_old, *v2_old;
- /* verts from the loops passed */
+ /* verts from the loops passed */
- BMVert *v1, *v2;
- /* these are the opposite verts - the verts that _would_ be used if 'ccw' was inverted*/
- BMVert *v1_alt, *v2_alt;
+ BMVert *v1, *v2;
+ /* these are the opposite verts - the verts that _would_ be used if 'ccw' was inverted*/
+ BMVert *v1_alt, *v2_alt;
- /* this should have already run */
- BLI_assert(BM_edge_rotate_check(e) == true);
+ /* this should have already run */
+ BLI_assert(BM_edge_rotate_check(e) == true);
- BM_edge_ordered_verts(e, &v1_old, &v2_old);
+ BM_edge_ordered_verts(e, &v1_old, &v2_old);
- v1 = l1->v;
- v2 = l2->v;
+ v1 = l1->v;
+ v2 = l2->v;
- /* get the next vert along */
- v1_alt = BM_face_other_vert_loop(l1->f, v1_old, v1)->v;
- v2_alt = BM_face_other_vert_loop(l2->f, v2_old, v2)->v;
+ /* get the next vert along */
+ v1_alt = BM_face_other_vert_loop(l1->f, v1_old, v1)->v;
+ v2_alt = BM_face_other_vert_loop(l2->f, v2_old, v2)->v;
- /* normalize all so comparisons are scale independent */
+ /* normalize all so comparisons are scale independent */
- BLI_assert(BM_edge_exists(v1_old, v1));
- BLI_assert(BM_edge_exists(v1, v1_alt));
+ BLI_assert(BM_edge_exists(v1_old, v1));
+ BLI_assert(BM_edge_exists(v1, v1_alt));
- BLI_assert(BM_edge_exists(v2_old, v2));
- BLI_assert(BM_edge_exists(v2, v2_alt));
+ BLI_assert(BM_edge_exists(v2_old, v2));
+ BLI_assert(BM_edge_exists(v2, v2_alt));
- /* old and new edge vecs */
- sub_v3_v3v3(ed_dir_old, v1_old->co, v2_old->co);
- sub_v3_v3v3(ed_dir_new, v1->co, v2->co);
- normalize_v3(ed_dir_old);
- normalize_v3(ed_dir_new);
+ /* old and new edge vecs */
+ sub_v3_v3v3(ed_dir_old, v1_old->co, v2_old->co);
+ sub_v3_v3v3(ed_dir_new, v1->co, v2->co);
+ normalize_v3(ed_dir_old);
+ normalize_v3(ed_dir_new);
- /* old edge corner vecs */
- sub_v3_v3v3(ed_dir_v1_old, v1_old->co, v1->co);
- sub_v3_v3v3(ed_dir_v2_old, v2_old->co, v2->co);
- normalize_v3(ed_dir_v1_old);
- normalize_v3(ed_dir_v2_old);
+ /* old edge corner vecs */
+ sub_v3_v3v3(ed_dir_v1_old, v1_old->co, v1->co);
+ sub_v3_v3v3(ed_dir_v2_old, v2_old->co, v2->co);
+ normalize_v3(ed_dir_v1_old);
+ normalize_v3(ed_dir_v2_old);
- /* old edge corner vecs */
- sub_v3_v3v3(ed_dir_v1_new, v1->co, v1_alt->co);
- sub_v3_v3v3(ed_dir_v2_new, v2->co, v2_alt->co);
- normalize_v3(ed_dir_v1_new);
- normalize_v3(ed_dir_v2_new);
+ /* old edge corner vecs */
+ sub_v3_v3v3(ed_dir_v1_new, v1->co, v1_alt->co);
+ sub_v3_v3v3(ed_dir_v2_new, v2->co, v2_alt->co);
+ normalize_v3(ed_dir_v1_new);
+ normalize_v3(ed_dir_v2_new);
- /* compare */
- cross_v3_v3v3(cross_old, ed_dir_old, ed_dir_v1_old);
- cross_v3_v3v3(cross_new, ed_dir_new, ed_dir_v1_new);
- if (dot_v3v3(cross_old, cross_new) < 0.0f) { /* does this flip? */
- return false;
- }
- cross_v3_v3v3(cross_old, ed_dir_old, ed_dir_v2_old);
- cross_v3_v3v3(cross_new, ed_dir_new, ed_dir_v2_new);
- if (dot_v3v3(cross_old, cross_new) < 0.0f) { /* does this flip? */
- return false;
- }
+ /* compare */
+ cross_v3_v3v3(cross_old, ed_dir_old, ed_dir_v1_old);
+ cross_v3_v3v3(cross_new, ed_dir_new, ed_dir_v1_new);
+ if (dot_v3v3(cross_old, cross_new) < 0.0f) { /* does this flip? */
+ return false;
+ }
+ cross_v3_v3v3(cross_old, ed_dir_old, ed_dir_v2_old);
+ cross_v3_v3v3(cross_new, ed_dir_new, ed_dir_v2_new);
+ if (dot_v3v3(cross_old, cross_new) < 0.0f) { /* does this flip? */
+ return false;
+ }
- negate_v3_v3(ed_dir_new_flip, ed_dir_new);
+ negate_v3_v3(ed_dir_new_flip, ed_dir_new);
- /* result is zero area corner */
- if ((dot_v3v3(ed_dir_new, ed_dir_v1_new) > 0.999f) ||
- (dot_v3v3(ed_dir_new_flip, ed_dir_v2_new) > 0.999f))
- {
- return false;
- }
+ /* result is zero area corner */
+ if ((dot_v3v3(ed_dir_new, ed_dir_v1_new) > 0.999f) ||
+ (dot_v3v3(ed_dir_new_flip, ed_dir_v2_new) > 0.999f)) {
+ return false;
+ }
- return true;
+ return true;
}
-bool BM_edge_rotate_check_beauty(
- BMEdge *e,
- BMLoop *l1, BMLoop *l2)
+bool BM_edge_rotate_check_beauty(BMEdge *e, BMLoop *l1, BMLoop *l2)
{
- /* Stupid check for now:
- * Could compare angles of surrounding edges
- * before & after, but this is OK.*/
- return (len_squared_v3v3(e->v1->co, e->v2->co) >
- len_squared_v3v3(l1->v->co, l2->v->co));
+ /* Stupid check for now:
+ * Could compare angles of surrounding edges
+ * before & after, but this is OK.*/
+ return (len_squared_v3v3(e->v1->co, e->v2->co) > len_squared_v3v3(l1->v->co, l2->v->co));
}
/**
@@ -981,115 +977,113 @@ bool BM_edge_rotate_check_beauty(
*/
BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_flag)
{
- BMVert *v1, *v2;
- BMLoop *l1, *l2;
- BMFace *f;
- BMEdge *e_new = NULL;
- char f_active_prev = 0;
- char f_hflag_prev_1;
- char f_hflag_prev_2;
-
- if (!BM_edge_rotate_check(e)) {
- return NULL;
- }
-
- BM_edge_calc_rotate(e, ccw, &l1, &l2);
-
- /* the loops will be freed so assign verts */
- v1 = l1->v;
- v2 = l2->v;
-
- /* --------------------------------------- */
- /* Checking Code - make sure we can rotate */
-
- if (check_flag & BM_EDGEROT_CHECK_BEAUTY) {
- if (!BM_edge_rotate_check_beauty(e, l1, l2)) {
- return NULL;
- }
- }
-
- /* check before applying */
- if (check_flag & BM_EDGEROT_CHECK_EXISTS) {
- if (BM_edge_exists(v1, v2)) {
- return NULL;
- }
- }
-
- /* slowest, check last */
- if (check_flag & BM_EDGEROT_CHECK_DEGENERATE) {
- if (!BM_edge_rotate_check_degenerate(e, l1, l2)) {
- return NULL;
- }
- }
- /* Done Checking */
- /* ------------- */
-
-
-
- /* --------------- */
- /* Rotate The Edge */
-
- /* first create the new edge, this is so we can copy the customdata from the old one
- * if splice if disabled, always add in a new edge even if theres one there. */
- e_new = BM_edge_create(bm, v1, v2, e, (check_flag & BM_EDGEROT_CHECK_SPLICE) ? BM_CREATE_NO_DOUBLE : BM_CREATE_NOP);
-
- f_hflag_prev_1 = l1->f->head.hflag;
- f_hflag_prev_2 = l2->f->head.hflag;
-
- /* maintain active face */
- if (bm->act_face == l1->f) {
- f_active_prev = 1;
- }
- else if (bm->act_face == l2->f) {
- f_active_prev = 2;
- }
-
- const bool is_flipped = !BM_edge_is_contiguous(e);
-
- /* don't delete the edge, manually remove the edge after so we can copy its attributes */
- f = BM_faces_join_pair(bm, BM_face_edge_share_loop(l1->f, e), BM_face_edge_share_loop(l2->f, e), true);
-
- if (f == NULL) {
- return NULL;
- }
-
- /* note, this assumes joining the faces _didnt_ also remove the verts.
- * the #BM_edge_rotate_check will ensure this, but its possibly corrupt state or future edits
- * break this */
- if ((l1 = BM_face_vert_share_loop(f, v1)) &&
- (l2 = BM_face_vert_share_loop(f, v2)) &&
- BM_face_split(bm, f, l1, l2, NULL, NULL, true))
- {
- /* we should really be able to know the faces some other way,
- * rather then fetching them back from the edge, but this is predictable
- * where using the return values from face split isn't. - campbell */
- BMFace *fa, *fb;
- if (BM_edge_face_pair(e_new, &fa, &fb)) {
- fa->head.hflag = f_hflag_prev_1;
- fb->head.hflag = f_hflag_prev_2;
-
- if (f_active_prev == 1) {
- bm->act_face = fa;
- }
- else if (f_active_prev == 2) {
- bm->act_face = fb;
- }
-
- if (is_flipped) {
- BM_face_normal_flip(bm, fb);
-
- if (ccw) {
- /* needed otherwise ccw toggles direction */
- e_new->l = e_new->l->radial_next;
- }
- }
- }
- }
- else {
- return NULL;
- }
-
- return e_new;
+ BMVert *v1, *v2;
+ BMLoop *l1, *l2;
+ BMFace *f;
+ BMEdge *e_new = NULL;
+ char f_active_prev = 0;
+ char f_hflag_prev_1;
+ char f_hflag_prev_2;
+
+ if (!BM_edge_rotate_check(e)) {
+ return NULL;
+ }
+
+ BM_edge_calc_rotate(e, ccw, &l1, &l2);
+
+ /* the loops will be freed so assign verts */
+ v1 = l1->v;
+ v2 = l2->v;
+
+ /* --------------------------------------- */
+ /* Checking Code - make sure we can rotate */
+
+ if (check_flag & BM_EDGEROT_CHECK_BEAUTY) {
+ if (!BM_edge_rotate_check_beauty(e, l1, l2)) {
+ return NULL;
+ }
+ }
+
+ /* check before applying */
+ if (check_flag & BM_EDGEROT_CHECK_EXISTS) {
+ if (BM_edge_exists(v1, v2)) {
+ return NULL;
+ }
+ }
+
+ /* slowest, check last */
+ if (check_flag & BM_EDGEROT_CHECK_DEGENERATE) {
+ if (!BM_edge_rotate_check_degenerate(e, l1, l2)) {
+ return NULL;
+ }
+ }
+ /* Done Checking */
+ /* ------------- */
+
+ /* --------------- */
+ /* Rotate The Edge */
+
+ /* first create the new edge, this is so we can copy the customdata from the old one
+ * if splice if disabled, always add in a new edge even if theres one there. */
+ e_new = BM_edge_create(
+ bm, v1, v2, e, (check_flag & BM_EDGEROT_CHECK_SPLICE) ? BM_CREATE_NO_DOUBLE : BM_CREATE_NOP);
+
+ f_hflag_prev_1 = l1->f->head.hflag;
+ f_hflag_prev_2 = l2->f->head.hflag;
+
+ /* maintain active face */
+ if (bm->act_face == l1->f) {
+ f_active_prev = 1;
+ }
+ else if (bm->act_face == l2->f) {
+ f_active_prev = 2;
+ }
+
+ const bool is_flipped = !BM_edge_is_contiguous(e);
+
+ /* don't delete the edge, manually remove the edge after so we can copy its attributes */
+ f = BM_faces_join_pair(
+ bm, BM_face_edge_share_loop(l1->f, e), BM_face_edge_share_loop(l2->f, e), true);
+
+ if (f == NULL) {
+ return NULL;
+ }
+
+ /* note, this assumes joining the faces _didnt_ also remove the verts.
+ * the #BM_edge_rotate_check will ensure this, but its possibly corrupt state or future edits
+ * break this */
+ if ((l1 = BM_face_vert_share_loop(f, v1)) && (l2 = BM_face_vert_share_loop(f, v2)) &&
+ BM_face_split(bm, f, l1, l2, NULL, NULL, true)) {
+ /* we should really be able to know the faces some other way,
+ * rather then fetching them back from the edge, but this is predictable
+ * where using the return values from face split isn't. - campbell */
+ BMFace *fa, *fb;
+ if (BM_edge_face_pair(e_new, &fa, &fb)) {
+ fa->head.hflag = f_hflag_prev_1;
+ fb->head.hflag = f_hflag_prev_2;
+
+ if (f_active_prev == 1) {
+ bm->act_face = fa;
+ }
+ else if (f_active_prev == 2) {
+ bm->act_face = fb;
+ }
+
+ if (is_flipped) {
+ BM_face_normal_flip(bm, fb);
+
+ if (ccw) {
+ /* needed otherwise ccw toggles direction */
+ e_new->l = e_new->l->radial_next;
+ }
+ }
+ }
+ }
+ else {
+ return NULL;
+ }
+
+ return e_new;
}
/**
@@ -1097,15 +1091,15 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_f
*/
BMVert *BM_face_loop_separate(BMesh *bm, BMLoop *l_sep)
{
- return bmesh_kernel_unglue_region_make_vert(bm, l_sep);
+ return bmesh_kernel_unglue_region_make_vert(bm, l_sep);
}
BMVert *BM_face_loop_separate_multi_isolated(BMesh *bm, BMLoop *l_sep)
{
- return bmesh_kernel_unglue_region_make_vert_multi_isolated(bm, l_sep);
+ return bmesh_kernel_unglue_region_make_vert_multi_isolated(bm, l_sep);
}
BMVert *BM_face_loop_separate_multi(BMesh *bm, BMLoop **larr, int larr_len)
{
- return bmesh_kernel_unglue_region_make_vert_multi(bm, larr, larr_len);
+ return bmesh_kernel_unglue_region_make_vert_multi(bm, larr, larr_len);
}
diff --git a/source/blender/bmesh/intern/bmesh_mods.h b/source/blender/bmesh/intern/bmesh_mods.h
index 425770a8c32..3d4eefbb598 100644
--- a/source/blender/bmesh/intern/bmesh_mods.h
+++ b/source/blender/bmesh/intern/bmesh_mods.h
@@ -27,31 +27,43 @@ bool BM_disk_dissolve(BMesh *bm, BMVert *v);
BMFace *BM_faces_join_pair(BMesh *bm, BMLoop *l_a, BMLoop *l_b, const bool do_del);
-
/** see: bmesh_polygon_edgenet.h for #BM_face_split_edgenet */
-BMFace *BM_face_split(
- BMesh *bm, BMFace *f,
- BMLoop *l_a, BMLoop *l_b,
- BMLoop **r_l,
- BMEdge *example, const bool no_double);
-
-BMFace *BM_face_split_n(
- BMesh *bm, BMFace *f,
- BMLoop *l_a, BMLoop *l_b,
- float cos[][3], int n,
-BMLoop **r_l, BMEdge *example);
-
-BMEdge *BM_vert_collapse_faces(
- BMesh *bm, BMEdge *e_kill, BMVert *v_kill, float fac,
- const bool do_del, const bool join_faces, const bool kill_degenerate_faces);
-BMEdge *BM_vert_collapse_edge(
- BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
- const bool do_del, const bool kill_degenerate_faces);
-
-BMVert *BM_edge_collapse(
- BMesh *bm, BMEdge *e_kill, BMVert *v_kill,
- const bool do_del, const bool kill_degenerate_faces);
+BMFace *BM_face_split(BMesh *bm,
+ BMFace *f,
+ BMLoop *l_a,
+ BMLoop *l_b,
+ BMLoop **r_l,
+ BMEdge *example,
+ const bool no_double);
+
+BMFace *BM_face_split_n(BMesh *bm,
+ BMFace *f,
+ BMLoop *l_a,
+ BMLoop *l_b,
+ float cos[][3],
+ int n,
+ BMLoop **r_l,
+ BMEdge *example);
+
+BMEdge *BM_vert_collapse_faces(BMesh *bm,
+ BMEdge *e_kill,
+ BMVert *v_kill,
+ float fac,
+ const bool do_del,
+ const bool join_faces,
+ const bool kill_degenerate_faces);
+BMEdge *BM_vert_collapse_edge(BMesh *bm,
+ BMEdge *e_kill,
+ BMVert *v_kill,
+ const bool do_del,
+ const bool kill_degenerate_faces);
+
+BMVert *BM_edge_collapse(BMesh *bm,
+ BMEdge *e_kill,
+ BMVert *v_kill,
+ const bool do_del,
+ const bool kill_degenerate_faces);
BMVert *BM_edge_split(BMesh *bm, BMEdge *e, BMVert *v, BMEdge **r_e, float percent);
@@ -59,29 +71,25 @@ BMVert *BM_edge_split_n(BMesh *bm, BMEdge *e, int numcuts, BMVert **r_varr);
void BM_edge_verts_swap(BMEdge *e);
-bool BM_face_validate(BMFace *face, FILE *err);
-
-void BM_edge_calc_rotate(
- BMEdge *e, const bool ccw,
- BMLoop **r_l1, BMLoop **r_l2);
-bool BM_edge_rotate_check(BMEdge *e);
-bool BM_edge_rotate_check_degenerate(
- BMEdge *e,
- BMLoop *l1, BMLoop *l2);
-bool BM_edge_rotate_check_beauty(
- BMEdge *e,
- BMLoop *l1, BMLoop *l2);
+bool BM_face_validate(BMFace *face, FILE *err);
+
+void BM_edge_calc_rotate(BMEdge *e, const bool ccw, BMLoop **r_l1, BMLoop **r_l2);
+bool BM_edge_rotate_check(BMEdge *e);
+bool BM_edge_rotate_check_degenerate(BMEdge *e, BMLoop *l1, BMLoop *l2);
+bool BM_edge_rotate_check_beauty(BMEdge *e, BMLoop *l1, BMLoop *l2);
BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const bool ccw, const short check_flag);
/* flags for BM_edge_rotate */
enum {
- BM_EDGEROT_CHECK_EXISTS = (1 << 0), /* disallow to rotate when the new edge matches an existing one */
- BM_EDGEROT_CHECK_SPLICE = (1 << 1), /* overrides existing check, if the edge already, rotate and merge them */
- BM_EDGEROT_CHECK_DEGENERATE = (1 << 2), /* disallow creating bow-tie, concave or zero area faces */
- BM_EDGEROT_CHECK_BEAUTY = (1 << 3), /* disallow to rotate into ugly topology */
+ BM_EDGEROT_CHECK_EXISTS =
+ (1 << 0), /* disallow to rotate when the new edge matches an existing one */
+ BM_EDGEROT_CHECK_SPLICE =
+ (1 << 1), /* overrides existing check, if the edge already, rotate and merge them */
+ BM_EDGEROT_CHECK_DEGENERATE = (1
+ << 2), /* disallow creating bow-tie, concave or zero area faces */
+ BM_EDGEROT_CHECK_BEAUTY = (1 << 3), /* disallow to rotate into ugly topology */
};
-
BMVert *BM_face_loop_separate(BMesh *bm, BMLoop *l_sep);
BMVert *BM_face_loop_separate_multi_isolated(BMesh *bm, BMLoop *l_sep);
BMVert *BM_face_loop_separate_multi(BMesh *bm, BMLoop **larr, int larr_len);
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 4ca8e02e94d..2114f9ebd3d 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -96,20 +96,20 @@
/* enums shared between multiple operators */
static BMO_FlagSet bmo_enum_axis_xyz[] = {
- {0, "X"},
- {1, "Y"},
- {2, "Z"},
- {0, NULL},
+ {0, "X"},
+ {1, "Y"},
+ {2, "Z"},
+ {0, NULL},
};
static BMO_FlagSet bmo_enum_falloff_type[] = {
- {SUBD_FALLOFF_SMOOTH, "SMOOTH"},
- {SUBD_FALLOFF_SPHERE, "SPHERE"},
- {SUBD_FALLOFF_ROOT, "ROOT"},
- {SUBD_FALLOFF_SHARP, "SHARP"},
- {SUBD_FALLOFF_LIN, "LINEAR"},
- {SUBD_FALLOFF_INVSQUARE, "INVERSE_SQUARE"},
- {0, NULL},
+ {SUBD_FALLOFF_SMOOTH, "SMOOTH"},
+ {SUBD_FALLOFF_SPHERE, "SPHERE"},
+ {SUBD_FALLOFF_ROOT, "ROOT"},
+ {SUBD_FALLOFF_SHARP, "SHARP"},
+ {SUBD_FALLOFF_LIN, "LINEAR"},
+ {SUBD_FALLOFF_INVSQUARE, "INVERSE_SQUARE"},
+ {0, NULL},
};
/*
@@ -118,22 +118,22 @@ static BMO_FlagSet bmo_enum_falloff_type[] = {
* Smooths vertices by using a basic vertex averaging scheme.
*/
static BMOpDefine bmo_smooth_vert_def = {
- "smooth_vert",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {"factor", BMO_OP_SLOT_FLT}, /* smoothing factor */
- {"mirror_clip_x", BMO_OP_SLOT_BOOL}, /* set vertices close to the x axis before the operation to 0 */
- {"mirror_clip_y", BMO_OP_SLOT_BOOL}, /* set vertices close to the y axis before the operation to 0 */
- {"mirror_clip_z", BMO_OP_SLOT_BOOL}, /* set vertices close to the z axis before the operation to 0 */
- {"clip_dist", BMO_OP_SLOT_FLT}, /* clipping threshold for the above three slots */
- {"use_axis_x", BMO_OP_SLOT_BOOL}, /* smooth vertices along X axis */
- {"use_axis_y", BMO_OP_SLOT_BOOL}, /* smooth vertices along Y axis */
- {"use_axis_z", BMO_OP_SLOT_BOOL}, /* smooth vertices along Z axis */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_smooth_vert_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "smooth_vert",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"factor", BMO_OP_SLOT_FLT}, /* smoothing factor */
+ {"mirror_clip_x", BMO_OP_SLOT_BOOL}, /* set vertices close to the x axis before the operation to 0 */
+ {"mirror_clip_y", BMO_OP_SLOT_BOOL}, /* set vertices close to the y axis before the operation to 0 */
+ {"mirror_clip_z", BMO_OP_SLOT_BOOL}, /* set vertices close to the z axis before the operation to 0 */
+ {"clip_dist", BMO_OP_SLOT_FLT}, /* clipping threshold for the above three slots */
+ {"use_axis_x", BMO_OP_SLOT_BOOL}, /* smooth vertices along X axis */
+ {"use_axis_y", BMO_OP_SLOT_BOOL}, /* smooth vertices along Y axis */
+ {"use_axis_z", BMO_OP_SLOT_BOOL}, /* smooth vertices along Z axis */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_smooth_vert_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -143,20 +143,20 @@ static BMOpDefine bmo_smooth_vert_def = {
* Desbrun, et al. Implicit Fairing of Irregular Meshes using Diffusion and Curvature Flow.
*/
static BMOpDefine bmo_smooth_laplacian_vert_def = {
- "smooth_laplacian_vert",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {"lambda_factor", BMO_OP_SLOT_FLT}, /* lambda param */
- {"lambda_border", BMO_OP_SLOT_FLT}, /* lambda param in border */
- {"use_x", BMO_OP_SLOT_BOOL}, /* Smooth object along X axis */
- {"use_y", BMO_OP_SLOT_BOOL}, /* Smooth object along Y axis */
- {"use_z", BMO_OP_SLOT_BOOL}, /* Smooth object along Z axis */
- {"preserve_volume", BMO_OP_SLOT_BOOL}, /* Apply volume preservation after smooth */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_smooth_laplacian_vert_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "smooth_laplacian_vert",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"lambda_factor", BMO_OP_SLOT_FLT}, /* lambda param */
+ {"lambda_border", BMO_OP_SLOT_FLT}, /* lambda param in border */
+ {"use_x", BMO_OP_SLOT_BOOL}, /* Smooth object along X axis */
+ {"use_y", BMO_OP_SLOT_BOOL}, /* Smooth object along Y axis */
+ {"use_z", BMO_OP_SLOT_BOOL}, /* Smooth object along Z axis */
+ {"preserve_volume", BMO_OP_SLOT_BOOL}, /* Apply volume preservation after smooth */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_smooth_laplacian_vert_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -165,15 +165,15 @@ static BMOpDefine bmo_smooth_laplacian_vert_def = {
* Computes an "outside" normal for the specified input faces.
*/
static BMOpDefine bmo_recalc_face_normals_def = {
- "recalc_face_normals",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_recalc_face_normals_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "recalc_face_normals",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_recalc_face_normals_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -182,20 +182,20 @@ static BMOpDefine bmo_recalc_face_normals_def = {
* Iteratively flatten faces.
*/
static BMOpDefine bmo_planar_faces_def = {
- "planar_faces",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input geometry. */
- {"iterations", BMO_OP_SLOT_INT}, /* Number of times to flatten faces (for when connected faces are used) */
- {"factor", BMO_OP_SLOT_FLT}, /* Influence for making planar each iteration */
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
- {{'\0'}},
- },
- bmo_planar_faces_exec,
- (BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "planar_faces",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input geometry. */
+ {"iterations", BMO_OP_SLOT_INT}, /* Number of times to flatten faces (for when connected faces are used) */
+ {"factor", BMO_OP_SLOT_FLT}, /* Influence for making planar each iteration */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
+ {{'\0'}},
+ },
+ bmo_planar_faces_exec,
+ (BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -209,21 +209,21 @@ static BMOpDefine bmo_planar_faces_def = {
* otherwise it spits out faces.
*/
static BMOpDefine bmo_region_extend_def = {
- "region_extend",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
- {"use_contract", BMO_OP_SLOT_BOOL}, /* find boundary inside the regions, not outside. */
- {"use_faces", BMO_OP_SLOT_BOOL}, /* extend from faces instead of edges */
- {"use_face_step", BMO_OP_SLOT_BOOL}, /* step over connected faces */
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
- {{'\0'}},
- },
- bmo_region_extend_exec,
- (BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "region_extend",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
+ {"use_contract", BMO_OP_SLOT_BOOL}, /* find boundary inside the regions, not outside. */
+ {"use_faces", BMO_OP_SLOT_BOOL}, /* extend from faces instead of edges */
+ {"use_face_step", BMO_OP_SLOT_BOOL}, /* step over connected faces */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output slot, computed boundary geometry. */
+ {{'\0'}},
+ },
+ bmo_region_extend_exec,
+ (BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -233,21 +233,21 @@ static BMOpDefine bmo_region_extend_def = {
* Simple example: ``[/] becomes [|] then [\]``.
*/
static BMOpDefine bmo_rotate_edges_def = {
- "rotate_edges",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate edge counter-clockwise if true, otherwise clockwise */
- {{'\0'}},
- },
- /* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly spun edges */
- {{'\0'}},
- },
- bmo_rotate_edges_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "rotate_edges",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate edge counter-clockwise if true, otherwise clockwise */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly spun edges */
+ {{'\0'}},
+ },
+ bmo_rotate_edges_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -257,16 +257,16 @@ static BMOpDefine bmo_rotate_edges_def = {
* This has the effect of flipping the normal.
*/
static BMOpDefine bmo_reverse_faces_def = {
- "reverse_faces",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"flip_multires", BMO_OP_SLOT_BOOL}, /* maintain multi-res offset */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_reverse_faces_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "reverse_faces",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"flip_multires", BMO_OP_SLOT_BOOL}, /* maintain multi-res offset */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_reverse_faces_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -276,22 +276,22 @@ static BMOpDefine bmo_reverse_faces_def = {
* This creates a 2-valence vert.
*/
static BMOpDefine bmo_bisect_edges_def = {
- "bisect_edges",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */
- {"edge_percents", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
- {{'\0'}},
- },
- /* slots_out */
- {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* newly created vertices and edges */
- {{'\0'}},
- },
- bmo_bisect_edges_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "bisect_edges",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"cuts", BMO_OP_SLOT_INT}, /* number of cuts */
+ {"edge_percents", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* newly created vertices and edges */
+ {{'\0'}},
+ },
+ bmo_bisect_edges_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -302,24 +302,24 @@ static BMOpDefine bmo_bisect_edges_def = {
* parameter (which defines the minimum distance for welding to happen).
*/
static BMOpDefine bmo_mirror_def = {
- "mirror",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
- {"matrix", BMO_OP_SLOT_MAT}, /* matrix defining the mirror transformation */
- {"merge_dist", BMO_OP_SLOT_FLT}, /* maximum distance for merging. does no merging if 0. */
- {"axis", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_axis_xyz}, /* the axis to use. */
- {"mirror_u", BMO_OP_SLOT_BOOL}, /* mirror UVs across the u axis */
- {"mirror_v", BMO_OP_SLOT_BOOL}, /* mirror UVs across the v axis */
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry, mirrored */
- {{'\0'}},
- },
- bmo_mirror_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "mirror",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix defining the mirror transformation */
+ {"merge_dist", BMO_OP_SLOT_FLT}, /* maximum distance for merging. does no merging if 0. */
+ {"axis", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_axis_xyz}, /* the axis to use. */
+ {"mirror_u", BMO_OP_SLOT_BOOL}, /* mirror UVs across the u axis */
+ {"mirror_v", BMO_OP_SLOT_BOOL}, /* mirror UVs across the v axis */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry, mirrored */
+ {{'\0'}},
+ },
+ bmo_mirror_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -332,19 +332,19 @@ static BMOpDefine bmo_mirror_def = {
* with vertices in that set.
*/
static BMOpDefine bmo_find_doubles_def = {
- "find_doubles",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {"keep_verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* list of verts to keep */
- {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
- {{'\0'}},
- },
- /* slots_out */
- {{"targetmap.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {{'\0'}},
- },
- bmo_find_doubles_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "find_doubles",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"keep_verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* list of verts to keep */
+ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"targetmap.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
+ },
+ bmo_find_doubles_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -354,18 +354,18 @@ static BMOpDefine bmo_find_doubles_def = {
* using the weld verts bmop.
*/
static BMOpDefine bmo_remove_doubles_def = {
- "remove_doubles",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
- {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_remove_doubles_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "remove_doubles",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
+ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_remove_doubles_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -376,18 +376,18 @@ static BMOpDefine bmo_remove_doubles_def = {
* **verts** to one in **verts**.
*/
static BMOpDefine bmo_automerge_def = {
- "automerge",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
- {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_automerge_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "automerge",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input verts */
+ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_automerge_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -396,18 +396,18 @@ static BMOpDefine bmo_automerge_def = {
* Collapses connected vertices
*/
static BMOpDefine bmo_collapse_def = {
- "collapse",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- {"uvs", BMO_OP_SLOT_BOOL}, /* also collapse UVs and such */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_collapse_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "collapse",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"uvs", BMO_OP_SLOT_BOOL}, /* also collapse UVs and such */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_collapse_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -416,15 +416,15 @@ static BMOpDefine bmo_collapse_def = {
* Merge uv/vcols at a specific vertex.
*/
static BMOpDefine bmo_pointmerge_facedata_def = {
- "pointmerge_facedata",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {"vert_snap", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | (int)BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* snap vertex */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_pointmerge_facedata_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "pointmerge_facedata",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"vert_snap", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | (int)BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE}}, /* snap vertex */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_pointmerge_facedata_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -435,14 +435,14 @@ static BMOpDefine bmo_pointmerge_facedata_def = {
* the vert_snap_to_bb_center is just too long).
*/
static BMOpDefine bmo_average_vert_facedata_def = {
- "average_vert_facedata",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_average_vert_facedata_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "average_vert_facedata",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_average_vert_facedata_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -451,18 +451,18 @@ static BMOpDefine bmo_average_vert_facedata_def = {
* Merge verts together at a point.
*/
static BMOpDefine bmo_pointmerge_def = {
- "pointmerge",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices (all verts will be merged into the first). */
- {"merge_co", BMO_OP_SLOT_VEC}, /* Position to merge at. */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_pointmerge_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "pointmerge",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices (all verts will be merged into the first). */
+ {"merge_co", BMO_OP_SLOT_VEC}, /* Position to merge at. */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_pointmerge_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -471,14 +471,14 @@ static BMOpDefine bmo_pointmerge_def = {
* Collapses connected UV vertices.
*/
static BMOpDefine bmo_collapse_uvs_def = {
- "collapse_uvs",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_collapse_uvs_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "collapse_uvs",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_collapse_uvs_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -489,18 +489,18 @@ static BMOpDefine bmo_collapse_uvs_def = {
* they weld with.
*/
static BMOpDefine bmo_weld_verts_def = {
- "weld_verts",
- /* slots_in */
- /* maps welded vertices to verts they should weld to */
- {{"targetmap", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_weld_verts_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "weld_verts",
+ /* slots_in */
+ /* maps welded vertices to verts they should weld to */
+ {{"targetmap", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_weld_verts_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -510,17 +510,17 @@ static BMOpDefine bmo_weld_verts_def = {
* for click-create-vertex.
*/
static BMOpDefine bmo_create_vert_def = {
- "create_vert",
- /* slots_in */
- {{"co", BMO_OP_SLOT_VEC}, /* the coordinate of the new vert */
- {{'\0'}},
- },
- /* slots_out */
- {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* the new vert */
- {{'\0'}},
- },
- bmo_create_vert_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "create_vert",
+ /* slots_in */
+ {{"co", BMO_OP_SLOT_VEC}, /* the coordinate of the new vert */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"vert.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* the new vert */
+ {{'\0'}},
+ },
+ bmo_create_vert_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -530,27 +530,27 @@ static BMOpDefine bmo_create_vert_def = {
* to angle threshold and delimiters.
*/
static BMOpDefine bmo_join_triangles_def = {
- "join_triangles",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input geometry. */
- {"cmp_seam", BMO_OP_SLOT_BOOL},
- {"cmp_sharp", BMO_OP_SLOT_BOOL},
- {"cmp_uvs", BMO_OP_SLOT_BOOL},
- {"cmp_vcols", BMO_OP_SLOT_BOOL},
- {"cmp_materials", BMO_OP_SLOT_BOOL},
- {"angle_face_threshold", BMO_OP_SLOT_FLT},
- {"angle_shape_threshold", BMO_OP_SLOT_FLT},
- {{'\0'}},
- },
- /* slots_out */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* joined faces */
- {{'\0'}},
- },
- bmo_join_triangles_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "join_triangles",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input geometry. */
+ {"cmp_seam", BMO_OP_SLOT_BOOL},
+ {"cmp_sharp", BMO_OP_SLOT_BOOL},
+ {"cmp_uvs", BMO_OP_SLOT_BOOL},
+ {"cmp_vcols", BMO_OP_SLOT_BOOL},
+ {"cmp_materials", BMO_OP_SLOT_BOOL},
+ {"angle_face_threshold", BMO_OP_SLOT_FLT},
+ {"angle_shape_threshold", BMO_OP_SLOT_FLT},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* joined faces */
+ {{'\0'}},
+ },
+ bmo_join_triangles_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -564,49 +564,49 @@ static BMOpDefine bmo_join_triangles_def = {
* become a wire edge.
*/
static BMOpDefine bmo_contextual_create_def = {
- "contextual_create",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry. */
- {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */
- {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth to use */
- {{'\0'}},
- },
- /* slots_out */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* newly-made face(s) */
- /* note, this is for stand-alone edges only, not edges which are apart of newly created faces */
- {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly-made edge(s) */
- {{'\0'}},
- },
- bmo_contextual_create_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "contextual_create",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input geometry. */
+ {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */
+ {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth to use */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* newly-made face(s) */
+ /* note, this is for stand-alone edges only, not edges which are apart of newly created faces */
+ {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* newly-made edge(s) */
+ {{'\0'}},
+ },
+ bmo_contextual_create_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
* Bridge edge loops with faces.
*/
static BMOpDefine bmo_bridge_loops_def = {
- "bridge_loops",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- {"use_pairs", BMO_OP_SLOT_BOOL},
- {"use_cyclic", BMO_OP_SLOT_BOOL},
- {"use_merge", BMO_OP_SLOT_BOOL},
- {"merge_factor", BMO_OP_SLOT_FLT},
- {"twist_offset", BMO_OP_SLOT_INT},
- {{'\0'}},
- },
- /* slots_out */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
- {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */
- {{'\0'}},
- },
- bmo_bridge_loops_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "bridge_loops",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"use_pairs", BMO_OP_SLOT_BOOL},
+ {"use_cyclic", BMO_OP_SLOT_BOOL},
+ {"use_merge", BMO_OP_SLOT_BOOL},
+ {"merge_factor", BMO_OP_SLOT_FLT},
+ {"twist_offset", BMO_OP_SLOT_INT},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
+ {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */
+ {{'\0'}},
+ },
+ bmo_bridge_loops_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -615,23 +615,23 @@ static BMOpDefine bmo_bridge_loops_def = {
* Create faces defined by 2 disconnected edge loops (which share edges).
*/
static BMOpDefine bmo_grid_fill_def = {
- "grid_fill",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- /* restricts edges to groups. maps edges to integer */
- {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */
- {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth state to use */
- {"use_interp_simple", BMO_OP_SLOT_BOOL}, /* use simple interpolation */
- {{'\0'}},
- },
- /* slots_out */
- /* maps new faces to the group numbers they came from */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
- {{'\0'}},
- },
- bmo_grid_fill_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "grid_fill",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ /* restricts edges to groups. maps edges to integer */
+ {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */
+ {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth state to use */
+ {"use_interp_simple", BMO_OP_SLOT_BOOL}, /* use simple interpolation */
+ {{'\0'}},
+ },
+ /* slots_out */
+ /* maps new faces to the group numbers they came from */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
+ {{'\0'}},
+ },
+ bmo_grid_fill_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
@@ -641,20 +641,20 @@ static BMOpDefine bmo_grid_fill_def = {
* Fill boundary edges with faces, copying surrounding customdata.
*/
static BMOpDefine bmo_holes_fill_def = {
- "holes_fill",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- {"sides", BMO_OP_SLOT_INT}, /* number of face sides to fill */
- {{'\0'}},
- },
- /* slots_out */
- /* maps new faces to the group numbers they came from */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
- {{'\0'}},
- },
- bmo_holes_fill_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "holes_fill",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"sides", BMO_OP_SLOT_INT}, /* number of face sides to fill */
+ {{'\0'}},
+ },
+ /* slots_out */
+ /* maps new faces to the group numbers they came from */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
+ {{'\0'}},
+ },
+ bmo_holes_fill_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
@@ -664,20 +664,20 @@ static BMOpDefine bmo_holes_fill_def = {
* Fill in faces with data from adjacent faces.
*/
static BMOpDefine bmo_face_attribute_fill_def = {
- "face_attribute_fill",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"use_normals", BMO_OP_SLOT_BOOL}, /* copy face winding */
- {"use_data", BMO_OP_SLOT_BOOL}, /* copy face data */
- {{'\0'}},
- },
- /* slots_out */
- /* maps new faces to the group numbers they came from */
- {{"faces_fail.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* faces that could not be handled */
- {{'\0'}},
- },
- bmo_face_attribute_fill_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "face_attribute_fill",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"use_normals", BMO_OP_SLOT_BOOL}, /* copy face winding */
+ {"use_data", BMO_OP_SLOT_BOOL}, /* copy face data */
+ {{'\0'}},
+ },
+ /* slots_out */
+ /* maps new faces to the group numbers they came from */
+ {{"faces_fail.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* faces that could not be handled */
+ {{'\0'}},
+ },
+ bmo_face_attribute_fill_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -686,22 +686,22 @@ static BMOpDefine bmo_face_attribute_fill_def = {
* Create faces defined by one or more non overlapping edge loops.
*/
static BMOpDefine bmo_edgeloop_fill_def = {
- "edgeloop_fill",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- /* restricts edges to groups. maps edges to integer */
- {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */
- {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth state to use */
- {{'\0'}},
- },
- /* slots_out */
- /* maps new faces to the group numbers they came from */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
- {{'\0'}},
- },
- bmo_edgeloop_fill_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "edgeloop_fill",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ /* restricts edges to groups. maps edges to integer */
+ {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */
+ {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth state to use */
+ {{'\0'}},
+ },
+ /* slots_out */
+ /* maps new faces to the group numbers they came from */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
+ {{'\0'}},
+ },
+ bmo_edgeloop_fill_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
@@ -711,22 +711,22 @@ static BMOpDefine bmo_edgeloop_fill_def = {
* Create faces defined by enclosed edges.
*/
static BMOpDefine bmo_edgenet_fill_def = {
- "edgenet_fill",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */
- {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth state to use */
- {"sides", BMO_OP_SLOT_INT}, /* number of sides */
- {{'\0'}},
- },
- /* slots_out */
- /* maps new faces to the group numbers they came from */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
- {{'\0'}},
- },
- bmo_edgenet_fill_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "edgenet_fill",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"mat_nr", BMO_OP_SLOT_INT}, /* material to use */
+ {"use_smooth", BMO_OP_SLOT_BOOL}, /* smooth state to use */
+ {"sides", BMO_OP_SLOT_INT}, /* number of sides */
+ {{'\0'}},
+ },
+ /* slots_out */
+ /* maps new faces to the group numbers they came from */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* new faces */
+ {{'\0'}},
+ },
+ bmo_edgenet_fill_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -740,17 +740,17 @@ static BMOpDefine bmo_edgenet_fill_def = {
* shortest distance between each endpont).
*/
static BMOpDefine bmo_edgenet_prepare_def = {
- "edgenet_prepare",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- {{'\0'}},
- },
- /* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */
- {{'\0'}},
- },
- bmo_edgenet_prepare_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "edgenet_prepare",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* new edges */
+ {{'\0'}},
+ },
+ bmo_edgenet_prepare_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -759,17 +759,17 @@ static BMOpDefine bmo_edgenet_prepare_def = {
* Rotate vertices around a center, using a 3x3 rotation matrix.
*/
static BMOpDefine bmo_rotate_def = {
- "rotate",
- /* slots_in */
- {{"cent", BMO_OP_SLOT_VEC}, /* center of rotation */
- {"matrix", BMO_OP_SLOT_MAT}, /* matrix defining rotation */
- {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_rotate_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "rotate",
+ /* slots_in */
+ {{"cent", BMO_OP_SLOT_VEC}, /* center of rotation */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix defining rotation */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_rotate_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -778,16 +778,16 @@ static BMOpDefine bmo_rotate_def = {
* Translate vertices by an offset.
*/
static BMOpDefine bmo_translate_def = {
- "translate",
- /* slots_in */
- {{"vec", BMO_OP_SLOT_VEC}, /* translation offset */
- {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
- {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_translate_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "translate",
+ /* slots_in */
+ {{"vec", BMO_OP_SLOT_VEC}, /* translation offset */
+ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_translate_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -796,16 +796,16 @@ static BMOpDefine bmo_translate_def = {
* Scales vertices by an offset.
*/
static BMOpDefine bmo_scale_def = {
- "scale",
- /* slots_in */
- {{"vec", BMO_OP_SLOT_VEC}, /* scale factor */
- {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
- {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_scale_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "scale",
+ /* slots_in */
+ {{"vec", BMO_OP_SLOT_VEC}, /* scale factor */
+ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_scale_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
@@ -816,16 +816,16 @@ static BMOpDefine bmo_scale_def = {
* the vertex coordinates with the matrix.
*/
static BMOpDefine bmo_transform_def = {
- "transform",
- /* slots_in */
- {{"matrix", BMO_OP_SLOT_MAT}, /* transform matrix */
- {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
- {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_transform_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "transform",
+ /* slots_in */
+ {{"matrix", BMO_OP_SLOT_MAT}, /* transform matrix */
+ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_transform_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -835,15 +835,15 @@ static BMOpDefine bmo_transform_def = {
* bmop.
*/
static BMOpDefine bmo_object_load_bmesh_def = {
- "object_load_bmesh",
- /* slots_in */
- {{"scene", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_SCENE}},
- {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_object_load_bmesh_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "object_load_bmesh",
+ /* slots_in */
+ {{"scene", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_SCENE}},
+ {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_object_load_bmesh_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
@@ -853,18 +853,18 @@ static BMOpDefine bmo_object_load_bmesh_def = {
* Converts a bmesh to a Mesh. This is reserved for exiting editmode.
*/
static BMOpDefine bmo_bmesh_to_mesh_def = {
- "bmesh_to_mesh",
- /* slots_in */
- {
- /* pointer to a mesh structure to fill in */
- {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
- /* pointer to an object structure */
- {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_bmesh_to_mesh_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "bmesh_to_mesh",
+ /* slots_in */
+ {
+ /* pointer to a mesh structure to fill in */
+ {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
+ /* pointer to an object structure */
+ {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_bmesh_to_mesh_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -874,19 +874,19 @@ static BMOpDefine bmo_bmesh_to_mesh_def = {
* reserved exclusively for entering editmode.
*/
static BMOpDefine bmo_mesh_to_bmesh_def = {
- "mesh_to_bmesh",
- /* slots_in */
- {
- /* pointer to a Mesh structure */
- {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
- /* pointer to an Object structure */
- {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
- {"use_shapekey", BMO_OP_SLOT_BOOL}, /* load active shapekey coordinates into verts */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_mesh_to_bmesh_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "mesh_to_bmesh",
+ /* slots_in */
+ {
+ /* pointer to a Mesh structure */
+ {"mesh", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_MESH}},
+ /* pointer to an Object structure */
+ {"object", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_OBJECT}},
+ {"use_shapekey", BMO_OP_SLOT_BOOL}, /* load active shapekey coordinates into verts */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_mesh_to_bmesh_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -895,19 +895,19 @@ static BMOpDefine bmo_mesh_to_bmesh_def = {
* Extrudes faces individually.
*/
static BMOpDefine bmo_extrude_discrete_faces_def = {
- "extrude_discrete_faces",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
- {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
- {{'\0'}},
- },
- /* slots_out */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
- {{'\0'}},
- },
- bmo_extrude_discrete_faces_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "extrude_discrete_faces",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
+ {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
+ },
+ bmo_extrude_discrete_faces_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -917,19 +917,19 @@ static BMOpDefine bmo_extrude_discrete_faces_def = {
* winged extrusion.
*/
static BMOpDefine bmo_extrude_edge_only_def = {
- "extrude_edge_only",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
- {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
- {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry */
- {{'\0'}},
- },
- bmo_extrude_edge_only_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "extrude_edge_only",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
+ {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
+ {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* output geometry */
+ {{'\0'}},
+ },
+ bmo_extrude_edge_only_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -938,19 +938,19 @@ static BMOpDefine bmo_extrude_edge_only_def = {
* Extrudes wire edges from vertices.
*/
static BMOpDefine bmo_extrude_vert_indiv_def = {
- "extrude_vert_indiv",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
- {{'\0'}},
- },
- /* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output wire edges */
- {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */
- {{'\0'}},
- },
- bmo_extrude_vert_indiv_exec,
- (BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "extrude_vert_indiv",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output wire edges */
+ {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output vertices */
+ {{'\0'}},
+ },
+ bmo_extrude_vert_indiv_exec,
+ (BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -959,21 +959,21 @@ static BMOpDefine bmo_extrude_vert_indiv_def = {
* Split faces by adding edges that connect **verts**.
*/
static BMOpDefine bmo_connect_verts_def = {
- "connect_verts",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {"check_degenerate", BMO_OP_SLOT_BOOL}, /* prevent splits with overlaps & intersections */
- {{'\0'}},
- },
- /* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {{'\0'}},
- },
- bmo_connect_verts_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "connect_verts",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"check_degenerate", BMO_OP_SLOT_BOOL}, /* prevent splits with overlaps & intersections */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{'\0'}},
+ },
+ bmo_connect_verts_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -982,20 +982,20 @@ static BMOpDefine bmo_connect_verts_def = {
* Ensures all faces are convex **faces**.
*/
static BMOpDefine bmo_connect_verts_concave_def = {
- "connect_verts_concave",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {{'\0'}},
- },
- /* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {{'\0'}},
- },
- bmo_connect_verts_concave_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "connect_verts_concave",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ bmo_connect_verts_concave_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1004,21 +1004,21 @@ static BMOpDefine bmo_connect_verts_concave_def = {
* Split faces by connecting edges along non planer **faces**.
*/
static BMOpDefine bmo_connect_verts_nonplanar_def = {
- "connect_verts_nonplanar",
- /* slots_in */
- {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
- {"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {{'\0'}},
- },
- /* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {{'\0'}},
- },
- bmo_connect_verts_nonplanar_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "connect_verts_nonplanar",
+ /* slots_in */
+ {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
+ {"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ bmo_connect_verts_nonplanar_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1027,21 +1027,21 @@ static BMOpDefine bmo_connect_verts_nonplanar_def = {
* Split faces by adding edges that connect **verts**.
*/
static BMOpDefine bmo_connect_vert_pair_def = {
- "connect_vert_pair",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {"verts_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {{'\0'}},
- },
- /* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {{'\0'}},
- },
- bmo_connect_vert_pair_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "connect_vert_pair",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {"verts_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{'\0'}},
+ },
+ bmo_connect_vert_pair_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
@@ -1051,93 +1051,93 @@ static BMOpDefine bmo_connect_vert_pair_def = {
* Extrude operator (does not transform)
*/
static BMOpDefine bmo_extrude_face_region_def = {
- "extrude_face_region",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* edges and faces */
- {"edges_exclude", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}},
- {"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry (requires ``geom`` to include edges). */
- {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
- {"use_normal_from_adjacent", BMO_OP_SLOT_BOOL}, /* Use winding from surrounding faces instead of this region. */
- {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {{'\0'}},
- },
- bmo_extrude_face_region_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "extrude_face_region",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* edges and faces */
+ {"edges_exclude", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}},
+ {"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry (requires ``geom`` to include edges). */
+ {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
+ {"use_normal_from_adjacent", BMO_OP_SLOT_BOOL}, /* Use winding from surrounding faces instead of this region. */
+ {"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
+ },
+ bmo_extrude_face_region_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
* Dissolve Verts.
*/
static BMOpDefine bmo_dissolve_verts_def = {
- "dissolve_verts",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {"use_face_split", BMO_OP_SLOT_BOOL},
- {"use_boundary_tear", BMO_OP_SLOT_BOOL},
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_dissolve_verts_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "dissolve_verts",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {"use_face_split", BMO_OP_SLOT_BOOL},
+ {"use_boundary_tear", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_dissolve_verts_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
* Dissolve Edges.
*/
static BMOpDefine bmo_dissolve_edges_def = {
- "dissolve_edges",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
- {"use_face_split", BMO_OP_SLOT_BOOL},
- {{'\0'}},
- },
- /* slots_out */
- {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {{'\0'}},
- },
- bmo_dissolve_edges_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "dissolve_edges",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
+ {"use_face_split", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ bmo_dissolve_edges_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
* Dissolve Faces.
*/
static BMOpDefine bmo_dissolve_faces_def = {
- "dissolve_faces",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
- {{'\0'}},
- },
- /* slots_out */
- {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {{'\0'}},
- },
- bmo_dissolve_faces_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "dissolve_faces",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}},
+ },
+ bmo_dissolve_faces_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
static BMO_FlagSet bmo_enum_dissolve_limit_flags[] = {
- {BMO_DELIM_NORMAL, "NORMAL"},
- {BMO_DELIM_MATERIAL, "MATERIAL"},
- {BMO_DELIM_SEAM, "SEAM"},
- {BMO_DELIM_SHARP, "SHARP"},
- {BMO_DELIM_UV, "UV"},
- {0, NULL},
+ {BMO_DELIM_NORMAL, "NORMAL"},
+ {BMO_DELIM_MATERIAL, "MATERIAL"},
+ {BMO_DELIM_SEAM, "SEAM"},
+ {BMO_DELIM_SHARP, "SHARP"},
+ {BMO_DELIM_UV, "UV"},
+ {0, NULL},
};
/*
@@ -1146,23 +1146,23 @@ static BMO_FlagSet bmo_enum_dissolve_limit_flags[] = {
* Dissolve planar faces and co-linear edges.
*/
static BMOpDefine bmo_dissolve_limit_def = {
- "dissolve_limit",
- /* slots_in */
- {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
- {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL},
- {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
- {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {"delimit", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_FLAG}, bmo_enum_dissolve_limit_flags},
- {{'\0'}},
- },
- /* slots_out */
- {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {{'\0'}}},
- bmo_dissolve_limit_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "dissolve_limit",
+ /* slots_in */
+ {{"angle_limit", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
+ {"use_dissolve_boundaries", BMO_OP_SLOT_BOOL},
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}},
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"delimit", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_FLAG}, bmo_enum_dissolve_limit_flags},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"region.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {{'\0'}}},
+ bmo_dissolve_limit_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -1171,57 +1171,57 @@ static BMOpDefine bmo_dissolve_limit_def = {
* Dissolve edges with no length, faces with no area.
*/
static BMOpDefine bmo_dissolve_degenerate_def = {
- "dissolve_degenerate",
- /* slots_in */
- {{"dist", BMO_OP_SLOT_FLT}, /* minimum distance to consider degenerate */
- {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {{'\0'}},
- },
- /* slots_out */
- {{{'\0'}}},
- bmo_dissolve_degenerate_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "dissolve_degenerate",
+ /* slots_in */
+ {{"dist", BMO_OP_SLOT_FLT}, /* minimum distance to consider degenerate */
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{{'\0'}}},
+ bmo_dissolve_degenerate_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
static BMO_FlagSet bmo_enum_triangulate_quad_method[] = {
- {MOD_TRIANGULATE_QUAD_BEAUTY, "BEAUTY"},
- {MOD_TRIANGULATE_QUAD_FIXED, "FIXED"},
- {MOD_TRIANGULATE_QUAD_ALTERNATE, "ALTERNATE"},
- {MOD_TRIANGULATE_QUAD_SHORTEDGE, "SHORT_EDGE"},
- {0, NULL},
+ {MOD_TRIANGULATE_QUAD_BEAUTY, "BEAUTY"},
+ {MOD_TRIANGULATE_QUAD_FIXED, "FIXED"},
+ {MOD_TRIANGULATE_QUAD_ALTERNATE, "ALTERNATE"},
+ {MOD_TRIANGULATE_QUAD_SHORTEDGE, "SHORT_EDGE"},
+ {0, NULL},
};
static BMO_FlagSet bmo_enum_triangulate_ngon_method[] = {
- {MOD_TRIANGULATE_NGON_BEAUTY, "BEAUTY"},
- {MOD_TRIANGULATE_NGON_EARCLIP, "EAR_CLIP"},
- {0, NULL},
+ {MOD_TRIANGULATE_NGON_BEAUTY, "BEAUTY"},
+ {MOD_TRIANGULATE_NGON_EARCLIP, "EAR_CLIP"},
+ {0, NULL},
};
/*
* Triangulate.
*/
static BMOpDefine bmo_triangulate_def = {
- "triangulate",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {"quad_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_triangulate_quad_method},
- {"ngon_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_triangulate_ngon_method},
- {{'\0'}},
- },
- /* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {"face_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {"face_map_double.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, /* duplicate faces */
- {{'\0'}},
- },
- bmo_triangulate_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "triangulate",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"quad_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_triangulate_quad_method},
+ {"ngon_method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_triangulate_ngon_method},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"face_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"face_map_double.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}}, /* duplicate faces */
+ {{'\0'}},
+ },
+ bmo_triangulate_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1230,26 +1230,26 @@ static BMOpDefine bmo_triangulate_def = {
* Reduce detail in geometry containing grids.
*/
static BMOpDefine bmo_unsubdivide_def = {
- "unsubdivide",
- /* slots_in */
- {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
- {"iterations", BMO_OP_SLOT_INT},
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_unsubdivide_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "unsubdivide",
+ /* slots_in */
+ {{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"iterations", BMO_OP_SLOT_INT},
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_unsubdivide_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
static BMO_FlagSet bmo_enum_subdivide_edges_quad_corner_type[] = {
- {SUBD_CORNER_STRAIGHT_CUT, "STRAIGHT_CUT"},
- {SUBD_CORNER_INNERVERT, "INNER_VERT"},
- {SUBD_CORNER_PATH, "PATH"},
- {SUBD_CORNER_FAN, "FAN"},
- {0, NULL},
+ {SUBD_CORNER_STRAIGHT_CUT, "STRAIGHT_CUT"},
+ {SUBD_CORNER_INNERVERT, "INNER_VERT"},
+ {SUBD_CORNER_PATH, "PATH"},
+ {SUBD_CORNER_FAN, "FAN"},
+ {0, NULL},
};
/*
@@ -1259,44 +1259,44 @@ static BMO_FlagSet bmo_enum_subdivide_edges_quad_corner_type[] = {
* with options for face patterns, smoothing and randomization.
*/
static BMOpDefine bmo_subdivide_edges_def = {
- "subdivide_edges",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
- {"smooth", BMO_OP_SLOT_FLT},
- {"smooth_falloff", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_falloff_type}, /* smooth falloff type */
- {"fractal", BMO_OP_SLOT_FLT},
- {"along_normal", BMO_OP_SLOT_FLT},
- {"cuts", BMO_OP_SLOT_INT},
- {"seed", BMO_OP_SLOT_INT},
- {"custom_patterns", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}}, /* uses custom pointers */
- {"edge_percents", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
- {"quad_corner_type", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_subdivide_edges_quad_corner_type}, /* quad corner type */
- {"use_grid_fill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */
- {"use_single_edge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */
- {"use_only_quads", BMO_OP_SLOT_BOOL}, /* only subdivide quads (for loopcut) */
- {"use_sphere", BMO_OP_SLOT_BOOL}, /* for making new primitives only */
- {"use_smooth_even", BMO_OP_SLOT_BOOL}, /* maintain even offset when smoothing */
- {{'\0'}},
- },
- /* slots_out */
- {/* these next three can have multiple types of elements in them */
- {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometry */
- {{'\0'}},
- },
- bmo_subdivide_edges_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "subdivide_edges",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
+ {"smooth", BMO_OP_SLOT_FLT},
+ {"smooth_falloff", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_falloff_type}, /* smooth falloff type */
+ {"fractal", BMO_OP_SLOT_FLT},
+ {"along_normal", BMO_OP_SLOT_FLT},
+ {"cuts", BMO_OP_SLOT_INT},
+ {"seed", BMO_OP_SLOT_INT},
+ {"custom_patterns", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL}}, /* uses custom pointers */
+ {"edge_percents", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_FLT}},
+ {"quad_corner_type", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_subdivide_edges_quad_corner_type}, /* quad corner type */
+ {"use_grid_fill", BMO_OP_SLOT_BOOL}, /* fill in fully-selected faces with a grid */
+ {"use_single_edge", BMO_OP_SLOT_BOOL}, /* tessellate the case of one edge selected in a quad or triangle */
+ {"use_only_quads", BMO_OP_SLOT_BOOL}, /* only subdivide quads (for loopcut) */
+ {"use_sphere", BMO_OP_SLOT_BOOL}, /* for making new primitives only */
+ {"use_smooth_even", BMO_OP_SLOT_BOOL}, /* maintain even offset when smoothing */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {/* these next three can have multiple types of elements in them */
+ {"geom_inner.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom_split.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* contains all output geometry */
+ {{'\0'}},
+ },
+ bmo_subdivide_edges_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
static BMO_FlagSet bmo_enum_subdivide_edgering_interp_mode[] = {
- {SUBD_RING_INTERP_LINEAR, "LINEAR"},
- {SUBD_RING_INTERP_PATH, "PATH"},
- {SUBD_RING_INTERP_SURF, "SURFACE"},
- {0, NULL},
+ {SUBD_RING_INTERP_LINEAR, "LINEAR"},
+ {SUBD_RING_INTERP_PATH, "PATH"},
+ {SUBD_RING_INTERP_SURF, "SURFACE"},
+ {0, NULL},
};
/*
@@ -1305,23 +1305,23 @@ static BMO_FlagSet bmo_enum_subdivide_edgering_interp_mode[] = {
* Take an edge-ring, and subdivide with interpolation options.
*/
static BMOpDefine bmo_subdivide_edgering_def = {
- "subdivide_edgering",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
- {"interp_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_subdivide_edgering_interp_mode}, /* interpolation method */
- {"smooth", BMO_OP_SLOT_FLT},
- {"cuts", BMO_OP_SLOT_INT},
- {"profile_shape", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_falloff_type}, /* profile shape type */
- {"profile_shape_factor", BMO_OP_SLOT_FLT},
- {{'\0'}},
- },
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
- {{'\0'}}},
- bmo_subdivide_edgering_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "subdivide_edgering",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input vertices */
+ {"interp_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_subdivide_edgering_interp_mode}, /* interpolation method */
+ {"smooth", BMO_OP_SLOT_FLT},
+ {"cuts", BMO_OP_SLOT_INT},
+ {"profile_shape", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_falloff_type}, /* profile shape type */
+ {"profile_shape_factor", BMO_OP_SLOT_FLT},
+ {{'\0'}},
+ },
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}}},
+ bmo_subdivide_edgering_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -1330,36 +1330,36 @@ static BMOpDefine bmo_subdivide_edgering_def = {
* Bisects the mesh by a plane (cut the mesh in half).
*/
static BMOpDefine bmo_bisect_plane_def = {
- "bisect_plane",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"dist", BMO_OP_SLOT_FLT}, /* minimum distance when testing if a vert is exactly on the plane */
- {"plane_co", BMO_OP_SLOT_VEC}, /* point on the plane */
- {"plane_no", BMO_OP_SLOT_VEC}, /* direction of the plane */
- {"use_snap_center", BMO_OP_SLOT_BOOL}, /* snap axis aligned verts to the center */
- {"clear_outer", BMO_OP_SLOT_BOOL}, /* when enabled. remove all geometry on the positive side of the plane */
- {"clear_inner", BMO_OP_SLOT_BOOL}, /* when enabled. remove all geometry on the negative side of the plane */
- {{'\0'}},
- },
- {{"geom_cut.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE}}, /* output geometry aligned with the plane (new and existing) */
- {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input and output geometry (result of cut) */
- {{'\0'}}},
- bmo_bisect_plane_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "bisect_plane",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance when testing if a vert is exactly on the plane */
+ {"plane_co", BMO_OP_SLOT_VEC}, /* point on the plane */
+ {"plane_no", BMO_OP_SLOT_VEC}, /* direction of the plane */
+ {"use_snap_center", BMO_OP_SLOT_BOOL}, /* snap axis aligned verts to the center */
+ {"clear_outer", BMO_OP_SLOT_BOOL}, /* when enabled. remove all geometry on the positive side of the plane */
+ {"clear_inner", BMO_OP_SLOT_BOOL}, /* when enabled. remove all geometry on the negative side of the plane */
+ {{'\0'}},
+ },
+ {{"geom_cut.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE}}, /* output geometry aligned with the plane (new and existing) */
+ {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input and output geometry (result of cut) */
+ {{'\0'}}},
+ bmo_bisect_plane_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
static BMO_FlagSet bmo_enum_delete_context[] = {
- {DEL_VERTS, "VERTS"},
- {DEL_EDGES, "EDGES"},
- {DEL_ONLYFACES, "FACES_ONLY"},
- {DEL_EDGESFACES, "EDGES_FACES"},
- {DEL_FACES, "FACES"},
- {DEL_FACES_KEEP_BOUNDARY, "FACES_KEEP_BOUNDARY"},
- {DEL_ONLYTAGGED, "TAGGED_ONLY"},
- {0, NULL},
+ {DEL_VERTS, "VERTS"},
+ {DEL_EDGES, "EDGES"},
+ {DEL_ONLYFACES, "FACES_ONLY"},
+ {DEL_EDGESFACES, "EDGES_FACES"},
+ {DEL_FACES, "FACES"},
+ {DEL_FACES_KEEP_BOUNDARY, "FACES_KEEP_BOUNDARY"},
+ {DEL_ONLYTAGGED, "TAGGED_ONLY"},
+ {0, NULL},
};
/*
@@ -1368,17 +1368,17 @@ static BMO_FlagSet bmo_enum_delete_context[] = {
* Utility operator to delete geometry.
*/
static BMOpDefine bmo_delete_def = {
- "delete",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"context", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_delete_context}, /* geometry types to delete */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_delete_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "delete",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"context", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_delete_context}, /* geometry types to delete */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_delete_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -1388,30 +1388,30 @@ static BMOpDefine bmo_delete_def = {
* optionally into a destination mesh.
*/
static BMOpDefine bmo_duplicate_def = {
- "duplicate",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- /* destination bmesh, if NULL will use current on */
- {"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
- {"use_select_history", BMO_OP_SLOT_BOOL},
- {"use_edge_flip_from_face", BMO_OP_SLOT_BOOL},
- {{'\0'}},
- },
- /* slots_out */
- {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- /* facemap maps from source faces to dupe
- * faces, and from dupe faces to source faces */
- {"vert_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {"edge_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {"face_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {"boundary_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {"isovert_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {{'\0'}},
- },
- bmo_duplicate_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "duplicate",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ /* destination bmesh, if NULL will use current on */
+ {"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
+ {"use_select_history", BMO_OP_SLOT_BOOL},
+ {"use_edge_flip_from_face", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom_orig.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ /* facemap maps from source faces to dupe
+ * faces, and from dupe faces to source faces */
+ {"vert_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"edge_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"face_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"boundary_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"isovert_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
+ },
+ bmo_duplicate_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1421,23 +1421,23 @@ static BMOpDefine bmo_duplicate_def = {
* optionally into a destination mesh.
*/
static BMOpDefine bmo_split_def = {
- "split",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- /* destination bmesh, if NULL will use current one */
- {"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
- {"use_only_faces", BMO_OP_SLOT_BOOL}, /* when enabled. don't duplicate loose verts/edges */
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"boundary_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {"isovert_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
- {{'\0'}},
- },
- bmo_split_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "split",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ /* destination bmesh, if NULL will use current one */
+ {"dest", BMO_OP_SLOT_PTR, {(int)BMO_OP_SLOT_SUBTYPE_PTR_BMESH}},
+ {"use_only_faces", BMO_OP_SLOT_BOOL}, /* when enabled. don't duplicate loose verts/edges */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"boundary_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {"isovert_map.out", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_ELEM}},
+ {{'\0'}},
+ },
+ bmo_split_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1447,27 +1447,27 @@ static BMOpDefine bmo_split_def = {
* rotating and possibly translating after each step
*/
static BMOpDefine bmo_spin_def = {
- "spin",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"cent", BMO_OP_SLOT_VEC}, /* rotation center */
- {"axis", BMO_OP_SLOT_VEC}, /* rotation axis */
- {"dvec", BMO_OP_SLOT_VEC}, /* translation delta per step */
- {"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
- {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
- {"steps", BMO_OP_SLOT_INT}, /* number of steps */
- {"use_merge", BMO_OP_SLOT_BOOL}, /* Merge first/last when the angle is a full revolution. */
- {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
- {"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */
- {{'\0'}},
- },
- /* slots_out */
- {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* result of last step */
- {{'\0'}},
- },
- bmo_spin_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "spin",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"cent", BMO_OP_SLOT_VEC}, /* rotation center */
+ {"axis", BMO_OP_SLOT_VEC}, /* rotation axis */
+ {"dvec", BMO_OP_SLOT_VEC}, /* translation delta per step */
+ {"angle", BMO_OP_SLOT_FLT}, /* total rotation angle (radians) */
+ {"space", BMO_OP_SLOT_MAT}, /* matrix to define the space (typically object matrix) */
+ {"steps", BMO_OP_SLOT_INT}, /* number of steps */
+ {"use_merge", BMO_OP_SLOT_BOOL}, /* Merge first/last when the angle is a full revolution. */
+ {"use_normal_flip", BMO_OP_SLOT_BOOL}, /* Create faces with reversed direction. */
+ {"use_duplicate", BMO_OP_SLOT_BOOL}, /* duplicate or extrude? */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom_last.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* result of last step */
+ {{'\0'}},
+ },
+ bmo_spin_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1476,15 +1476,15 @@ static BMOpDefine bmo_spin_def = {
* Cycle the loop UV's
*/
static BMOpDefine bmo_rotate_uvs_def = {
- "rotate_uvs",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_rotate_uvs_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "rotate_uvs",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_rotate_uvs_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -1493,14 +1493,14 @@ static BMOpDefine bmo_rotate_uvs_def = {
* Reverse the UV's
*/
static BMOpDefine bmo_reverse_uvs_def = {
- "reverse_uvs",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_reverse_uvs_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "reverse_uvs",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_reverse_uvs_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -1509,15 +1509,15 @@ static BMOpDefine bmo_reverse_uvs_def = {
* Cycle the loop colors
*/
static BMOpDefine bmo_rotate_colors_def = {
- "rotate_colors",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_rotate_colors_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "rotate_colors",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"use_ccw", BMO_OP_SLOT_BOOL}, /* rotate counter-clockwise if true, otherwise clockwise */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_rotate_colors_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -1526,14 +1526,14 @@ static BMOpDefine bmo_rotate_colors_def = {
* Reverse the loop colors.
*/
static BMOpDefine bmo_reverse_colors_def = {
- "reverse_colors",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {{'\0'}},
- },
- {{{'\0'}}}, /* no output */
- bmo_reverse_colors_exec,
- (BMO_OPTYPE_FLAG_NOP),
+ "reverse_colors",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {{'\0'}},
+ },
+ {{{'\0'}}}, /* no output */
+ bmo_reverse_colors_exec,
+ (BMO_OPTYPE_FLAG_NOP),
};
/*
@@ -1542,22 +1542,22 @@ static BMOpDefine bmo_reverse_colors_def = {
* Disconnects faces along input edges.
*/
static BMOpDefine bmo_split_edges_def = {
- "split_edges",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
- {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* optional tag verts, use to have greater control of splits */
- {"use_verts", BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */
- {{'\0'}},
- },
- /* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* old output disconnected edges */
- {{'\0'}},
- },
- bmo_split_edges_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "split_edges",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ /* needed for vertex rip so we can rip only half an edge at a boundary wich would otherwise split off */
+ {"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* optional tag verts, use to have greater control of splits */
+ {"use_verts", BMO_OP_SLOT_BOOL}, /* use 'verts' for splitting, else just find verts to split from edges */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* old output disconnected edges */
+ {{'\0'}},
+ },
+ bmo_split_edges_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1566,22 +1566,22 @@ static BMOpDefine bmo_split_edges_def = {
* Creates a grid with a variable number of subdivisions
*/
static BMOpDefine bmo_create_grid_def = {
- "create_grid",
- /* slots_in */
- {{"x_segments", BMO_OP_SLOT_INT}, /* number of x segments */
- {"y_segments", BMO_OP_SLOT_INT}, /* number of y segments */
- {"size", BMO_OP_SLOT_FLT}, /* size of the grid */
- {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
- {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
- {{'\0'}},
- },
- /* slots_out */
- {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
- {{'\0'}},
- },
- bmo_create_grid_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "create_grid",
+ /* slots_in */
+ {{"x_segments", BMO_OP_SLOT_INT}, /* number of x segments */
+ {"y_segments", BMO_OP_SLOT_INT}, /* number of y segments */
+ {"size", BMO_OP_SLOT_FLT}, /* size of the grid */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
+ },
+ bmo_create_grid_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1590,22 +1590,22 @@ static BMOpDefine bmo_create_grid_def = {
* Creates a grid with a variable number of subdivisions
*/
static BMOpDefine bmo_create_uvsphere_def = {
- "create_uvsphere",
- /* slots_in */
- {{"u_segments", BMO_OP_SLOT_INT}, /* number of u segments */
- {"v_segments", BMO_OP_SLOT_INT}, /* number of v segment */
- {"diameter", BMO_OP_SLOT_FLT}, /* diameter */
- {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
- {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
- {{'\0'}},
- },
- /* slots_out */
- {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
- {{'\0'}},
- },
- bmo_create_uvsphere_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "create_uvsphere",
+ /* slots_in */
+ {{"u_segments", BMO_OP_SLOT_INT}, /* number of u segments */
+ {"v_segments", BMO_OP_SLOT_INT}, /* number of v segment */
+ {"diameter", BMO_OP_SLOT_FLT}, /* diameter */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
+ },
+ bmo_create_uvsphere_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1614,21 +1614,21 @@ static BMOpDefine bmo_create_uvsphere_def = {
* Creates a grid with a variable number of subdivisions
*/
static BMOpDefine bmo_create_icosphere_def = {
- "create_icosphere",
- /* slots_in */
- {{"subdivisions", BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */
- {"diameter", BMO_OP_SLOT_FLT}, /* diameter */
- {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
- {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
- {{'\0'}},
- },
- /* slots_out */
- {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
- {{'\0'}},
- },
- bmo_create_icosphere_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "create_icosphere",
+ /* slots_in */
+ {{"subdivisions", BMO_OP_SLOT_INT}, /* how many times to recursively subdivide the sphere */
+ {"diameter", BMO_OP_SLOT_FLT}, /* diameter */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
+ },
+ bmo_create_icosphere_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1637,19 +1637,19 @@ static BMOpDefine bmo_create_icosphere_def = {
* Creates a monkey (standard blender primitive).
*/
static BMOpDefine bmo_create_monkey_def = {
- "create_monkey",
- /* slots_in */
- {{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
- {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
- {{'\0'}},
- },
- /* slots_out */
- {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
- {{'\0'}},
- },
- bmo_create_monkey_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "create_monkey",
+ /* slots_in */
+ {{"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
+ },
+ bmo_create_monkey_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1658,48 +1658,48 @@ static BMOpDefine bmo_create_monkey_def = {
* Creates a cone with variable depth at both ends
*/
static BMOpDefine bmo_create_cone_def = {
- "create_cone",
- /* slots_in */
- {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */
- {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */
- {"segments", BMO_OP_SLOT_INT},
- {"diameter1", BMO_OP_SLOT_FLT}, /* diameter of one end */
- {"diameter2", BMO_OP_SLOT_FLT}, /* diameter of the opposite */
- {"depth", BMO_OP_SLOT_FLT}, /* distance between ends */
- {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
- {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
- {{'\0'}},
- },
- /* slots_out */
- {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
- {{'\0'}},
- },
- bmo_create_cone_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "create_cone",
+ /* slots_in */
+ {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */
+ {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */
+ {"segments", BMO_OP_SLOT_INT},
+ {"diameter1", BMO_OP_SLOT_FLT}, /* diameter of one end */
+ {"diameter2", BMO_OP_SLOT_FLT}, /* diameter of the opposite */
+ {"depth", BMO_OP_SLOT_FLT}, /* distance between ends */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
+ },
+ bmo_create_cone_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
* Creates a Circle.
*/
static BMOpDefine bmo_create_circle_def = {
- "create_circle",
- /* slots_in */
- {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */
- {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */
- {"segments", BMO_OP_SLOT_INT},
- {"radius", BMO_OP_SLOT_FLT}, /* Radius of the circle. */
- {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
- {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
- {{'\0'}},
- },
- /* slots_out */
- {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
- {{'\0'}},
- },
- bmo_create_circle_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "create_circle",
+ /* slots_in */
+ {{"cap_ends", BMO_OP_SLOT_BOOL}, /* whether or not to fill in the ends with faces */
+ {"cap_tris", BMO_OP_SLOT_BOOL}, /* fill ends with triangles instead of ngons */
+ {"segments", BMO_OP_SLOT_INT},
+ {"radius", BMO_OP_SLOT_FLT}, /* Radius of the circle. */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
+ },
+ bmo_create_circle_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1708,43 +1708,43 @@ static BMOpDefine bmo_create_circle_def = {
* Creates a cube.
*/
static BMOpDefine bmo_create_cube_def = {
- "create_cube",
- /* slots_in */
- {{"size", BMO_OP_SLOT_FLT}, /* size of the cube */
- {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
- {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
- {{'\0'}},
- },
- /* slots_out */
- {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
- {{'\0'}},
- },
- bmo_create_cube_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "create_cube",
+ /* slots_in */
+ {{"size", BMO_OP_SLOT_FLT}, /* size of the cube */
+ {"matrix", BMO_OP_SLOT_MAT}, /* matrix to multiply the new geometry with */
+ {"calc_uvs", BMO_OP_SLOT_BOOL}, /* calculate default UVs */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
+ },
+ bmo_create_cube_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
static BMO_FlagSet bmo_enum_bevel_offset_type[] = {
- {BEVEL_AMT_OFFSET, "OFFSET"},
- {BEVEL_AMT_WIDTH, "WIDTH"},
- {BEVEL_AMT_DEPTH, "DEPTH"},
- {BEVEL_AMT_PERCENT, "PERCENT"},
- {0, NULL},
+ {BEVEL_AMT_OFFSET, "OFFSET"},
+ {BEVEL_AMT_WIDTH, "WIDTH"},
+ {BEVEL_AMT_DEPTH, "DEPTH"},
+ {BEVEL_AMT_PERCENT, "PERCENT"},
+ {0, NULL},
};
static BMO_FlagSet bmo_enum_bevel_face_strength_type[] = {
- {BEVEL_FACE_STRENGTH_NONE, "NONE"},
- {BEVEL_FACE_STRENGTH_NEW, "NEW"},
- {BEVEL_FACE_STRENGTH_AFFECTED, "AFFECTED"},
- {BEVEL_FACE_STRENGTH_ALL, "ALL"},
- {0, NULL},
+ {BEVEL_FACE_STRENGTH_NONE, "NONE"},
+ {BEVEL_FACE_STRENGTH_NEW, "NEW"},
+ {BEVEL_FACE_STRENGTH_AFFECTED, "AFFECTED"},
+ {BEVEL_FACE_STRENGTH_ALL, "ALL"},
+ {0, NULL},
};
static BMO_FlagSet bmo_enum_bevel_miter_type[] = {
- {BEVEL_MITER_SHARP, "SHARP"},
- {BEVEL_MITER_PATCH, "PATCH"},
- {BEVEL_MITER_ARC, "ARC"},
- {0, NULL},
+ {BEVEL_MITER_SHARP, "SHARP"},
+ {BEVEL_MITER_PATCH, "PATCH"},
+ {BEVEL_MITER_ARC, "ARC"},
+ {0, NULL},
};
/*
@@ -1753,49 +1753,49 @@ static BMO_FlagSet bmo_enum_bevel_miter_type[] = {
* Bevels edges and vertices
*/
static BMOpDefine bmo_bevel_def = {
- "bevel",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */
- {"offset", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */
- {"offset_type", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_bevel_offset_type}, /* how to measure the offset */
- {"segments", BMO_OP_SLOT_INT}, /* number of segments in bevel */
- {"profile", BMO_OP_SLOT_FLT}, /* profile shape, 0->1 (.5=>round) */
- {"vertex_only", BMO_OP_SLOT_BOOL}, /* only bevel vertices, not edges */
- {"clamp_overlap", BMO_OP_SLOT_BOOL}, /* do not allow beveled edges/vertices to overlap each other */
- {"material", BMO_OP_SLOT_INT}, /* material for bevel faces, -1 means get from adjacent faces */
- {"loop_slide", BMO_OP_SLOT_BOOL}, /* prefer to slide along edges to having even widths */
- {"mark_seam", BMO_OP_SLOT_BOOL}, /* extend edge data to allow seams to run across bevels */
- {"mark_sharp", BMO_OP_SLOT_BOOL}, /* extend edge data to allow sharp edges to run across bevels */
- {"harden_normals", BMO_OP_SLOT_BOOL}, /* harden normals */
- {"face_strength_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
- bmo_enum_bevel_face_strength_type}, /* whether to set face strength, and which faces to set if so */
- {"miter_outer", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
- bmo_enum_bevel_miter_type}, /* outer miter kind */
- {"miter_inner", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
- bmo_enum_bevel_miter_type}, /* outer miter kind */
- {"spread", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */
- {"smoothresh", BMO_OP_SLOT_FLT}, /* for passing mesh's smoothresh, used in hardening */
- {{'\0'}},
- },
- /* slots_out */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
- {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */
- {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
- {{'\0'}},
- },
-
- bmo_bevel_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "bevel",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* input edges and vertices */
+ {"offset", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */
+ {"offset_type", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_bevel_offset_type}, /* how to measure the offset */
+ {"segments", BMO_OP_SLOT_INT}, /* number of segments in bevel */
+ {"profile", BMO_OP_SLOT_FLT}, /* profile shape, 0->1 (.5=>round) */
+ {"vertex_only", BMO_OP_SLOT_BOOL}, /* only bevel vertices, not edges */
+ {"clamp_overlap", BMO_OP_SLOT_BOOL}, /* do not allow beveled edges/vertices to overlap each other */
+ {"material", BMO_OP_SLOT_INT}, /* material for bevel faces, -1 means get from adjacent faces */
+ {"loop_slide", BMO_OP_SLOT_BOOL}, /* prefer to slide along edges to having even widths */
+ {"mark_seam", BMO_OP_SLOT_BOOL}, /* extend edge data to allow seams to run across bevels */
+ {"mark_sharp", BMO_OP_SLOT_BOOL}, /* extend edge data to allow sharp edges to run across bevels */
+ {"harden_normals", BMO_OP_SLOT_BOOL}, /* harden normals */
+ {"face_strength_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
+ bmo_enum_bevel_face_strength_type}, /* whether to set face strength, and which faces to set if so */
+ {"miter_outer", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
+ bmo_enum_bevel_miter_type}, /* outer miter kind */
+ {"miter_inner", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM},
+ bmo_enum_bevel_miter_type}, /* outer miter kind */
+ {"spread", BMO_OP_SLOT_FLT}, /* amount to offset beveled edge */
+ {"smoothresh", BMO_OP_SLOT_FLT}, /* for passing mesh's smoothresh, used in hardening */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */
+ {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {{'\0'}},
+ },
+
+ bmo_bevel_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/* no enum is defined for this */
static BMO_FlagSet bmo_enum_beautify_fill_method[] = {
- {0, "AREA"},
- {1, "ANGLE"},
- {0, NULL},
+ {0, "AREA"},
+ {1, "ANGLE"},
+ {0, NULL},
};
/*
@@ -1804,23 +1804,23 @@ static BMO_FlagSet bmo_enum_beautify_fill_method[] = {
* Rotate edges to create more evenly spaced triangles.
*/
static BMOpDefine bmo_beautify_fill_def = {
- "beautify_fill",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can be flipped */
- {"use_restrict_tag", BMO_OP_SLOT_BOOL}, /* restrict edge rotation to mixed tagged vertices */
- {"method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_beautify_fill_method}, /* method to define what is beautiful */
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new flipped faces and edges */
- {{'\0'}},
- },
- bmo_beautify_fill_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "beautify_fill",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* edges that can be flipped */
+ {"use_restrict_tag", BMO_OP_SLOT_BOOL}, /* restrict edge rotation to mixed tagged vertices */
+ {"method", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_beautify_fill_method}, /* method to define what is beautiful */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new flipped faces and edges */
+ {{'\0'}},
+ },
+ bmo_beautify_fill_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/*
@@ -1829,22 +1829,22 @@ static BMOpDefine bmo_beautify_fill_def = {
* Fill edges with triangles
*/
static BMOpDefine bmo_triangle_fill_def = {
- "triangle_fill",
- /* slots_in */
- {{"use_beauty", BMO_OP_SLOT_BOOL},
- {"use_dissolve", BMO_OP_SLOT_BOOL}, /* dissolve resulting faces */
- {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
- {"normal", BMO_OP_SLOT_VEC}, /* optionally pass the fill normal to use */
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new faces and edges */
- {{'\0'}},
- },
- bmo_triangle_fill_exec,
- (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
- BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "triangle_fill",
+ /* slots_in */
+ {{"use_beauty", BMO_OP_SLOT_BOOL},
+ {"use_dissolve", BMO_OP_SLOT_BOOL}, /* dissolve resulting faces */
+ {"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+ {"normal", BMO_OP_SLOT_VEC}, /* optionally pass the fill normal to use */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* new faces and edges */
+ {{'\0'}},
+ },
+ bmo_triangle_fill_exec,
+ (BMO_OPTYPE_FLAG_UNTAN_MULTIRES |
+ BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1853,19 +1853,19 @@ static BMOpDefine bmo_triangle_fill_def = {
* Turns a mesh into a shell with thickness
*/
static BMOpDefine bmo_solidify_def = {
- "solidify",
- /* slots_in */
- {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"thickness", BMO_OP_SLOT_FLT},
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {{'\0'}},
- },
- bmo_solidify_face_region_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "solidify",
+ /* slots_in */
+ {{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"thickness", BMO_OP_SLOT_FLT},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
+ },
+ bmo_solidify_face_region_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1874,23 +1874,23 @@ static BMOpDefine bmo_solidify_def = {
* Insets individual faces.
*/
static BMOpDefine bmo_inset_individual_def = {
- "inset_individual",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"thickness", BMO_OP_SLOT_FLT},
- {"depth", BMO_OP_SLOT_FLT},
- {"use_even_offset", BMO_OP_SLOT_BOOL},
- {"use_interpolate", BMO_OP_SLOT_BOOL},
- {"use_relative_offset", BMO_OP_SLOT_BOOL},
- {{'\0'}},
- },
- /* slots_out */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
- {{'\0'}},
- },
- bmo_inset_individual_exec,
- /* caller needs to handle BMO_OPTYPE_FLAG_SELECT_FLUSH */
- (BMO_OPTYPE_FLAG_NORMALS_CALC),
+ "inset_individual",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"thickness", BMO_OP_SLOT_FLT},
+ {"depth", BMO_OP_SLOT_FLT},
+ {"use_even_offset", BMO_OP_SLOT_BOOL},
+ {"use_interpolate", BMO_OP_SLOT_BOOL},
+ {"use_relative_offset", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
+ },
+ bmo_inset_individual_exec,
+ /* caller needs to handle BMO_OPTYPE_FLAG_SELECT_FLUSH */
+ (BMO_OPTYPE_FLAG_NORMALS_CALC),
};
/*
@@ -1899,27 +1899,27 @@ static BMOpDefine bmo_inset_individual_def = {
* Inset or outset face regions.
*/
static BMOpDefine bmo_inset_region_def = {
- "inset_region",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
- {"use_boundary", BMO_OP_SLOT_BOOL},
- {"use_even_offset", BMO_OP_SLOT_BOOL},
- {"use_interpolate", BMO_OP_SLOT_BOOL},
- {"use_relative_offset", BMO_OP_SLOT_BOOL},
- {"use_edge_rail", BMO_OP_SLOT_BOOL},
- {"thickness", BMO_OP_SLOT_FLT},
- {"depth", BMO_OP_SLOT_FLT},
- {"use_outset", BMO_OP_SLOT_BOOL},
- {{'\0'}},
- },
- /* slots_out */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
- {{'\0'}},
- },
- bmo_inset_region_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "inset_region",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"faces_exclude", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},
+ {"use_boundary", BMO_OP_SLOT_BOOL},
+ {"use_even_offset", BMO_OP_SLOT_BOOL},
+ {"use_interpolate", BMO_OP_SLOT_BOOL},
+ {"use_relative_offset", BMO_OP_SLOT_BOOL},
+ {"use_edge_rail", BMO_OP_SLOT_BOOL},
+ {"thickness", BMO_OP_SLOT_FLT},
+ {"depth", BMO_OP_SLOT_FLT},
+ {"use_outset", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
+ },
+ bmo_inset_region_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1928,19 +1928,19 @@ static BMOpDefine bmo_inset_region_def = {
* Creates edge loops based on simple edge-outset method.
*/
static BMOpDefine bmo_offset_edgeloops_def = {
- "offset_edgeloops",
- /* slots_in */
- {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input faces */
- {"use_cap_endpoint", BMO_OP_SLOT_BOOL},
- {{'\0'}},
- },
- /* slots_out */
- {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output faces */
- {{'\0'}},
- },
- bmo_offset_edgeloops_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH),
+ "offset_edgeloops",
+ /* slots_in */
+ {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input faces */
+ {"use_cap_endpoint", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output faces */
+ {{'\0'}},
+ },
+ bmo_offset_edgeloops_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH),
};
/*
@@ -1949,35 +1949,35 @@ static BMOpDefine bmo_offset_edgeloops_def = {
* Makes a wire-frame copy of faces.
*/
static BMOpDefine bmo_wireframe_def = {
- "wireframe",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"thickness", BMO_OP_SLOT_FLT},
- {"offset", BMO_OP_SLOT_FLT},
- {"use_replace", BMO_OP_SLOT_BOOL},
- {"use_boundary", BMO_OP_SLOT_BOOL},
- {"use_even_offset", BMO_OP_SLOT_BOOL},
- {"use_crease", BMO_OP_SLOT_BOOL},
- {"crease_weight", BMO_OP_SLOT_FLT},
- {"use_relative_offset", BMO_OP_SLOT_BOOL},
- {"material_offset", BMO_OP_SLOT_INT},
- {{'\0'}},
- },
- /* slots_out */
- {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
- {{'\0'}},
- },
- bmo_wireframe_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "wireframe",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"thickness", BMO_OP_SLOT_FLT},
+ {"offset", BMO_OP_SLOT_FLT},
+ {"use_replace", BMO_OP_SLOT_BOOL},
+ {"use_boundary", BMO_OP_SLOT_BOOL},
+ {"use_even_offset", BMO_OP_SLOT_BOOL},
+ {"use_crease", BMO_OP_SLOT_BOOL},
+ {"crease_weight", BMO_OP_SLOT_FLT},
+ {"use_relative_offset", BMO_OP_SLOT_BOOL},
+ {"material_offset", BMO_OP_SLOT_INT},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
+ },
+ bmo_wireframe_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
static BMO_FlagSet bmo_enum_poke_center_mode[] = {
- {BMOP_POKE_MEDIAN_WEIGHTED, "MEAN_WEIGHTED"},
- {BMOP_POKE_MEDIAN, "MEAN"},
- {BMOP_POKE_BOUNDS, "BOUNDS"},
- {0, NULL},
+ {BMOP_POKE_MEDIAN_WEIGHTED, "MEAN_WEIGHTED"},
+ {BMOP_POKE_MEDIAN, "MEAN"},
+ {BMOP_POKE_BOUNDS, "BOUNDS"},
+ {0, NULL},
};
/*
@@ -1986,23 +1986,23 @@ static BMO_FlagSet bmo_enum_poke_center_mode[] = {
* Splits a face into a triangle fan.
*/
static BMOpDefine bmo_poke_def = {
- "poke",
- /* slots_in */
- {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
- {"offset", BMO_OP_SLOT_FLT}, /* center vertex offset along normal */
- {"center_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_poke_center_mode}, /* calculation mode for center vertex */
- {"use_relative_offset", BMO_OP_SLOT_BOOL}, /* apply offset */
- {{'\0'}},
- },
- /* slots_out */
- {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
- {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
- {{'\0'}},
- },
- bmo_poke_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "poke",
+ /* slots_in */
+ {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* input faces */
+ {"offset", BMO_OP_SLOT_FLT}, /* center vertex offset along normal */
+ {"center_mode", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_poke_center_mode}, /* calculation mode for center vertex */
+ {"use_relative_offset", BMO_OP_SLOT_BOOL}, /* apply offset */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
+ {"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {{'\0'}},
+ },
+ bmo_poke_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
#ifdef WITH_BULLET
@@ -2022,23 +2022,23 @@ static BMOpDefine bmo_poke_def = {
* that were in the input and are part of the hull.
*/
static BMOpDefine bmo_convex_hull_def = {
- "convex_hull",
- /* slots_in */
- {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"use_existing_faces", BMO_OP_SLOT_BOOL},
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {{'\0'}},
- },
- bmo_convex_hull_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "convex_hull",
+ /* slots_in */
+ {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"use_existing_faces", BMO_OP_SLOT_BOOL},
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom_interior.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom_unused.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"geom_holes.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
+ },
+ bmo_convex_hull_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
#endif
@@ -2053,108 +2053,108 @@ static BMOpDefine bmo_convex_hull_def = {
* All new vertices, edges, and faces are added to the "geom.out" slot.
*/
static BMOpDefine bmo_symmetrize_def = {
- "symmetrize",
- /* slots_in */
- {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {"direction", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_axis_xyz}, /* axis to use */
- {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
- {{'\0'}},
- },
- /* slots_out */
- {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
- {{'\0'}},
- },
- bmo_symmetrize_exec,
- (BMO_OPTYPE_FLAG_NORMALS_CALC |
- BMO_OPTYPE_FLAG_SELECT_FLUSH |
- BMO_OPTYPE_FLAG_SELECT_VALIDATE),
+ "symmetrize",
+ /* slots_in */
+ {{"input", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {"direction", BMO_OP_SLOT_INT, {(int)BMO_OP_SLOT_SUBTYPE_INT_ENUM}, bmo_enum_axis_xyz}, /* axis to use */
+ {"dist", BMO_OP_SLOT_FLT}, /* minimum distance */
+ {{'\0'}},
+ },
+ /* slots_out */
+ {{"geom.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}},
+ {{'\0'}},
+ },
+ bmo_symmetrize_exec,
+ (BMO_OPTYPE_FLAG_NORMALS_CALC |
+ BMO_OPTYPE_FLAG_SELECT_FLUSH |
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE),
};
/* clang-format on */
const BMOpDefine *bmo_opdefines[] = {
- &bmo_automerge_def,
- &bmo_average_vert_facedata_def,
- &bmo_beautify_fill_def,
- &bmo_bevel_def,
- &bmo_bisect_edges_def,
- &bmo_bmesh_to_mesh_def,
- &bmo_bridge_loops_def,
- &bmo_collapse_def,
- &bmo_collapse_uvs_def,
- &bmo_connect_verts_def,
- &bmo_connect_verts_concave_def,
- &bmo_connect_verts_nonplanar_def,
- &bmo_connect_vert_pair_def,
- &bmo_contextual_create_def,
+ &bmo_automerge_def,
+ &bmo_average_vert_facedata_def,
+ &bmo_beautify_fill_def,
+ &bmo_bevel_def,
+ &bmo_bisect_edges_def,
+ &bmo_bmesh_to_mesh_def,
+ &bmo_bridge_loops_def,
+ &bmo_collapse_def,
+ &bmo_collapse_uvs_def,
+ &bmo_connect_verts_def,
+ &bmo_connect_verts_concave_def,
+ &bmo_connect_verts_nonplanar_def,
+ &bmo_connect_vert_pair_def,
+ &bmo_contextual_create_def,
#ifdef WITH_BULLET
- &bmo_convex_hull_def,
+ &bmo_convex_hull_def,
#endif
- &bmo_create_circle_def,
- &bmo_create_cone_def,
- &bmo_create_cube_def,
- &bmo_create_grid_def,
- &bmo_create_icosphere_def,
- &bmo_create_monkey_def,
- &bmo_create_uvsphere_def,
- &bmo_create_vert_def,
- &bmo_delete_def,
- &bmo_dissolve_edges_def,
- &bmo_dissolve_faces_def,
- &bmo_dissolve_verts_def,
- &bmo_dissolve_limit_def,
- &bmo_dissolve_degenerate_def,
- &bmo_duplicate_def,
- &bmo_holes_fill_def,
- &bmo_face_attribute_fill_def,
- &bmo_offset_edgeloops_def,
- &bmo_edgeloop_fill_def,
- &bmo_edgenet_fill_def,
- &bmo_edgenet_prepare_def,
- &bmo_extrude_discrete_faces_def,
- &bmo_extrude_edge_only_def,
- &bmo_extrude_face_region_def,
- &bmo_extrude_vert_indiv_def,
- &bmo_find_doubles_def,
- &bmo_grid_fill_def,
- &bmo_inset_individual_def,
- &bmo_inset_region_def,
- &bmo_join_triangles_def,
- &bmo_mesh_to_bmesh_def,
- &bmo_mirror_def,
- &bmo_object_load_bmesh_def,
- &bmo_pointmerge_def,
- &bmo_pointmerge_facedata_def,
- &bmo_poke_def,
- &bmo_recalc_face_normals_def,
- &bmo_planar_faces_def,
- &bmo_region_extend_def,
- &bmo_remove_doubles_def,
- &bmo_reverse_colors_def,
- &bmo_reverse_faces_def,
- &bmo_reverse_uvs_def,
- &bmo_rotate_colors_def,
- &bmo_rotate_def,
- &bmo_rotate_edges_def,
- &bmo_rotate_uvs_def,
- &bmo_scale_def,
- &bmo_smooth_vert_def,
- &bmo_smooth_laplacian_vert_def,
- &bmo_solidify_def,
- &bmo_spin_def,
- &bmo_split_def,
- &bmo_split_edges_def,
- &bmo_subdivide_edges_def,
- &bmo_subdivide_edgering_def,
- &bmo_bisect_plane_def,
- &bmo_symmetrize_def,
- &bmo_transform_def,
- &bmo_translate_def,
- &bmo_triangle_fill_def,
- &bmo_triangulate_def,
- &bmo_unsubdivide_def,
- &bmo_weld_verts_def,
- &bmo_wireframe_def,
+ &bmo_create_circle_def,
+ &bmo_create_cone_def,
+ &bmo_create_cube_def,
+ &bmo_create_grid_def,
+ &bmo_create_icosphere_def,
+ &bmo_create_monkey_def,
+ &bmo_create_uvsphere_def,
+ &bmo_create_vert_def,
+ &bmo_delete_def,
+ &bmo_dissolve_edges_def,
+ &bmo_dissolve_faces_def,
+ &bmo_dissolve_verts_def,
+ &bmo_dissolve_limit_def,
+ &bmo_dissolve_degenerate_def,
+ &bmo_duplicate_def,
+ &bmo_holes_fill_def,
+ &bmo_face_attribute_fill_def,
+ &bmo_offset_edgeloops_def,
+ &bmo_edgeloop_fill_def,
+ &bmo_edgenet_fill_def,
+ &bmo_edgenet_prepare_def,
+ &bmo_extrude_discrete_faces_def,
+ &bmo_extrude_edge_only_def,
+ &bmo_extrude_face_region_def,
+ &bmo_extrude_vert_indiv_def,
+ &bmo_find_doubles_def,
+ &bmo_grid_fill_def,
+ &bmo_inset_individual_def,
+ &bmo_inset_region_def,
+ &bmo_join_triangles_def,
+ &bmo_mesh_to_bmesh_def,
+ &bmo_mirror_def,
+ &bmo_object_load_bmesh_def,
+ &bmo_pointmerge_def,
+ &bmo_pointmerge_facedata_def,
+ &bmo_poke_def,
+ &bmo_recalc_face_normals_def,
+ &bmo_planar_faces_def,
+ &bmo_region_extend_def,
+ &bmo_remove_doubles_def,
+ &bmo_reverse_colors_def,
+ &bmo_reverse_faces_def,
+ &bmo_reverse_uvs_def,
+ &bmo_rotate_colors_def,
+ &bmo_rotate_def,
+ &bmo_rotate_edges_def,
+ &bmo_rotate_uvs_def,
+ &bmo_scale_def,
+ &bmo_smooth_vert_def,
+ &bmo_smooth_laplacian_vert_def,
+ &bmo_solidify_def,
+ &bmo_spin_def,
+ &bmo_split_def,
+ &bmo_split_edges_def,
+ &bmo_subdivide_edges_def,
+ &bmo_subdivide_edgering_def,
+ &bmo_bisect_plane_def,
+ &bmo_symmetrize_def,
+ &bmo_transform_def,
+ &bmo_translate_def,
+ &bmo_triangle_fill_def,
+ &bmo_triangulate_def,
+ &bmo_unsubdivide_def,
+ &bmo_weld_verts_def,
+ &bmo_wireframe_def,
};
const int bmo_opdefines_total = ARRAY_SIZE(bmo_opdefines);
diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h
index 9894252a53a..5085eb801ce 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -71,222 +71,274 @@ struct GHashIterator;
BLI_INLINE BMFlagLayer *BMO_elem_flag_from_header(BMHeader *ele_head)
{
- switch (ele_head->htype) {
- case BM_VERT: return ((BMVert_OFlag *)ele_head)->oflags;
- case BM_EDGE: return ((BMEdge_OFlag *)ele_head)->oflags;
- default: return ((BMFace_OFlag *)ele_head)->oflags;
- }
+ switch (ele_head->htype) {
+ case BM_VERT:
+ return ((BMVert_OFlag *)ele_head)->oflags;
+ case BM_EDGE:
+ return ((BMEdge_OFlag *)ele_head)->oflags;
+ default:
+ return ((BMFace_OFlag *)ele_head)->oflags;
+ }
}
#define BMO_elem_flag_test(bm, ele, oflag) \
- _bmo_elem_flag_test(bm, BMO_elem_flag_from_header(&(ele)->head), oflag)
+ _bmo_elem_flag_test(bm, BMO_elem_flag_from_header(&(ele)->head), oflag)
#define BMO_elem_flag_test_bool(bm, ele, oflag) \
- _bmo_elem_flag_test_bool(bm, BMO_elem_flag_from_header(&(ele)->head), oflag)
+ _bmo_elem_flag_test_bool(bm, BMO_elem_flag_from_header(&(ele)->head), oflag)
#define BMO_elem_flag_enable(bm, ele, oflag) \
- _bmo_elem_flag_enable(bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
+ _bmo_elem_flag_enable( \
+ bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
#define BMO_elem_flag_disable(bm, ele, oflag) \
- _bmo_elem_flag_disable(bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
+ _bmo_elem_flag_disable( \
+ bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
#define BMO_elem_flag_set(bm, ele, oflag, val) \
- _bmo_elem_flag_set(bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag, val)
+ _bmo_elem_flag_set(bm, \
+ (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), \
+ oflag, \
+ val)
#define BMO_elem_flag_toggle(bm, ele, oflag) \
- _bmo_elem_flag_toggle(bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
+ _bmo_elem_flag_toggle( \
+ bm, (BM_CHECK_TYPE_ELEM_NONCONST(ele), BMO_elem_flag_from_header(&(ele)->head)), oflag)
/* take care not to instansiate args multiple times */
#ifdef __GNUC___
-#define _BMO_CAST_V_CONST(e) ({ typeof(e) _e = e; \
- (BM_CHECK_TYPE_VERT(_e), BLI_assert(((const BMHeader *)_e)->htype == BM_VERT), (const BMVert_OFlag *)_e); })
-#define _BMO_CAST_E_CONST(e) ({ typeof(e) _e = e; \
- (BM_CHECK_TYPE_EDGE(_e), BLI_assert(((const BMHeader *)_e)->htype == BM_EDGE), (const BMEdge_OFlag *)_e); })
-#define _BMO_CAST_F_CONST(e) ({ typeof(e) _e = e; \
- (BM_CHECK_TYPE_FACE(_e), BLI_assert(((const BMHeader *)_e)->htype == BM_FACE), (const BMFace_OFlag *)_e); })
-#define _BMO_CAST_V(e) ({ typeof(e) _e = e; \
- (BM_CHECK_TYPE_VERT_NONCONST(_e), BLI_assert(((BMHeader *)_e)->htype == BM_VERT), (BMVert_OFlag *)_e); })
-#define _BMO_CAST_E(e) ({ typeof(e) _e = e; \
- (BM_CHECK_TYPE_EDGE_NONCONST(_e), BLI_assert(((BMHeader *)_e)->htype == BM_EDGE), (BMEdge_OFlag *)_e); })
-#define _BMO_CAST_F(e) ({ typeof(e) _e = e; \
- (BM_CHECK_TYPE_FACE_NONCONST(_e), BLI_assert(((BMHeader *)_e)->htype == BM_FACE), (BMFace_OFlag *)_e); })
+# define _BMO_CAST_V_CONST(e) \
+ ({ \
+ typeof(e) _e = e; \
+ (BM_CHECK_TYPE_VERT(_e), \
+ BLI_assert(((const BMHeader *)_e)->htype == BM_VERT), \
+ (const BMVert_OFlag *)_e); \
+ })
+# define _BMO_CAST_E_CONST(e) \
+ ({ \
+ typeof(e) _e = e; \
+ (BM_CHECK_TYPE_EDGE(_e), \
+ BLI_assert(((const BMHeader *)_e)->htype == BM_EDGE), \
+ (const BMEdge_OFlag *)_e); \
+ })
+# define _BMO_CAST_F_CONST(e) \
+ ({ \
+ typeof(e) _e = e; \
+ (BM_CHECK_TYPE_FACE(_e), \
+ BLI_assert(((const BMHeader *)_e)->htype == BM_FACE), \
+ (const BMFace_OFlag *)_e); \
+ })
+# define _BMO_CAST_V(e) \
+ ({ \
+ typeof(e) _e = e; \
+ (BM_CHECK_TYPE_VERT_NONCONST(_e), \
+ BLI_assert(((BMHeader *)_e)->htype == BM_VERT), \
+ (BMVert_OFlag *)_e); \
+ })
+# define _BMO_CAST_E(e) \
+ ({ \
+ typeof(e) _e = e; \
+ (BM_CHECK_TYPE_EDGE_NONCONST(_e), \
+ BLI_assert(((BMHeader *)_e)->htype == BM_EDGE), \
+ (BMEdge_OFlag *)_e); \
+ })
+# define _BMO_CAST_F(e) \
+ ({ \
+ typeof(e) _e = e; \
+ (BM_CHECK_TYPE_FACE_NONCONST(_e), \
+ BLI_assert(((BMHeader *)_e)->htype == BM_FACE), \
+ (BMFace_OFlag *)_e); \
+ })
#else
-#define _BMO_CAST_V_CONST(e) (BM_CHECK_TYPE_VERT(e), (const BMVert_OFlag *)e)
-#define _BMO_CAST_E_CONST(e) (BM_CHECK_TYPE_EDGE(e), (const BMEdge_OFlag *)e)
-#define _BMO_CAST_F_CONST(e) (BM_CHECK_TYPE_FACE(e), (const BMFace_OFlag *)e)
-#define _BMO_CAST_V(e) (BM_CHECK_TYPE_VERT_NONCONST(e), (BMVert_OFlag *)e)
-#define _BMO_CAST_E(e) (BM_CHECK_TYPE_EDGE_NONCONST(e), (BMEdge_OFlag *)e)
-#define _BMO_CAST_F(e) (BM_CHECK_TYPE_FACE_NONCONST(e), (BMFace_OFlag *)e)
+# define _BMO_CAST_V_CONST(e) (BM_CHECK_TYPE_VERT(e), (const BMVert_OFlag *)e)
+# define _BMO_CAST_E_CONST(e) (BM_CHECK_TYPE_EDGE(e), (const BMEdge_OFlag *)e)
+# define _BMO_CAST_F_CONST(e) (BM_CHECK_TYPE_FACE(e), (const BMFace_OFlag *)e)
+# define _BMO_CAST_V(e) (BM_CHECK_TYPE_VERT_NONCONST(e), (BMVert_OFlag *)e)
+# define _BMO_CAST_E(e) (BM_CHECK_TYPE_EDGE_NONCONST(e), (BMEdge_OFlag *)e)
+# define _BMO_CAST_F(e) (BM_CHECK_TYPE_FACE_NONCONST(e), (BMFace_OFlag *)e)
#endif
-#define BMO_vert_flag_test( bm, e, oflag) _bmo_elem_flag_test (bm, _BMO_CAST_V_CONST(e)->oflags, oflag)
-#define BMO_vert_flag_test_bool(bm, e, oflag) _bmo_elem_flag_test_bool(bm, _BMO_CAST_V_CONST(e)->oflags, oflag)
-#define BMO_vert_flag_enable( bm, e, oflag) _bmo_elem_flag_enable (bm, _BMO_CAST_V(e)->oflags, oflag)
-#define BMO_vert_flag_disable( bm, e, oflag) _bmo_elem_flag_disable (bm, _BMO_CAST_V(e)->oflags, oflag)
-#define BMO_vert_flag_set( bm, e, oflag, val) _bmo_elem_flag_set (bm, _BMO_CAST_V(e)->oflags, oflag, val)
-#define BMO_vert_flag_toggle( bm, e, oflag) _bmo_elem_flag_toggle (bm, _BMO_CAST_V(e)->oflags, oflag)
-
-#define BMO_edge_flag_test( bm, e, oflag) _bmo_elem_flag_test (bm, _BMO_CAST_E_CONST(e)->oflags, oflag)
-#define BMO_edge_flag_test_bool(bm, e, oflag) _bmo_elem_flag_test_bool(bm, _BMO_CAST_E_CONST(e)->oflags, oflag)
-#define BMO_edge_flag_enable( bm, e, oflag) _bmo_elem_flag_enable (bm, _BMO_CAST_E(e)->oflags, oflag)
-#define BMO_edge_flag_disable( bm, e, oflag) _bmo_elem_flag_disable (bm, _BMO_CAST_E(e)->oflags, oflag)
-#define BMO_edge_flag_set( bm, e, oflag, val) _bmo_elem_flag_set (bm, _BMO_CAST_E(e)->oflags, oflag, val)
-#define BMO_edge_flag_toggle( bm, e, oflag) _bmo_elem_flag_toggle (bm, _BMO_CAST_E(e)->oflags, oflag)
-
-#define BMO_face_flag_test( bm, e, oflag) _bmo_elem_flag_test (bm, _BMO_CAST_F_CONST(e)->oflags, oflag)
-#define BMO_face_flag_test_bool(bm, e, oflag) _bmo_elem_flag_test_bool(bm, _BMO_CAST_F_CONST(e)->oflags, oflag)
-#define BMO_face_flag_enable( bm, e, oflag) _bmo_elem_flag_enable (bm, _BMO_CAST_F(e)->oflags, oflag)
-#define BMO_face_flag_disable( bm, e, oflag) _bmo_elem_flag_disable (bm, _BMO_CAST_F(e)->oflags, oflag)
-#define BMO_face_flag_set( bm, e, oflag, val) _bmo_elem_flag_set (bm, _BMO_CAST_F(e)->oflags, oflag, val)
-#define BMO_face_flag_toggle( bm, e, oflag) _bmo_elem_flag_toggle (bm, _BMO_CAST_F(e)->oflags, oflag)
-
-BLI_INLINE short _bmo_elem_flag_test( BMesh *bm, const BMFlagLayer *oflags, const short oflag);
-BLI_INLINE bool _bmo_elem_flag_test_bool(BMesh *bm, const BMFlagLayer *oflags, const short oflag);
-BLI_INLINE void _bmo_elem_flag_enable( BMesh *bm, BMFlagLayer *oflags, const short oflag);
-BLI_INLINE void _bmo_elem_flag_disable( BMesh *bm, BMFlagLayer *oflags, const short oflag);
-BLI_INLINE void _bmo_elem_flag_set( BMesh *bm, BMFlagLayer *oflags, const short oflag, int val);
-BLI_INLINE void _bmo_elem_flag_toggle( BMesh *bm, BMFlagLayer *oflags, const short oflag);
+#define BMO_vert_flag_test(bm, e, oflag) \
+ _bmo_elem_flag_test(bm, _BMO_CAST_V_CONST(e)->oflags, oflag)
+#define BMO_vert_flag_test_bool(bm, e, oflag) \
+ _bmo_elem_flag_test_bool(bm, _BMO_CAST_V_CONST(e)->oflags, oflag)
+#define BMO_vert_flag_enable(bm, e, oflag) _bmo_elem_flag_enable(bm, _BMO_CAST_V(e)->oflags, oflag)
+#define BMO_vert_flag_disable(bm, e, oflag) \
+ _bmo_elem_flag_disable(bm, _BMO_CAST_V(e)->oflags, oflag)
+#define BMO_vert_flag_set(bm, e, oflag, val) \
+ _bmo_elem_flag_set(bm, _BMO_CAST_V(e)->oflags, oflag, val)
+#define BMO_vert_flag_toggle(bm, e, oflag) _bmo_elem_flag_toggle(bm, _BMO_CAST_V(e)->oflags, oflag)
+
+#define BMO_edge_flag_test(bm, e, oflag) \
+ _bmo_elem_flag_test(bm, _BMO_CAST_E_CONST(e)->oflags, oflag)
+#define BMO_edge_flag_test_bool(bm, e, oflag) \
+ _bmo_elem_flag_test_bool(bm, _BMO_CAST_E_CONST(e)->oflags, oflag)
+#define BMO_edge_flag_enable(bm, e, oflag) _bmo_elem_flag_enable(bm, _BMO_CAST_E(e)->oflags, oflag)
+#define BMO_edge_flag_disable(bm, e, oflag) \
+ _bmo_elem_flag_disable(bm, _BMO_CAST_E(e)->oflags, oflag)
+#define BMO_edge_flag_set(bm, e, oflag, val) \
+ _bmo_elem_flag_set(bm, _BMO_CAST_E(e)->oflags, oflag, val)
+#define BMO_edge_flag_toggle(bm, e, oflag) _bmo_elem_flag_toggle(bm, _BMO_CAST_E(e)->oflags, oflag)
+
+#define BMO_face_flag_test(bm, e, oflag) \
+ _bmo_elem_flag_test(bm, _BMO_CAST_F_CONST(e)->oflags, oflag)
+#define BMO_face_flag_test_bool(bm, e, oflag) \
+ _bmo_elem_flag_test_bool(bm, _BMO_CAST_F_CONST(e)->oflags, oflag)
+#define BMO_face_flag_enable(bm, e, oflag) _bmo_elem_flag_enable(bm, _BMO_CAST_F(e)->oflags, oflag)
+#define BMO_face_flag_disable(bm, e, oflag) \
+ _bmo_elem_flag_disable(bm, _BMO_CAST_F(e)->oflags, oflag)
+#define BMO_face_flag_set(bm, e, oflag, val) \
+ _bmo_elem_flag_set(bm, _BMO_CAST_F(e)->oflags, oflag, val)
+#define BMO_face_flag_toggle(bm, e, oflag) _bmo_elem_flag_toggle(bm, _BMO_CAST_F(e)->oflags, oflag)
+
+BLI_INLINE short _bmo_elem_flag_test(BMesh *bm, const BMFlagLayer *oflags, const short oflag);
+BLI_INLINE bool _bmo_elem_flag_test_bool(BMesh *bm, const BMFlagLayer *oflags, const short oflag);
+BLI_INLINE void _bmo_elem_flag_enable(BMesh *bm, BMFlagLayer *oflags, const short oflag);
+BLI_INLINE void _bmo_elem_flag_disable(BMesh *bm, BMFlagLayer *oflags, const short oflag);
+BLI_INLINE void _bmo_elem_flag_set(BMesh *bm, BMFlagLayer *oflags, const short oflag, int val);
+BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const short oflag);
/* slot type arrays are terminated by the last member
* having a slot type of 0 */
typedef enum eBMOpSlotType {
- /* BMO_OP_SLOT_SENTINEL = 0, */
- BMO_OP_SLOT_BOOL = 1,
- BMO_OP_SLOT_INT = 2,
- BMO_OP_SLOT_FLT = 3,
-
- /* normally store pointers to object, scene,
- * _never_ store arrays corresponding to mesh elements with this */
- BMO_OP_SLOT_PTR = 4, /* requres subtype BMO_OP_SLOT_SUBTYPE_PTR_xxx */
- BMO_OP_SLOT_MAT = 5,
- BMO_OP_SLOT_VEC = 8,
-
- /* after BMO_OP_SLOT_VEC, everything is dynamically allocated arrays.
- * We leave a space in the identifiers for future growth.
- *
- * it's very important this remain a power of two */
- BMO_OP_SLOT_ELEMENT_BUF = 9, /* list of verts/edges/faces */
- BMO_OP_SLOT_MAPPING = 10 /* simple hash map, requres subtype BMO_OP_SLOT_SUBTYPE_MAP_xxx */
+ /* BMO_OP_SLOT_SENTINEL = 0, */
+ BMO_OP_SLOT_BOOL = 1,
+ BMO_OP_SLOT_INT = 2,
+ BMO_OP_SLOT_FLT = 3,
+
+ /* normally store pointers to object, scene,
+ * _never_ store arrays corresponding to mesh elements with this */
+ BMO_OP_SLOT_PTR = 4, /* requres subtype BMO_OP_SLOT_SUBTYPE_PTR_xxx */
+ BMO_OP_SLOT_MAT = 5,
+ BMO_OP_SLOT_VEC = 8,
+
+ /* after BMO_OP_SLOT_VEC, everything is dynamically allocated arrays.
+ * We leave a space in the identifiers for future growth.
+ *
+ * it's very important this remain a power of two */
+ BMO_OP_SLOT_ELEMENT_BUF = 9, /* list of verts/edges/faces */
+ BMO_OP_SLOT_MAPPING = 10 /* simple hash map, requres subtype BMO_OP_SLOT_SUBTYPE_MAP_xxx */
} eBMOpSlotType;
#define BMO_OP_SLOT_TOTAL_TYPES 11
/* don't overlap values to avoid confusion */
typedef enum eBMOpSlotSubType_Elem {
- /* use as flags */
- BMO_OP_SLOT_SUBTYPE_ELEM_VERT = BM_VERT,
- BMO_OP_SLOT_SUBTYPE_ELEM_EDGE = BM_EDGE,
- BMO_OP_SLOT_SUBTYPE_ELEM_FACE = BM_FACE,
- BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE = (BM_FACE << 1),
+ /* use as flags */
+ BMO_OP_SLOT_SUBTYPE_ELEM_VERT = BM_VERT,
+ BMO_OP_SLOT_SUBTYPE_ELEM_EDGE = BM_EDGE,
+ BMO_OP_SLOT_SUBTYPE_ELEM_FACE = BM_FACE,
+ BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE = (BM_FACE << 1),
} eBMOpSlotSubType_Elem;
typedef enum eBMOpSlotSubType_Map {
- BMO_OP_SLOT_SUBTYPE_MAP_EMPTY = 64, /* use as a set(), unused value */
- BMO_OP_SLOT_SUBTYPE_MAP_ELEM = 65,
- BMO_OP_SLOT_SUBTYPE_MAP_FLT = 66,
- BMO_OP_SLOT_SUBTYPE_MAP_INT = 67,
- BMO_OP_SLOT_SUBTYPE_MAP_BOOL = 68,
- BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL = 69, /* python can't convert these */
+ BMO_OP_SLOT_SUBTYPE_MAP_EMPTY = 64, /* use as a set(), unused value */
+ BMO_OP_SLOT_SUBTYPE_MAP_ELEM = 65,
+ BMO_OP_SLOT_SUBTYPE_MAP_FLT = 66,
+ BMO_OP_SLOT_SUBTYPE_MAP_INT = 67,
+ BMO_OP_SLOT_SUBTYPE_MAP_BOOL = 68,
+ BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL = 69, /* python can't convert these */
} eBMOpSlotSubType_Map;
typedef enum eBMOpSlotSubType_Ptr {
- BMO_OP_SLOT_SUBTYPE_PTR_BMESH = 100,
- BMO_OP_SLOT_SUBTYPE_PTR_SCENE = 101,
- BMO_OP_SLOT_SUBTYPE_PTR_OBJECT = 102,
- BMO_OP_SLOT_SUBTYPE_PTR_MESH = 103,
+ BMO_OP_SLOT_SUBTYPE_PTR_BMESH = 100,
+ BMO_OP_SLOT_SUBTYPE_PTR_SCENE = 101,
+ BMO_OP_SLOT_SUBTYPE_PTR_OBJECT = 102,
+ BMO_OP_SLOT_SUBTYPE_PTR_MESH = 103,
} eBMOpSlotSubType_Ptr;
typedef enum eBMOpSlotSubType_Int {
- BMO_OP_SLOT_SUBTYPE_INT_ENUM = 200,
- BMO_OP_SLOT_SUBTYPE_INT_FLAG = 201,
+ BMO_OP_SLOT_SUBTYPE_INT_ENUM = 200,
+ BMO_OP_SLOT_SUBTYPE_INT_FLAG = 201,
} eBMOpSlotSubType_Int;
typedef union eBMOpSlotSubType_Union {
- eBMOpSlotSubType_Elem elem;
- eBMOpSlotSubType_Ptr ptr;
- eBMOpSlotSubType_Map map;
- eBMOpSlotSubType_Int intg;
+ eBMOpSlotSubType_Elem elem;
+ eBMOpSlotSubType_Ptr ptr;
+ eBMOpSlotSubType_Map map;
+ eBMOpSlotSubType_Int intg;
} eBMOpSlotSubType_Union;
typedef struct BMO_FlagSet {
- int value;
- const char *identifier;
+ int value;
+ const char *identifier;
} BMO_FlagSet;
/* please ignore all these structures, don't touch them in tool code, except
* for when your defining an operator with BMOpDefine.*/
typedef struct BMOpSlot {
- const char *slot_name; /* pointer to BMOpDefine.slot_args */
- eBMOpSlotType slot_type;
- eBMOpSlotSubType_Union slot_subtype;
-
- int len;
-// int flag; /* UNUSED */
-// int index; /* index within slot array */ /* UNUSED */
- union {
- int i;
- float f;
- void *p;
- float vec[3];
- void **buf;
- GHash *ghash;
- struct {
- /** Don't clobber (i) when assigning flags, see #eBMOpSlotSubType_Int. */
- int _i;
- BMO_FlagSet *flags;
- } enum_data;
- } data;
+ const char *slot_name; /* pointer to BMOpDefine.slot_args */
+ eBMOpSlotType slot_type;
+ eBMOpSlotSubType_Union slot_subtype;
+
+ int len;
+ // int flag; /* UNUSED */
+ // int index; /* index within slot array */ /* UNUSED */
+ union {
+ int i;
+ float f;
+ void *p;
+ float vec[3];
+ void **buf;
+ GHash *ghash;
+ struct {
+ /** Don't clobber (i) when assigning flags, see #eBMOpSlotSubType_Int. */
+ int _i;
+ BMO_FlagSet *flags;
+ } enum_data;
+ } data;
} BMOpSlot;
/* mainly for use outside bmesh internal code */
-#define BMO_SLOT_AS_BOOL(slot) ((slot)->data.i)
-#define BMO_SLOT_AS_INT(slot) ((slot)->data.i)
-#define BMO_SLOT_AS_FLOAT(slot) ((slot)->data.f)
-#define BMO_SLOT_AS_VECTOR(slot) ((slot)->data.vec)
-#define BMO_SLOT_AS_MATRIX(slot ) ((float (*)[4])((slot)->data.p))
-#define BMO_SLOT_AS_BUFFER(slot ) ((slot)->data.buf)
-#define BMO_SLOT_AS_GHASH(slot ) ((slot)->data.ghash)
+#define BMO_SLOT_AS_BOOL(slot) ((slot)->data.i)
+#define BMO_SLOT_AS_INT(slot) ((slot)->data.i)
+#define BMO_SLOT_AS_FLOAT(slot) ((slot)->data.f)
+#define BMO_SLOT_AS_VECTOR(slot) ((slot)->data.vec)
+#define BMO_SLOT_AS_MATRIX(slot) ((float(*)[4])((slot)->data.p))
+#define BMO_SLOT_AS_BUFFER(slot) ((slot)->data.buf)
+#define BMO_SLOT_AS_GHASH(slot) ((slot)->data.ghash)
#define BMO_ASSERT_SLOT_IN_OP(slot, op) \
- BLI_assert(((slot >= (op)->slots_in) && (slot < &(op)->slots_in[BMO_OP_MAX_SLOTS])) || \
- ((slot >= (op)->slots_out) && (slot < &(op)->slots_out[BMO_OP_MAX_SLOTS])))
+ BLI_assert(((slot >= (op)->slots_in) && (slot < &(op)->slots_in[BMO_OP_MAX_SLOTS])) || \
+ ((slot >= (op)->slots_out) && (slot < &(op)->slots_out[BMO_OP_MAX_SLOTS])))
/* way more than probably needed, compiler complains if limit hit */
#define BMO_OP_MAX_SLOTS 20
/* BMOpDefine->type_flag */
typedef enum {
- BMO_OPTYPE_FLAG_NOP = 0,
- BMO_OPTYPE_FLAG_UNTAN_MULTIRES = (1 << 0), /* switch from multires tangent space to absolute coordinates */
- BMO_OPTYPE_FLAG_NORMALS_CALC = (1 << 1),
- BMO_OPTYPE_FLAG_SELECT_FLUSH = (1 << 2),
- BMO_OPTYPE_FLAG_SELECT_VALIDATE = (1 << 3),
- BMO_OPTYPE_FLAG_INVALIDATE_CLNOR_ALL = (1 << 4),
+ BMO_OPTYPE_FLAG_NOP = 0,
+ BMO_OPTYPE_FLAG_UNTAN_MULTIRES =
+ (1 << 0), /* switch from multires tangent space to absolute coordinates */
+ BMO_OPTYPE_FLAG_NORMALS_CALC = (1 << 1),
+ BMO_OPTYPE_FLAG_SELECT_FLUSH = (1 << 2),
+ BMO_OPTYPE_FLAG_SELECT_VALIDATE = (1 << 3),
+ BMO_OPTYPE_FLAG_INVALIDATE_CLNOR_ALL = (1 << 4),
} BMOpTypeFlag;
typedef struct BMOperator {
- struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS];
- struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS];
- void (*exec)(BMesh *bm, struct BMOperator *op);
- struct MemArena *arena;
- int type;
- BMOpTypeFlag type_flag;
- int flag; /* runtime options */
+ struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS];
+ struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS];
+ void (*exec)(BMesh *bm, struct BMOperator *op);
+ struct MemArena *arena;
+ int type;
+ BMOpTypeFlag type_flag;
+ int flag; /* runtime options */
} BMOperator;
enum {
- BMO_FLAG_RESPECT_HIDE = 1,
+ BMO_FLAG_RESPECT_HIDE = 1,
};
-#define BMO_FLAG_DEFAULTS BMO_FLAG_RESPECT_HIDE
+#define BMO_FLAG_DEFAULTS BMO_FLAG_RESPECT_HIDE
-#define MAX_SLOTNAME 32
+#define MAX_SLOTNAME 32
typedef struct BMOSlotType {
- char name[MAX_SLOTNAME];
- eBMOpSlotType type;
- eBMOpSlotSubType_Union subtype;
- BMO_FlagSet *enum_flags;
+ char name[MAX_SLOTNAME];
+ eBMOpSlotType type;
+ eBMOpSlotSubType_Union subtype;
+ BMO_FlagSet *enum_flags;
} BMOSlotType;
typedef struct BMOpDefine {
- const char *opname;
- BMOSlotType slot_types_in[BMO_OP_MAX_SLOTS];
- BMOSlotType slot_types_out[BMO_OP_MAX_SLOTS];
- void (*exec)(BMesh *bm, BMOperator *op);
- BMOpTypeFlag type_flag;
+ const char *opname;
+ BMOSlotType slot_types_in[BMO_OP_MAX_SLOTS];
+ BMOSlotType slot_types_out[BMO_OP_MAX_SLOTS];
+ void (*exec)(BMesh *bm, BMOperator *op);
+ BMOpTypeFlag type_flag;
} BMOpDefine;
/*------------- Operator API --------------*/
@@ -337,177 +389,205 @@ BMOpSlot *BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identif
/* copies the data of a slot from one operator to another. src and dst are the
* source/destination slot codes, respectively. */
-#define BMO_slot_copy(op_src, slots_src, slot_name_src, \
- op_dst, slots_dst, slot_name_dst) \
- _bmo_slot_copy((op_src)->slots_src, slot_name_src, \
- (op_dst)->slots_dst, slot_name_dst, \
- (op_dst)->arena)
+#define BMO_slot_copy(op_src, slots_src, slot_name_src, op_dst, slots_dst, slot_name_dst) \
+ _bmo_slot_copy( \
+ (op_src)->slots_src, slot_name_src, (op_dst)->slots_dst, slot_name_dst, (op_dst)->arena)
-void _bmo_slot_copy(
- BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_name_src,
- BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const char *slot_name_dst,
- struct MemArena *arena_dst);
+void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS],
+ const char *slot_name_src,
+ BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS],
+ const char *slot_name_dst,
+ struct MemArena *arena_dst);
/* del "context" slot values, used for operator too */
enum {
- DEL_VERTS = 1,
- DEL_EDGES,
- DEL_ONLYFACES,
- DEL_EDGESFACES,
- DEL_FACES,
- /* A version of 'DEL_FACES' that keeps edges on face boundaries,
- * allowing the surrounding edge-loop to be kept from removed face regions. */
- DEL_FACES_KEEP_BOUNDARY,
- DEL_ONLYTAGGED,
+ DEL_VERTS = 1,
+ DEL_EDGES,
+ DEL_ONLYFACES,
+ DEL_EDGESFACES,
+ DEL_FACES,
+ /* A version of 'DEL_FACES' that keeps edges on face boundaries,
+ * allowing the surrounding edge-loop to be kept from removed face regions. */
+ DEL_FACES_KEEP_BOUNDARY,
+ DEL_ONLYTAGGED,
};
typedef enum {
- BMO_SYMMETRIZE_NEGATIVE_X,
- BMO_SYMMETRIZE_NEGATIVE_Y,
- BMO_SYMMETRIZE_NEGATIVE_Z,
+ BMO_SYMMETRIZE_NEGATIVE_X,
+ BMO_SYMMETRIZE_NEGATIVE_Y,
+ BMO_SYMMETRIZE_NEGATIVE_Z,
- BMO_SYMMETRIZE_POSITIVE_X,
- BMO_SYMMETRIZE_POSITIVE_Y,
- BMO_SYMMETRIZE_POSITIVE_Z,
+ BMO_SYMMETRIZE_POSITIVE_X,
+ BMO_SYMMETRIZE_POSITIVE_Y,
+ BMO_SYMMETRIZE_POSITIVE_Z,
} BMO_SymmDirection;
typedef enum {
- BMO_DELIM_NORMAL = 1 << 0,
- BMO_DELIM_MATERIAL = 1 << 1,
- BMO_DELIM_SEAM = 1 << 2,
- BMO_DELIM_SHARP = 1 << 3,
- BMO_DELIM_UV = 1 << 4,
+ BMO_DELIM_NORMAL = 1 << 0,
+ BMO_DELIM_MATERIAL = 1 << 1,
+ BMO_DELIM_SEAM = 1 << 2,
+ BMO_DELIM_SHARP = 1 << 3,
+ BMO_DELIM_UV = 1 << 4,
} BMO_Delimit;
void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag);
void BMO_op_flag_disable(BMesh *bm, BMOperator *op, const int op_flag);
-void BMO_slot_float_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float f);
+void BMO_slot_float_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const float f);
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
-void BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i);
-int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
-void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const bool i);
-bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
+void BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i);
+int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
+void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const bool i);
+bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
void *BMO_slot_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int *len);
-
/* don't pass in arrays that are supposed to map to elements this way.
*
* so, e.g. passing in list of floats per element in another slot is bad.
* passing in, e.g. pointer to an editmesh for the conversion operator is fine
* though. */
-void BMO_slot_ptr_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, void *p);
+void BMO_slot_ptr_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, void *p);
void *BMO_slot_ptr_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
-void BMO_slot_vec_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float vec[3]);
-void BMO_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_vec[3]);
+void BMO_slot_vec_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const float vec[3]);
+void BMO_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_vec[3]);
/* only supports square mats */
/* size must be 3 or 4; this api is meant only for transformation matrices.
* note that internally the matrix is stored in 4x4 form, and it's safe to
* call whichever BMO_Get_MatXXX function you want. */
-void BMO_slot_mat_set(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float *mat, int size);
-void BMO_slot_mat4_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[4][4]);
-void BMO_slot_mat3_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[3][3]);
+void BMO_slot_mat_set(BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const float *mat,
+ int size);
+void BMO_slot_mat4_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ float r_mat[4][4]);
+void BMO_slot_mat3_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ float r_mat[3][3]);
void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *op, const char htype, const short oflag);
-void BMO_mesh_selected_remap(
- BMesh *bm,
- BMOpSlot *slot_vert_map,
- BMOpSlot *slot_edge_map,
- BMOpSlot *slot_face_map,
- const bool check_select);
+void BMO_mesh_selected_remap(BMesh *bm,
+ BMOpSlot *slot_vert_map,
+ BMOpSlot *slot_edge_map,
+ BMOpSlot *slot_face_map,
+ const bool check_select);
/* copies the values from another slot to the end of the output slot */
-#define BMO_slot_buffer_append(op_src, slots_src, slot_name_src, \
- op_dst, slots_dst, slot_name_dst) \
- _bmo_slot_buffer_append((op_src)->slots_src, slot_name_src, \
- (op_dst)->slots_dst, slot_name_dst, \
- (op_dst)->arena)
-void _bmo_slot_buffer_append(
- BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const char *slot_name_dst,
- BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_name_src,
- struct MemArena *arena_dst);
+#define BMO_slot_buffer_append( \
+ op_src, slots_src, slot_name_src, op_dst, slots_dst, slot_name_dst) \
+ _bmo_slot_buffer_append( \
+ (op_src)->slots_src, slot_name_src, (op_dst)->slots_dst, slot_name_dst, (op_dst)->arena)
+void _bmo_slot_buffer_append(BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS],
+ const char *slot_name_dst,
+ BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS],
+ const char *slot_name_src,
+ struct MemArena *arena_dst);
/* puts every element of type 'type' (which is a bitmask) with tool
* flag 'flag', into a slot. */
-void BMO_slot_buffer_from_enabled_flag(
- BMesh *bm, BMOperator *op,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const short oflag);
+void BMO_slot_buffer_from_enabled_flag(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const short oflag);
/* puts every element of type 'type' (which is a bitmask) without tool
* flag 'flag', into a slot. */
-void BMO_slot_buffer_from_disabled_flag(
- BMesh *bm, BMOperator *op,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const short oflag);
+void BMO_slot_buffer_from_disabled_flag(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const short oflag);
/* tool-flags all elements inside an element slot array with flag flag. */
-void BMO_slot_buffer_flag_enable(
- BMesh *bm,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const short oflag);
+void BMO_slot_buffer_flag_enable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const short oflag);
/* clears tool-flag flag from all elements inside a slot array. */
-void BMO_slot_buffer_flag_disable(
- BMesh *bm,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const short oflag);
+void BMO_slot_buffer_flag_disable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const short oflag);
/* tool-flags all elements inside an element slot array with flag flag. */
-void BMO_slot_buffer_hflag_enable(
- BMesh *bm,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag, const bool do_flush);
+void BMO_slot_buffer_hflag_enable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const char hflag,
+ const bool do_flush);
/* clears tool-flag flag from all elements inside a slot array. */
-void BMO_slot_buffer_hflag_disable(
- BMesh *bm,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag, const bool do_flush);
+void BMO_slot_buffer_hflag_disable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const char hflag,
+ const bool do_flush);
/* puts every element of type 'type' (which is a bitmask) with header
* flag 'flag', into a slot. note: ignores hidden elements
* (e.g. elements with header flag BM_ELEM_HIDDEN set).*/
-void BMO_slot_buffer_from_enabled_hflag(
- BMesh *bm, BMOperator *op,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag);
+void BMO_slot_buffer_from_enabled_hflag(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const char hflag);
/* puts every element of type 'type' (which is a bitmask) without
* header flag 'flag', into a slot. note: ignores hidden elements
* (e.g. elements with header flag BM_ELEM_HIDDEN set).*/
-void BMO_slot_buffer_from_disabled_hflag(
- BMesh *bm, BMOperator *op,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag);
-
-void BMO_slot_buffer_from_array(BMOperator *op, BMOpSlot *slot, BMHeader **ele_buffer, int ele_buffer_len);
-
-void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele);
+void BMO_slot_buffer_from_disabled_hflag(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const char hflag);
+
+void BMO_slot_buffer_from_array(BMOperator *op,
+ BMOpSlot *slot,
+ BMHeader **ele_buffer,
+ int ele_buffer_len);
+
+void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele);
void *BMO_slot_buffer_get_single(BMOpSlot *slot);
-
/* counts number of elements inside a slot array. */
int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name);
-void BMO_slot_map_insert(
- BMOperator *op, BMOpSlot *slot,
- const void *element, const void *data);
+void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot, const void *element, const void *data);
/* flags all elements in a mapping. note that the mapping must only have
* bmesh elements in it.*/
-void BMO_slot_map_to_flag(
- BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
- const char *slot_name, const char hflag, const short oflag);
-
-void *BMO_slot_buffer_alloc(
- BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
- const char *slot_name, const int len);
-
-void BMO_slot_buffer_from_all(
- BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
- const char *slot_name, const char htype);
+void BMO_slot_map_to_flag(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char hflag,
+ const short oflag);
+
+void *BMO_slot_buffer_alloc(BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const int len);
+
+void BMO_slot_buffer_from_all(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype);
/**
* This part of the API is used to iterate over element buffer or
@@ -547,37 +627,38 @@ void BMO_slot_buffer_from_all(
/* contents of this structure are private,
* don't directly access. */
typedef struct BMOIter {
- BMOpSlot *slot;
- int cur; //for arrays
- GHashIterator giter;
- void **val;
- char restrictmask; /* bitwise '&' with BMHeader.htype */
+ BMOpSlot *slot;
+ int cur; //for arrays
+ GHashIterator giter;
+ void **val;
+ char restrictmask; /* bitwise '&' with BMHeader.htype */
} BMOIter;
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,
- const char restrictmask);
+void *BMO_iter_new(BMOIter *iter,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char restrictmask);
void *BMO_iter_step(BMOIter *iter);
void **BMO_iter_map_value_p(BMOIter *iter);
-void *BMO_iter_map_value_ptr(BMOIter *iter);
+void *BMO_iter_map_value_ptr(BMOIter *iter);
float BMO_iter_map_value_float(BMOIter *iter);
-int BMO_iter_map_value_int(BMOIter *iter);
-bool BMO_iter_map_value_bool(BMOIter *iter);
-
-#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag) \
- for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_new(iter, slot_args, slot_name, restrict_flag); \
- ele; \
- BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_step(iter))
-
-#define BMO_ITER_INDEX(ele, iter, slot_args, slot_name, restrict_flag, i_) \
- for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_new(iter, slot_args, slot_name, restrict_flag), i_ = 0; \
- ele; \
- BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_step(iter), i_++)
+int BMO_iter_map_value_int(BMOIter *iter);
+bool BMO_iter_map_value_bool(BMOIter *iter);
+
+#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag) \
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_new(iter, slot_args, slot_name, restrict_flag); \
+ ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_step(iter))
+
+#define BMO_ITER_INDEX(ele, iter, slot_args, slot_name, restrict_flag, i_) \
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_new(iter, slot_args, slot_name, restrict_flag), \
+ i_ = 0; \
+ ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMO_iter_step(iter), i_++)
extern const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES];
diff --git a/source/blender/bmesh/intern/bmesh_operator_api_inline.h b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
index 78e75cf3d30..2bda2d121c2 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api_inline.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api_inline.h
@@ -32,195 +32,209 @@
* ghash or a mapping slot to do it. */
/* flags 15 and 16 (1 << 14 and 1 << 15) are reserved for bmesh api use */
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
-BLI_INLINE short _bmo_elem_flag_test(BMesh *bm, const BMFlagLayer *oflags, const short oflag)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE
+ short _bmo_elem_flag_test(BMesh *bm, const BMFlagLayer *oflags, const short oflag)
{
- BLI_assert(bm->use_toolflags);
- return oflags[bm->toolflag_index].f & oflag;
+ BLI_assert(bm->use_toolflags);
+ return oflags[bm->toolflag_index].f & oflag;
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
-BLI_INLINE bool _bmo_elem_flag_test_bool(BMesh *bm, const BMFlagLayer *oflags, const short oflag)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE
+ bool _bmo_elem_flag_test_bool(BMesh *bm, const BMFlagLayer *oflags, const short oflag)
{
- BLI_assert(bm->use_toolflags);
- return (oflags[bm->toolflag_index].f & oflag) != 0;
+ BLI_assert(bm->use_toolflags);
+ return (oflags[bm->toolflag_index].f & oflag) != 0;
}
ATTR_NONNULL(1, 2)
BLI_INLINE void _bmo_elem_flag_enable(BMesh *bm, BMFlagLayer *oflags, const short oflag)
{
- BLI_assert(bm->use_toolflags);
- oflags[bm->toolflag_index].f |= oflag;
+ BLI_assert(bm->use_toolflags);
+ oflags[bm->toolflag_index].f |= oflag;
}
ATTR_NONNULL(1, 2)
BLI_INLINE void _bmo_elem_flag_disable(BMesh *bm, BMFlagLayer *oflags, const short oflag)
{
- BLI_assert(bm->use_toolflags);
- oflags[bm->toolflag_index].f &= (short)~oflag;
+ BLI_assert(bm->use_toolflags);
+ oflags[bm->toolflag_index].f &= (short)~oflag;
}
ATTR_NONNULL(1, 2)
BLI_INLINE void _bmo_elem_flag_set(BMesh *bm, BMFlagLayer *oflags, const short oflag, int val)
{
- BLI_assert(bm->use_toolflags);
- if (val) { oflags[bm->toolflag_index].f |= oflag; }
- else { oflags[bm->toolflag_index].f &= (short)~oflag; }
+ BLI_assert(bm->use_toolflags);
+ if (val) {
+ oflags[bm->toolflag_index].f |= oflag;
+ }
+ else {
+ oflags[bm->toolflag_index].f &= (short)~oflag;
+ }
}
ATTR_NONNULL(1, 2)
BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const short oflag)
{
- BLI_assert(bm->use_toolflags);
- oflags[bm->toolflag_index].f ^= oflag;
+ BLI_assert(bm->use_toolflags);
+ oflags[bm->toolflag_index].f ^= oflag;
}
ATTR_NONNULL(1, 2)
-BLI_INLINE void BMO_slot_map_int_insert(
- BMOperator *op, BMOpSlot *slot,
- void *element, const int val)
+BLI_INLINE void BMO_slot_map_int_insert(BMOperator *op,
+ BMOpSlot *slot,
+ void *element,
+ const int val)
{
- union { void *ptr; int val; } t = {NULL};
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
- BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
+ union {
+ void *ptr;
+ int val;
+ } t = {NULL};
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
+ BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
}
ATTR_NONNULL(1, 2)
-BLI_INLINE void BMO_slot_map_bool_insert(
- BMOperator *op, BMOpSlot *slot,
- void *element, const bool val)
+BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op,
+ BMOpSlot *slot,
+ void *element,
+ const bool val)
{
- union { void *ptr; bool val; } t = {NULL};
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
- BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
+ union {
+ void *ptr;
+ bool val;
+ } t = {NULL};
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
+ BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
}
ATTR_NONNULL(1, 2)
-BLI_INLINE void BMO_slot_map_float_insert(
- BMOperator *op, BMOpSlot *slot,
- void *element, const float val)
+BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op,
+ BMOpSlot *slot,
+ void *element,
+ const float val)
{
- union { void *ptr; float val; } t = {NULL};
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
- BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
+ union {
+ void *ptr;
+ float val;
+ } t = {NULL};
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
+ BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
}
-
/* pointer versions of BMO_slot_map_float_get and BMO_slot_map_float_insert.
*
* do NOT use these for non-operator-api-allocated memory! instead
* use BMO_slot_map_data_get and BMO_slot_map_insert, which copies the data. */
ATTR_NONNULL(1, 2)
-BLI_INLINE void BMO_slot_map_ptr_insert(
- BMOperator *op, BMOpSlot *slot,
- const void *element, void *val)
+BLI_INLINE void BMO_slot_map_ptr_insert(BMOperator *op,
+ BMOpSlot *slot,
+ const void *element,
+ void *val)
{
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
- BMO_slot_map_insert(op, slot, element, val);
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
+ BMO_slot_map_insert(op, slot, element, val);
}
ATTR_NONNULL(1, 2)
-BLI_INLINE void BMO_slot_map_elem_insert(
- BMOperator *op, BMOpSlot *slot,
- const void *element, void *val)
+BLI_INLINE void BMO_slot_map_elem_insert(BMOperator *op,
+ BMOpSlot *slot,
+ const void *element,
+ void *val)
{
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
- BMO_slot_map_insert(op, slot, element, val);
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
+ BMO_slot_map_insert(op, slot, element, val);
}
-
/* no values */
ATTR_NONNULL(1, 2)
-BLI_INLINE void BMO_slot_map_empty_insert(
- BMOperator *op, BMOpSlot *slot,
- const void *element)
+BLI_INLINE void BMO_slot_map_empty_insert(BMOperator *op, BMOpSlot *slot, const void *element)
{
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY);
- BMO_slot_map_insert(op, slot, element, NULL);
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY);
+ BMO_slot_map_insert(op, slot, element, NULL);
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE bool BMO_slot_map_contains(BMOpSlot *slot, const void *element)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
+ bool BMO_slot_map_contains(BMOpSlot *slot, const void *element)
{
- BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
- return BLI_ghash_haskey(slot->data.ghash, element);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
+ return BLI_ghash_haskey(slot->data.ghash, element);
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE void **BMO_slot_map_data_get(BMOpSlot *slot, const void *element)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
+ void **BMO_slot_map_data_get(BMOpSlot *slot, const void *element)
{
- return BLI_ghash_lookup_p(slot->data.ghash, element);
+ return BLI_ghash_lookup_p(slot->data.ghash, element);
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
+ float BMO_slot_map_float_get(BMOpSlot *slot, const void *element)
{
- void **data;
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
+ void **data;
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
- data = BMO_slot_map_data_get(slot, element);
- if (data) {
- return *(float *)data;
- }
- else {
- return 0.0f;
- }
+ data = BMO_slot_map_data_get(slot, element);
+ if (data) {
+ return *(float *)data;
+ }
+ else {
+ return 0.0f;
+ }
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
+ int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
{
- void **data;
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
+ void **data;
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
- data = BMO_slot_map_data_get(slot, element);
- if (data) {
- return *(int *)data;
- }
- else {
- return 0;
- }
+ data = BMO_slot_map_data_get(slot, element);
+ if (data) {
+ return *(int *)data;
+ }
+ else {
+ return 0;
+ }
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE bool BMO_slot_map_bool_get(BMOpSlot *slot, const void *element)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
+ bool BMO_slot_map_bool_get(BMOpSlot *slot, const void *element)
{
- void **data;
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
+ void **data;
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
- data = BMO_slot_map_data_get(slot, element);
- if (data) {
- return *(bool *)data;
- }
- else {
- return false;
- }
+ data = BMO_slot_map_data_get(slot, element);
+ if (data) {
+ return *(bool *)data;
+ }
+ else {
+ return false;
+ }
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
+ void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element)
{
- void **val = BMO_slot_map_data_get(slot, element);
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
- if (val) {
- return *val;
- }
+ void **val = BMO_slot_map_data_get(slot, element);
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
+ if (val) {
+ return *val;
+ }
- return NULL;
+ return NULL;
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE void *BMO_slot_map_elem_get(BMOpSlot *slot, const void *element)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
+ void *BMO_slot_map_elem_get(BMOpSlot *slot, const void *element)
{
- void **val = (void **) BMO_slot_map_data_get(slot, element);
- BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
- if (val) {
- return *val;
- }
+ void **val = (void **)BMO_slot_map_data_get(slot, element);
+ BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
+ if (val) {
+ return *val;
+ }
- return NULL;
+ return NULL;
}
#endif /* __BMESH_OPERATOR_API_INLINE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index fb6edbecaed..a7783084c01 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -39,36 +39,37 @@ static void bmo_flag_layer_alloc(BMesh *bm);
static void bmo_flag_layer_free(BMesh *bm);
static void bmo_flag_layer_clear(BMesh *bm);
static int bmo_name_to_slotcode(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
-static int bmo_name_to_slotcode_check(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier);
+static int bmo_name_to_slotcode_check(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *identifier);
static const char *bmo_error_messages[] = {
- NULL,
- N_("Self intersection error"),
- N_("Could not dissolve vert"),
- N_("Could not connect vertices"),
- N_("Could not traverse mesh"),
- N_("Could not dissolve faces"),
- N_("Tessellation error"),
- N_("Cannot deal with non-manifold geometry"),
- N_("Invalid selection"),
- N_("Internal mesh error"),
+ NULL,
+ N_("Self intersection error"),
+ N_("Could not dissolve vert"),
+ N_("Could not connect vertices"),
+ N_("Could not traverse mesh"),
+ N_("Could not dissolve faces"),
+ N_("Tessellation error"),
+ N_("Cannot deal with non-manifold geometry"),
+ N_("Invalid selection"),
+ N_("Internal mesh error"),
};
BLI_STATIC_ASSERT(ARRAY_SIZE(bmo_error_messages) + 1 == BMERR_TOTAL, "message mismatch");
/* operator slot type information - size of one element of the type given. */
const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES] = {
- 0, /* 0: BMO_OP_SLOT_SENTINEL */
- sizeof(int), /* 1: BMO_OP_SLOT_BOOL */
- sizeof(int), /* 2: BMO_OP_SLOT_INT */
- sizeof(float), /* 3: BMO_OP_SLOT_FLT */
- sizeof(void *), /* 4: BMO_OP_SLOT_PNT */
- sizeof(void *), /* 5: BMO_OP_SLOT_PNT */
- 0, /* 6: unused */
- 0, /* 7: unused */
- sizeof(float) * 3, /* 8: BMO_OP_SLOT_VEC */
- sizeof(void *), /* 9: BMO_OP_SLOT_ELEMENT_BUF */
- sizeof(void *), /* 10: BMO_OP_SLOT_MAPPING */
+ 0, /* 0: BMO_OP_SLOT_SENTINEL */
+ sizeof(int), /* 1: BMO_OP_SLOT_BOOL */
+ sizeof(int), /* 2: BMO_OP_SLOT_INT */
+ sizeof(float), /* 3: BMO_OP_SLOT_FLT */
+ sizeof(void *), /* 4: BMO_OP_SLOT_PNT */
+ sizeof(void *), /* 5: BMO_OP_SLOT_PNT */
+ 0, /* 6: unused */
+ 0, /* 7: unused */
+ sizeof(float) * 3, /* 8: BMO_OP_SLOT_VEC */
+ sizeof(void *), /* 9: BMO_OP_SLOT_ELEMENT_BUF */
+ sizeof(void *), /* 10: BMO_OP_SLOT_MAPPING */
};
/* Dummy slot so there is something to return when slot name lookup fails */
@@ -76,12 +77,12 @@ const int BMO_OPSLOT_TYPEINFO[BMO_OP_SLOT_TOTAL_TYPES] = {
void BMO_op_flag_enable(BMesh *UNUSED(bm), BMOperator *op, const int op_flag)
{
- op->flag |= op_flag;
+ op->flag |= op_flag;
}
void BMO_op_flag_disable(BMesh *UNUSED(bm), BMOperator *op, const int op_flag)
{
- op->flag &= ~op_flag;
+ op->flag &= ~op_flag;
}
/**
@@ -91,17 +92,17 @@ void BMO_op_flag_disable(BMesh *UNUSED(bm), BMOperator *op, const int op_flag)
*/
void BMO_push(BMesh *bm, BMOperator *UNUSED(op))
{
- bm->toolflag_index++;
+ bm->toolflag_index++;
- BLI_assert(bm->totflags > 0);
+ BLI_assert(bm->totflags > 0);
- /* add flag layer, if appropriate */
- if (bm->toolflag_index > 0) {
- bmo_flag_layer_alloc(bm);
- }
- else {
- bmo_flag_layer_clear(bm);
- }
+ /* add flag layer, if appropriate */
+ if (bm->toolflag_index > 0) {
+ bmo_flag_layer_alloc(bm);
+ }
+ else {
+ bmo_flag_layer_clear(bm);
+ }
}
/**
@@ -113,54 +114,55 @@ void BMO_push(BMesh *bm, BMOperator *UNUSED(op))
*/
void BMO_pop(BMesh *bm)
{
- if (bm->toolflag_index > 0) {
- bmo_flag_layer_free(bm);
- }
+ if (bm->toolflag_index > 0) {
+ bmo_flag_layer_free(bm);
+ }
- bm->toolflag_index--;
+ bm->toolflag_index--;
}
-
/* use for both slot_types_in and slot_types_out */
static void bmo_op_slots_init(const BMOSlotType *slot_types, BMOpSlot *slot_args)
{
- BMOpSlot *slot;
- uint i;
- for (i = 0; slot_types[i].type; i++) {
- slot = &slot_args[i];
- slot->slot_name = slot_types[i].name;
- slot->slot_type = slot_types[i].type;
- slot->slot_subtype = slot_types[i].subtype;
- // slot->index = i; // UNUSED
-
- switch (slot->slot_type) {
- case BMO_OP_SLOT_MAPPING:
- slot->data.ghash = BLI_ghash_ptr_new("bmesh slot map hash");
- break;
- case BMO_OP_SLOT_INT:
- if (ELEM(slot->slot_subtype.intg, BMO_OP_SLOT_SUBTYPE_INT_ENUM, BMO_OP_SLOT_SUBTYPE_INT_FLAG)) {
- slot->data.enum_data.flags = slot_types[i].enum_flags;
- }
- default:
- break;
- }
- }
+ BMOpSlot *slot;
+ uint i;
+ for (i = 0; slot_types[i].type; i++) {
+ slot = &slot_args[i];
+ slot->slot_name = slot_types[i].name;
+ slot->slot_type = slot_types[i].type;
+ slot->slot_subtype = slot_types[i].subtype;
+ // slot->index = i; // UNUSED
+
+ switch (slot->slot_type) {
+ case BMO_OP_SLOT_MAPPING:
+ slot->data.ghash = BLI_ghash_ptr_new("bmesh slot map hash");
+ break;
+ case BMO_OP_SLOT_INT:
+ if (ELEM(slot->slot_subtype.intg,
+ BMO_OP_SLOT_SUBTYPE_INT_ENUM,
+ BMO_OP_SLOT_SUBTYPE_INT_FLAG)) {
+ slot->data.enum_data.flags = slot_types[i].enum_flags;
+ }
+ default:
+ break;
+ }
+ }
}
static void bmo_op_slots_free(const BMOSlotType *slot_types, BMOpSlot *slot_args)
{
- BMOpSlot *slot;
- uint i;
- for (i = 0; slot_types[i].type; i++) {
- slot = &slot_args[i];
- switch (slot->slot_type) {
- case BMO_OP_SLOT_MAPPING:
- BLI_ghash_free(slot->data.ghash, NULL, NULL);
- break;
- default:
- break;
- }
- }
+ BMOpSlot *slot;
+ uint i;
+ for (i = 0; slot_types[i].type; i++) {
+ slot = &slot_args[i];
+ switch (slot->slot_type) {
+ case BMO_OP_SLOT_MAPPING:
+ BLI_ghash_free(slot->data.ghash, NULL, NULL);
+ break;
+ default:
+ break;
+ }
+ }
}
/**
@@ -170,33 +172,33 @@ static void bmo_op_slots_free(const BMOSlotType *slot_types, BMOpSlot *slot_args
*/
void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
{
- int opcode = BMO_opcode_from_opname(opname);
+ int opcode = BMO_opcode_from_opname(opname);
#ifdef DEBUG
- BM_ELEM_INDEX_VALIDATE(bm, "pre bmo", opname);
+ BM_ELEM_INDEX_VALIDATE(bm, "pre bmo", opname);
#else
- (void)bm;
+ (void)bm;
#endif
- if (opcode == -1) {
- opcode = 0; /* error!, already printed, have a better way to handle this? */
- }
+ if (opcode == -1) {
+ opcode = 0; /* error!, already printed, have a better way to handle this? */
+ }
- memset(op, 0, sizeof(BMOperator));
- op->type = opcode;
- op->type_flag = bmo_opdefines[opcode]->type_flag;
- op->flag = flag;
+ memset(op, 0, sizeof(BMOperator));
+ op->type = opcode;
+ op->type_flag = bmo_opdefines[opcode]->type_flag;
+ op->flag = flag;
- /* initialize the operator slot types */
- bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_in, op->slots_in);
- bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_out, op->slots_out);
+ /* initialize the operator slot types */
+ bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_in, op->slots_in);
+ bmo_op_slots_init(bmo_opdefines[opcode]->slot_types_out, op->slots_out);
- /* callback */
- op->exec = bmo_opdefines[opcode]->exec;
+ /* callback */
+ op->exec = bmo_opdefines[opcode]->exec;
- /* memarena, used for operator's slot buffers */
- op->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
- BLI_memarena_use_calloc(op->arena);
+ /* memarena, used for operator's slot buffers */
+ op->arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ BLI_memarena_use_calloc(op->arena);
}
/**
@@ -210,21 +212,21 @@ void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
*/
void BMO_op_exec(BMesh *bm, BMOperator *op)
{
- /* allocate tool flags on demand */
- BM_mesh_elem_toolflags_ensure(bm);
+ /* allocate tool flags on demand */
+ BM_mesh_elem_toolflags_ensure(bm);
- BMO_push(bm, op);
+ BMO_push(bm, op);
- if (bm->toolflag_index == 1) {
- bmesh_edit_begin(bm, op->type_flag);
- }
- op->exec(bm, op);
+ if (bm->toolflag_index == 1) {
+ bmesh_edit_begin(bm, op->type_flag);
+ }
+ op->exec(bm, op);
- if (bm->toolflag_index == 1) {
- bmesh_edit_end(bm, op->type_flag);
- }
+ if (bm->toolflag_index == 1) {
+ bmesh_edit_end(bm, op->type_flag);
+ }
- BMO_pop(bm);
+ BMO_pop(bm);
}
/**
@@ -234,18 +236,18 @@ void BMO_op_exec(BMesh *bm, BMOperator *op)
*/
void BMO_op_finish(BMesh *bm, BMOperator *op)
{
- bmo_op_slots_free(bmo_opdefines[op->type]->slot_types_in, op->slots_in);
- bmo_op_slots_free(bmo_opdefines[op->type]->slot_types_out, op->slots_out);
+ bmo_op_slots_free(bmo_opdefines[op->type]->slot_types_in, op->slots_in);
+ bmo_op_slots_free(bmo_opdefines[op->type]->slot_types_out, op->slots_out);
- BLI_memarena_free(op->arena);
+ BLI_memarena_free(op->arena);
#ifdef DEBUG
- BM_ELEM_INDEX_VALIDATE(bm, "post bmo", bmo_opdefines[op->type]->opname);
+ BM_ELEM_INDEX_VALIDATE(bm, "post bmo", bmo_opdefines[op->type]->opname);
- /* avoid accidental re-use */
- memset(op, 0xff, sizeof(*op));
+ /* avoid accidental re-use */
+ memset(op, 0xff, sizeof(*op));
#else
- (void)bm;
+ (void)bm;
#endif
}
@@ -256,8 +258,8 @@ void BMO_op_finish(BMesh *bm, BMOperator *op)
*/
bool BMO_slot_exists(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
{
- int slot_code = bmo_name_to_slotcode(slot_args, identifier);
- return (slot_code >= 0);
+ int slot_code = bmo_name_to_slotcode(slot_args, identifier);
+ return (slot_code >= 0);
}
/**
@@ -267,15 +269,15 @@ bool BMO_slot_exists(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifie
*/
BMOpSlot *BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
{
- int slot_code = bmo_name_to_slotcode_check(slot_args, identifier);
+ int slot_code = bmo_name_to_slotcode_check(slot_args, identifier);
- if (UNLIKELY(slot_code < 0)) {
- //return &BMOpEmptySlot;
- BLI_assert(0);
- return NULL; /* better crash */
- }
+ if (UNLIKELY(slot_code < 0)) {
+ //return &BMOpEmptySlot;
+ BLI_assert(0);
+ return NULL; /* better crash */
+ }
- return &slot_args[slot_code];
+ return &slot_args[slot_code];
}
/**
@@ -284,84 +286,85 @@ BMOpSlot *BMO_slot_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identif
* define used.
* Copies data from one slot to another.
*/
-void _bmo_slot_copy(
- BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_name_src,
- BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const char *slot_name_dst,
- struct MemArena *arena_dst)
-{
- BMOpSlot *slot_src = BMO_slot_get(slot_args_src, slot_name_src);
- BMOpSlot *slot_dst = BMO_slot_get(slot_args_dst, slot_name_dst);
-
- if (slot_src == slot_dst) {
- return;
- }
-
- BLI_assert(slot_src->slot_type == slot_dst->slot_type);
- if (slot_src->slot_type != slot_dst->slot_type) {
- return;
- }
-
- if (slot_dst->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
- /* do buffer copy */
- slot_dst->data.buf = NULL;
- slot_dst->len = slot_src->len;
- if (slot_dst->len) {
- /* check dest has all flags enabled that the source has */
- const eBMOpSlotSubType_Elem src_elem_flag = (slot_src->slot_subtype.elem & BM_ALL_NOLOOP);
- const eBMOpSlotSubType_Elem dst_elem_flag = (slot_dst->slot_subtype.elem & BM_ALL_NOLOOP);
-
- if ((src_elem_flag | dst_elem_flag) == dst_elem_flag) {
- /* pass */
- }
- else {
- /* check types */
- const uint tot = slot_src->len;
- uint i;
- uint out = 0;
- BMElem **ele_src = (BMElem **)slot_src->data.buf;
- for (i = 0; i < tot; i++, ele_src++) {
- if ((*ele_src)->head.htype & dst_elem_flag) {
- out++;
- }
- }
- if (out != tot) {
- slot_dst->len = out;
- }
- }
-
- if (slot_dst->len) {
- const int slot_alloc_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type] * slot_dst->len;
- slot_dst->data.buf = BLI_memarena_alloc(arena_dst, slot_alloc_size);
- if (slot_src->len == slot_dst->len) {
- memcpy(slot_dst->data.buf, slot_src->data.buf, slot_alloc_size);
- }
- else {
- /* only copy compatible elements */
- const uint tot = slot_src->len;
- uint i;
- BMElem **ele_src = (BMElem **)slot_src->data.buf;
- BMElem **ele_dst = (BMElem **)slot_dst->data.buf;
- for (i = 0; i < tot; i++, ele_src++) {
- if ((*ele_src)->head.htype & dst_elem_flag) {
- *ele_dst = *ele_src;
- ele_dst++;
- }
- }
- }
- }
- }
- }
- else if (slot_dst->slot_type == BMO_OP_SLOT_MAPPING) {
- GHashIterator gh_iter;
- GHASH_ITER (gh_iter, slot_src->data.ghash) {
- void *key = BLI_ghashIterator_getKey(&gh_iter);
- void *val = BLI_ghashIterator_getValue(&gh_iter);
- BLI_ghash_insert(slot_dst->data.ghash, key, val);
- }
- }
- else {
- slot_dst->data = slot_src->data;
- }
+void _bmo_slot_copy(BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS],
+ const char *slot_name_src,
+ BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS],
+ const char *slot_name_dst,
+ struct MemArena *arena_dst)
+{
+ BMOpSlot *slot_src = BMO_slot_get(slot_args_src, slot_name_src);
+ BMOpSlot *slot_dst = BMO_slot_get(slot_args_dst, slot_name_dst);
+
+ if (slot_src == slot_dst) {
+ return;
+ }
+
+ BLI_assert(slot_src->slot_type == slot_dst->slot_type);
+ if (slot_src->slot_type != slot_dst->slot_type) {
+ return;
+ }
+
+ if (slot_dst->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
+ /* do buffer copy */
+ slot_dst->data.buf = NULL;
+ slot_dst->len = slot_src->len;
+ if (slot_dst->len) {
+ /* check dest has all flags enabled that the source has */
+ const eBMOpSlotSubType_Elem src_elem_flag = (slot_src->slot_subtype.elem & BM_ALL_NOLOOP);
+ const eBMOpSlotSubType_Elem dst_elem_flag = (slot_dst->slot_subtype.elem & BM_ALL_NOLOOP);
+
+ if ((src_elem_flag | dst_elem_flag) == dst_elem_flag) {
+ /* pass */
+ }
+ else {
+ /* check types */
+ const uint tot = slot_src->len;
+ uint i;
+ uint out = 0;
+ BMElem **ele_src = (BMElem **)slot_src->data.buf;
+ for (i = 0; i < tot; i++, ele_src++) {
+ if ((*ele_src)->head.htype & dst_elem_flag) {
+ out++;
+ }
+ }
+ if (out != tot) {
+ slot_dst->len = out;
+ }
+ }
+
+ if (slot_dst->len) {
+ const int slot_alloc_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type] * slot_dst->len;
+ slot_dst->data.buf = BLI_memarena_alloc(arena_dst, slot_alloc_size);
+ if (slot_src->len == slot_dst->len) {
+ memcpy(slot_dst->data.buf, slot_src->data.buf, slot_alloc_size);
+ }
+ else {
+ /* only copy compatible elements */
+ const uint tot = slot_src->len;
+ uint i;
+ BMElem **ele_src = (BMElem **)slot_src->data.buf;
+ BMElem **ele_dst = (BMElem **)slot_dst->data.buf;
+ for (i = 0; i < tot; i++, ele_src++) {
+ if ((*ele_src)->head.htype & dst_elem_flag) {
+ *ele_dst = *ele_src;
+ ele_dst++;
+ }
+ }
+ }
+ }
+ }
+ }
+ else if (slot_dst->slot_type == BMO_OP_SLOT_MAPPING) {
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, slot_src->data.ghash) {
+ void *key = BLI_ghashIterator_getKey(&gh_iter);
+ void *val = BLI_ghashIterator_getValue(&gh_iter);
+ BLI_ghash_insert(slot_dst->data.ghash, key, val);
+ }
+ }
+ else {
+ slot_dst->data = slot_src->data;
+ }
}
/*
@@ -372,185 +375,194 @@ void _bmo_slot_copy(
void BMO_slot_float_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float f)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_FLT);
- if (!(slot->slot_type == BMO_OP_SLOT_FLT)) {
- return;
- }
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_FLT);
+ if (!(slot->slot_type == BMO_OP_SLOT_FLT)) {
+ return;
+ }
- slot->data.f = f;
+ slot->data.f = f;
}
void BMO_slot_int_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int i)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_INT);
- if (!(slot->slot_type == BMO_OP_SLOT_INT)) {
- return;
- }
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_INT);
+ if (!(slot->slot_type == BMO_OP_SLOT_INT)) {
+ return;
+ }
- slot->data.i = i;
+ slot->data.i = i;
}
void BMO_slot_bool_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const bool i)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_BOOL);
- if (!(slot->slot_type == BMO_OP_SLOT_BOOL)) {
- return;
- }
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_BOOL);
+ if (!(slot->slot_type == BMO_OP_SLOT_BOOL)) {
+ return;
+ }
- slot->data.i = i;
+ slot->data.i = i;
}
/* only supports square mats */
-void BMO_slot_mat_set(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float *mat, int size)
-{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_MAT);
- if (!(slot->slot_type == BMO_OP_SLOT_MAT)) {
- return;
- }
-
- slot->len = 4;
- slot->data.p = BLI_memarena_alloc(op->arena, sizeof(float) * 4 * 4);
-
- if (size == 4) {
- copy_m4_m4(slot->data.p, (float (*)[4])mat);
- }
- else if (size == 3) {
- copy_m4_m3(slot->data.p, (float (*)[3])mat);
- }
- else {
- fprintf(stderr, "%s: invalid size argument %d (bmesh internal error)\n", __func__, size);
-
- zero_m4(slot->data.p);
- }
-}
-
-void BMO_slot_mat4_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[4][4])
-{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_MAT);
- if (!(slot->slot_type == BMO_OP_SLOT_MAT)) {
- return;
- }
-
- if (slot->data.p) {
- copy_m4_m4(r_mat, BMO_SLOT_AS_MATRIX(slot));
- }
- else {
- unit_m4(r_mat);
- }
-}
-
-void BMO_slot_mat3_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[3][3])
-{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_MAT);
- if (!(slot->slot_type == BMO_OP_SLOT_MAT)) {
- return;
- }
-
- if (slot->data.p) {
- copy_m3_m4(r_mat, BMO_SLOT_AS_MATRIX(slot));
- }
- else {
- unit_m3(r_mat);
- }
+void BMO_slot_mat_set(BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const float *mat,
+ int size)
+{
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_MAT);
+ if (!(slot->slot_type == BMO_OP_SLOT_MAT)) {
+ return;
+ }
+
+ slot->len = 4;
+ slot->data.p = BLI_memarena_alloc(op->arena, sizeof(float) * 4 * 4);
+
+ if (size == 4) {
+ copy_m4_m4(slot->data.p, (float(*)[4])mat);
+ }
+ else if (size == 3) {
+ copy_m4_m3(slot->data.p, (float(*)[3])mat);
+ }
+ else {
+ fprintf(stderr, "%s: invalid size argument %d (bmesh internal error)\n", __func__, size);
+
+ zero_m4(slot->data.p);
+ }
+}
+
+void BMO_slot_mat4_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ float r_mat[4][4])
+{
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_MAT);
+ if (!(slot->slot_type == BMO_OP_SLOT_MAT)) {
+ return;
+ }
+
+ if (slot->data.p) {
+ copy_m4_m4(r_mat, BMO_SLOT_AS_MATRIX(slot));
+ }
+ else {
+ unit_m4(r_mat);
+ }
+}
+
+void BMO_slot_mat3_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ float r_mat[3][3])
+{
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_MAT);
+ if (!(slot->slot_type == BMO_OP_SLOT_MAT)) {
+ return;
+ }
+
+ if (slot->data.p) {
+ copy_m3_m4(r_mat, BMO_SLOT_AS_MATRIX(slot));
+ }
+ else {
+ unit_m3(r_mat);
+ }
}
void BMO_slot_ptr_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, void *p)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_PTR);
- if (!(slot->slot_type == BMO_OP_SLOT_PTR)) {
- return;
- }
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_PTR);
+ if (!(slot->slot_type == BMO_OP_SLOT_PTR)) {
+ return;
+ }
- slot->data.p = p;
+ slot->data.p = p;
}
-void BMO_slot_vec_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const float vec[3])
+void BMO_slot_vec_set(BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const float vec[3])
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_VEC);
- if (!(slot->slot_type == BMO_OP_SLOT_VEC)) {
- return;
- }
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_VEC);
+ if (!(slot->slot_type == BMO_OP_SLOT_VEC)) {
+ return;
+ }
- copy_v3_v3(slot->data.vec, vec);
+ copy_v3_v3(slot->data.vec, vec);
}
-
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_FLT);
- if (!(slot->slot_type == BMO_OP_SLOT_FLT)) {
- return 0.0f;
- }
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_FLT);
+ if (!(slot->slot_type == BMO_OP_SLOT_FLT)) {
+ return 0.0f;
+ }
- return slot->data.f;
+ return slot->data.f;
}
int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_INT);
- if (!(slot->slot_type == BMO_OP_SLOT_INT)) {
- return 0;
- }
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_INT);
+ if (!(slot->slot_type == BMO_OP_SLOT_INT)) {
+ return 0;
+ }
- return slot->data.i;
+ return slot->data.i;
}
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_BOOL);
- if (!(slot->slot_type == BMO_OP_SLOT_BOOL)) {
- return 0;
- }
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_BOOL);
+ if (!(slot->slot_type == BMO_OP_SLOT_BOOL)) {
+ return 0;
+ }
- return slot->data.i;
+ return slot->data.i;
}
/* if you want a copy of the elem buffer */
void *BMO_slot_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, int *len)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- void **ret;
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ void **ret;
- /* could add support for mapping type */
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ /* could add support for mapping type */
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- ret = MEM_mallocN(sizeof(void *) * slot->len, __func__);
- memcpy(ret, slot->data.buf, sizeof(void *) * slot->len);
- *len = slot->len;
- return ret;
+ ret = MEM_mallocN(sizeof(void *) * slot->len, __func__);
+ memcpy(ret, slot->data.buf, sizeof(void *) * slot->len);
+ *len = slot->len;
+ return ret;
}
void *BMO_slot_ptr_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_PTR);
- if (!(slot->slot_type == BMO_OP_SLOT_PTR)) {
- return NULL;
- }
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_PTR);
+ if (!(slot->slot_type == BMO_OP_SLOT_PTR)) {
+ return NULL;
+ }
- return slot->data.p;
+ return slot->data.p;
}
void BMO_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_vec[3])
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_VEC);
- if (!(slot->slot_type == BMO_OP_SLOT_VEC)) {
- return;
- }
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_VEC);
+ if (!(slot->slot_type == BMO_OP_SLOT_VEC)) {
+ return;
+ }
- copy_v3_v3(r_vec, slot->data.vec);
+ copy_v3_v3(r_vec, slot->data.vec);
}
/*
@@ -560,234 +572,242 @@ void BMO_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_nam
* specific flag enabled (or disabled if test_for_enabled is false).
*/
-static int bmo_mesh_flag_count(
- BMesh *bm, const char htype, const short oflag,
- const bool test_for_enabled)
-{
- int count_vert = 0, count_edge = 0, count_face = 0;
-
- if (htype & BM_VERT) {
- BMIter iter;
- BMVert *ele;
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- if (BMO_vert_flag_test_bool(bm, ele, oflag) == test_for_enabled) {
- count_vert++;
- }
- }
- }
- if (htype & BM_EDGE) {
- BMIter iter;
- BMEdge *ele;
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- if (BMO_edge_flag_test_bool(bm, ele, oflag) == test_for_enabled) {
- count_edge++;
- }
- }
- }
- if (htype & BM_FACE) {
- BMIter iter;
- BMFace *ele;
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- if (BMO_face_flag_test_bool(bm, ele, oflag) == test_for_enabled) {
- count_face++;
- }
- }
- }
-
- return (count_vert + count_edge + count_face);
+static int bmo_mesh_flag_count(BMesh *bm,
+ const char htype,
+ const short oflag,
+ const bool test_for_enabled)
+{
+ int count_vert = 0, count_edge = 0, count_face = 0;
+
+ if (htype & BM_VERT) {
+ BMIter iter;
+ BMVert *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BMO_vert_flag_test_bool(bm, ele, oflag) == test_for_enabled) {
+ count_vert++;
+ }
+ }
+ }
+ if (htype & BM_EDGE) {
+ BMIter iter;
+ BMEdge *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BMO_edge_flag_test_bool(bm, ele, oflag) == test_for_enabled) {
+ count_edge++;
+ }
+ }
+ }
+ if (htype & BM_FACE) {
+ BMIter iter;
+ BMFace *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ if (BMO_face_flag_test_bool(bm, ele, oflag) == test_for_enabled) {
+ count_face++;
+ }
+ }
+ }
+
+ return (count_vert + count_edge + count_face);
}
-
int BMO_mesh_enabled_flag_count(BMesh *bm, const char htype, const short oflag)
{
- return bmo_mesh_flag_count(bm, htype, oflag, true);
+ return bmo_mesh_flag_count(bm, htype, oflag, true);
}
int BMO_mesh_disabled_flag_count(BMesh *bm, const char htype, const short oflag)
{
- return bmo_mesh_flag_count(bm, htype, oflag, false);
-}
-
-void BMO_mesh_flag_disable_all(BMesh *bm, BMOperator *UNUSED(op), const char htype, const short oflag)
-{
- if (htype & BM_VERT) {
- BMIter iter;
- BMVert *ele;
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- BMO_vert_flag_disable(bm, ele, oflag);
- }
- }
- if (htype & BM_EDGE) {
- BMIter iter;
- BMEdge *ele;
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- BMO_edge_flag_disable(bm, ele, oflag);
- }
- }
- if (htype & BM_FACE) {
- BMIter iter;
- BMFace *ele;
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- BMO_face_flag_disable(bm, ele, oflag);
- }
- }
-}
-
-void BMO_mesh_selected_remap(
- BMesh *bm,
- BMOpSlot *slot_vert_map,
- BMOpSlot *slot_edge_map,
- BMOpSlot *slot_face_map,
- const bool check_select)
-{
- if (bm->selected.first) {
- BMEditSelection *ese, *ese_next;
- BMOpSlot *slot_elem_map;
-
- for (ese = bm->selected.first; ese; ese = ese_next) {
- ese_next = ese->next;
-
- switch (ese->htype) {
- case BM_VERT: slot_elem_map = slot_vert_map; break;
- case BM_EDGE: slot_elem_map = slot_edge_map; break;
- default: slot_elem_map = slot_face_map; break;
- }
-
- ese->ele = BMO_slot_map_elem_get(slot_elem_map, ese->ele);
-
- if (UNLIKELY((ese->ele == NULL) ||
- (check_select && (BM_elem_flag_test(ese->ele, BM_ELEM_SELECT) == false))))
- {
- BLI_remlink(&bm->selected, ese);
- MEM_freeN(ese);
- }
- }
- }
-
- if (bm->act_face) {
- BMFace *f = BMO_slot_map_elem_get(slot_face_map, bm->act_face);
- if (f) {
- bm->act_face = f;
- }
- }
+ return bmo_mesh_flag_count(bm, htype, oflag, false);
+}
+
+void BMO_mesh_flag_disable_all(BMesh *bm,
+ BMOperator *UNUSED(op),
+ const char htype,
+ const short oflag)
+{
+ if (htype & BM_VERT) {
+ BMIter iter;
+ BMVert *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ BMO_vert_flag_disable(bm, ele, oflag);
+ }
+ }
+ if (htype & BM_EDGE) {
+ BMIter iter;
+ BMEdge *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ BMO_edge_flag_disable(bm, ele, oflag);
+ }
+ }
+ if (htype & BM_FACE) {
+ BMIter iter;
+ BMFace *ele;
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ BMO_face_flag_disable(bm, ele, oflag);
+ }
+ }
+}
+
+void BMO_mesh_selected_remap(BMesh *bm,
+ BMOpSlot *slot_vert_map,
+ BMOpSlot *slot_edge_map,
+ BMOpSlot *slot_face_map,
+ const bool check_select)
+{
+ if (bm->selected.first) {
+ BMEditSelection *ese, *ese_next;
+ BMOpSlot *slot_elem_map;
+
+ for (ese = bm->selected.first; ese; ese = ese_next) {
+ ese_next = ese->next;
+
+ switch (ese->htype) {
+ case BM_VERT:
+ slot_elem_map = slot_vert_map;
+ break;
+ case BM_EDGE:
+ slot_elem_map = slot_edge_map;
+ break;
+ default:
+ slot_elem_map = slot_face_map;
+ break;
+ }
+
+ ese->ele = BMO_slot_map_elem_get(slot_elem_map, ese->ele);
+
+ if (UNLIKELY((ese->ele == NULL) ||
+ (check_select && (BM_elem_flag_test(ese->ele, BM_ELEM_SELECT) == false)))) {
+ BLI_remlink(&bm->selected, ese);
+ MEM_freeN(ese);
+ }
+ }
+ }
+
+ if (bm->act_face) {
+ BMFace *f = BMO_slot_map_elem_get(slot_face_map, bm->act_face);
+ if (f) {
+ bm->act_face = f;
+ }
+ }
}
-
int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- /* check if its actually a buffer */
- if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF) {
- return 0;
- }
+ /* check if its actually a buffer */
+ if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF) {
+ return 0;
+ }
- return slot->len;
+ return slot->len;
}
int BMO_slot_map_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
- return BLI_ghash_len(slot->data.ghash);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
+ return BLI_ghash_len(slot->data.ghash);
}
/* inserts a key/value mapping into a mapping slot. note that it copies the
* value, it doesn't store a reference to it. */
-void BMO_slot_map_insert(
- BMOperator *op, BMOpSlot *slot,
- const void *element, const void *data)
+void BMO_slot_map_insert(BMOperator *op, BMOpSlot *slot, const void *element, const void *data)
{
- (void) op; /* Ignored in release builds. */
+ (void)op; /* Ignored in release builds. */
- BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
- BMO_ASSERT_SLOT_IN_OP(slot, op);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
+ BMO_ASSERT_SLOT_IN_OP(slot, op);
- BLI_ghash_insert(slot->data.ghash, (void *)element, (void *)data);
+ BLI_ghash_insert(slot->data.ghash, (void *)element, (void *)data);
}
#if 0
void *bmo_slot_buffer_grow(BMesh *bm, BMOperator *op, int slot_code, int totadd)
{
- BMOpSlot *slot = &op->slots[slot_code];
- void *tmp;
- ssize_t allocsize;
+ BMOpSlot *slot = &op->slots[slot_code];
+ void *tmp;
+ ssize_t allocsize;
- BLI_assert(slot->slottype == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(slot->slottype == BMO_OP_SLOT_ELEMENT_BUF);
- /* check if its actually a buffer */
- if (slot->slottype != BMO_OP_SLOT_ELEMENT_BUF)
- return NULL;
+ /* check if its actually a buffer */
+ if (slot->slottype != BMO_OP_SLOT_ELEMENT_BUF)
+ return NULL;
- if (slot->flag & BMOS_DYNAMIC_ARRAY) {
- if (slot->len >= slot->size) {
- slot->size = (slot->size + 1 + totadd) * 2;
+ if (slot->flag & BMOS_DYNAMIC_ARRAY) {
+ if (slot->len >= slot->size) {
+ slot->size = (slot->size + 1 + totadd) * 2;
- allocsize = BMO_OPSLOT_TYPEINFO[bmo_opdefines[op->type]->slot_types[slot_code].type] * slot->size;
+ allocsize = BMO_OPSLOT_TYPEINFO[bmo_opdefines[op->type]->slot_types[slot_code].type] * slot->size;
- tmp = slot->data.buf;
- slot->data.buf = MEM_callocN(allocsize, "opslot dynamic array");
- memcpy(slot->data.buf, tmp, allocsize);
- MEM_freeN(tmp);
- }
+ tmp = slot->data.buf;
+ slot->data.buf = MEM_callocN(allocsize, "opslot dynamic array");
+ memcpy(slot->data.buf, tmp, allocsize);
+ MEM_freeN(tmp);
+ }
- slot->len += totadd;
- }
- else {
- slot->flag |= BMOS_DYNAMIC_ARRAY;
- slot->len += totadd;
- slot->size = slot->len + 2;
+ slot->len += totadd;
+ }
+ else {
+ slot->flag |= BMOS_DYNAMIC_ARRAY;
+ slot->len += totadd;
+ slot->size = slot->len + 2;
- allocsize = BMO_OPSLOT_TYPEINFO[bmo_opdefines[op->type]->slot_types[slot_code].type] * slot->len;
+ allocsize = BMO_OPSLOT_TYPEINFO[bmo_opdefines[op->type]->slot_types[slot_code].type] * slot->len;
- tmp = slot->data.buf;
- slot->data.buf = MEM_callocN(allocsize, "opslot dynamic array");
- memcpy(slot->data.buf, tmp, allocsize);
- }
+ tmp = slot->data.buf;
+ slot->data.buf = MEM_callocN(allocsize, "opslot dynamic array");
+ memcpy(slot->data.buf, tmp, allocsize);
+ }
- return slot->data.buf;
+ return slot->data.buf;
}
#endif
-void BMO_slot_map_to_flag(
- BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const short oflag)
+void BMO_slot_map_to_flag(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const short oflag)
{
- GHashIterator gh_iter;
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BMElemF *ele_f;
-
- BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
+ GHashIterator gh_iter;
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BMElemF *ele_f;
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
- GHASH_ITER (gh_iter, slot->data.ghash) {
- ele_f = BLI_ghashIterator_getKey(&gh_iter);
- if (ele_f->head.htype & htype) {
- BMO_elem_flag_enable(bm, ele_f, oflag);
- }
- }
+ GHASH_ITER (gh_iter, slot->data.ghash) {
+ ele_f = BLI_ghashIterator_getKey(&gh_iter);
+ if (ele_f->head.htype & htype) {
+ BMO_elem_flag_enable(bm, ele_f, oflag);
+ }
+ }
}
-void *BMO_slot_buffer_alloc(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const int len)
+void *BMO_slot_buffer_alloc(BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const int len)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- /* check if its actually a buffer */
- if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF) {
- return NULL;
- }
+ /* check if its actually a buffer */
+ if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF) {
+ return NULL;
+ }
- slot->len = len;
- if (len) {
- slot->data.buf = BLI_memarena_alloc(op->arena, BMO_OPSLOT_TYPEINFO[slot->slot_type] * len);
- }
- else {
- slot->data.buf = NULL;
- }
+ slot->len = len;
+ if (len) {
+ slot->data.buf = BLI_memarena_alloc(op->arena, BMO_OPSLOT_TYPEINFO[slot->slot_type] * len);
+ }
+ else {
+ slot->data.buf = NULL;
+ }
- return slot->data.buf;
+ return slot->data.buf;
}
/**
@@ -795,49 +815,57 @@ void *BMO_slot_buffer_alloc(BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS]
*
* Copies all elements of a certain type into an operator slot.
*/
-void BMO_slot_buffer_from_all(
- BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
- const char *slot_name, const char htype)
-{
- BMOpSlot *output = BMO_slot_get(slot_args, slot_name);
- int totelement = 0, i = 0;
-
- BLI_assert(output->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- BLI_assert(((output->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
-
- if (htype & BM_VERT) { totelement += bm->totvert; }
- if (htype & BM_EDGE) { totelement += bm->totedge; }
- if (htype & BM_FACE) { totelement += bm->totface; }
-
- if (totelement) {
- BMIter iter;
- BMHeader *ele;
-
- BMO_slot_buffer_alloc(op, slot_args, slot_name, totelement);
-
- /* TODO - collapse these loops into one */
-
- if (htype & BM_VERT) {
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- output->data.buf[i] = ele;
- i++;
- }
- }
-
- if (htype & BM_EDGE) {
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- output->data.buf[i] = ele;
- i++;
- }
- }
-
- if (htype & BM_FACE) {
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- output->data.buf[i] = ele;
- i++;
- }
- }
- }
+void BMO_slot_buffer_from_all(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype)
+{
+ BMOpSlot *output = BMO_slot_get(slot_args, slot_name);
+ int totelement = 0, i = 0;
+
+ BLI_assert(output->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((output->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
+
+ if (htype & BM_VERT) {
+ totelement += bm->totvert;
+ }
+ if (htype & BM_EDGE) {
+ totelement += bm->totedge;
+ }
+ if (htype & BM_FACE) {
+ totelement += bm->totface;
+ }
+
+ if (totelement) {
+ BMIter iter;
+ BMHeader *ele;
+
+ BMO_slot_buffer_alloc(op, slot_args, slot_name, totelement);
+
+ /* TODO - collapse these loops into one */
+
+ if (htype & BM_VERT) {
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ output->data.buf[i] = ele;
+ i++;
+ }
+ }
+
+ if (htype & BM_EDGE) {
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ output->data.buf[i] = ele;
+ i++;
+ }
+ }
+
+ if (htype & BM_FACE) {
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ output->data.buf[i] = ele;
+ i++;
+ }
+ }
+ }
}
/**
@@ -846,159 +874,166 @@ void BMO_slot_buffer_from_all(
* Copies elements of a certain type, which have a certain header flag
* enabled/disabled into a slot for an operator.
*/
-static void bmo_slot_buffer_from_hflag(
- BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag,
- const bool test_for_enabled)
-{
- BMOpSlot *output = BMO_slot_get(slot_args, slot_name);
- int totelement = 0, i = 0;
- const bool respecthide = ((op->flag & BMO_FLAG_RESPECT_HIDE) != 0) && ((hflag & BM_ELEM_HIDDEN) == 0);
-
- BLI_assert(output->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- BLI_assert(((output->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
- BLI_assert((output->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) == 0);
-
- if (test_for_enabled) {
- totelement = BM_mesh_elem_hflag_count_enabled(bm, htype, hflag, respecthide);
- }
- else {
- totelement = BM_mesh_elem_hflag_count_disabled(bm, htype, hflag, respecthide);
- }
-
- if (totelement) {
- BMIter iter;
- BMElem *ele;
-
- BMO_slot_buffer_alloc(op, slot_args, slot_name, totelement);
-
- /* TODO - collapse these loops into one */
-
- if (htype & BM_VERT) {
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- if ((!respecthide || !BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) &&
- BM_elem_flag_test_bool(ele, hflag) == test_for_enabled)
- {
- output->data.buf[i] = ele;
- i++;
- }
- }
- }
-
- if (htype & BM_EDGE) {
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- if ((!respecthide || !BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) &&
- BM_elem_flag_test_bool(ele, hflag) == test_for_enabled)
- {
- output->data.buf[i] = ele;
- i++;
- }
- }
- }
-
- if (htype & BM_FACE) {
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- if ((!respecthide || !BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) &&
- BM_elem_flag_test_bool(ele, hflag) == test_for_enabled)
- {
- output->data.buf[i] = ele;
- i++;
- }
- }
- }
- }
- else {
- output->len = 0;
- }
-}
-
-void BMO_slot_buffer_from_enabled_hflag(
- BMesh *bm, BMOperator *op,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag)
-{
- bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, true);
-}
-
-void BMO_slot_buffer_from_disabled_hflag(
- BMesh *bm, BMOperator *op,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag)
-{
- bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, false);
+static void bmo_slot_buffer_from_hflag(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const char hflag,
+ const bool test_for_enabled)
+{
+ BMOpSlot *output = BMO_slot_get(slot_args, slot_name);
+ int totelement = 0, i = 0;
+ const bool respecthide = ((op->flag & BMO_FLAG_RESPECT_HIDE) != 0) &&
+ ((hflag & BM_ELEM_HIDDEN) == 0);
+
+ BLI_assert(output->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((output->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
+ BLI_assert((output->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) == 0);
+
+ if (test_for_enabled) {
+ totelement = BM_mesh_elem_hflag_count_enabled(bm, htype, hflag, respecthide);
+ }
+ else {
+ totelement = BM_mesh_elem_hflag_count_disabled(bm, htype, hflag, respecthide);
+ }
+
+ if (totelement) {
+ BMIter iter;
+ BMElem *ele;
+
+ BMO_slot_buffer_alloc(op, slot_args, slot_name, totelement);
+
+ /* TODO - collapse these loops into one */
+
+ if (htype & BM_VERT) {
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ if ((!respecthide || !BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) &&
+ BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) {
+ output->data.buf[i] = ele;
+ i++;
+ }
+ }
+ }
+
+ if (htype & BM_EDGE) {
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ if ((!respecthide || !BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) &&
+ BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) {
+ output->data.buf[i] = ele;
+ i++;
+ }
+ }
+ }
+
+ if (htype & BM_FACE) {
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ if ((!respecthide || !BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) &&
+ BM_elem_flag_test_bool(ele, hflag) == test_for_enabled) {
+ output->data.buf[i] = ele;
+ i++;
+ }
+ }
+ }
+ }
+ else {
+ output->len = 0;
+ }
+}
+
+void BMO_slot_buffer_from_enabled_hflag(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const char hflag)
+{
+ bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, true);
+}
+
+void BMO_slot_buffer_from_disabled_hflag(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const char hflag)
+{
+ bmo_slot_buffer_from_hflag(bm, op, slot_args, slot_name, htype, hflag, false);
}
void BMO_slot_buffer_from_single(BMOperator *op, BMOpSlot *slot, BMHeader *ele)
{
- BMO_ASSERT_SLOT_IN_OP(slot, op);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE);
- BLI_assert(slot->len == 0 || slot->len == 1);
+ BMO_ASSERT_SLOT_IN_OP(slot, op);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE);
+ BLI_assert(slot->len == 0 || slot->len == 1);
- BLI_assert(slot->slot_subtype.elem & ele->htype);
+ BLI_assert(slot->slot_subtype.elem & ele->htype);
- slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(void *) * 4); /* XXX, why 'x4' ? */
- slot->len = 1;
- *slot->data.buf = ele;
+ slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(void *) * 4); /* XXX, why 'x4' ? */
+ slot->len = 1;
+ *slot->data.buf = ele;
}
-void BMO_slot_buffer_from_array(BMOperator *op, BMOpSlot *slot, BMHeader **ele_buffer, int ele_buffer_len)
+void BMO_slot_buffer_from_array(BMOperator *op,
+ BMOpSlot *slot,
+ BMHeader **ele_buffer,
+ int ele_buffer_len)
{
- BMO_ASSERT_SLOT_IN_OP(slot, op);
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- BLI_assert(slot->len == 0 || slot->len == ele_buffer_len);
+ BMO_ASSERT_SLOT_IN_OP(slot, op);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(slot->len == 0 || slot->len == ele_buffer_len);
- if (slot->data.buf == NULL) {
- slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(*slot->data.buf) * ele_buffer_len);
- }
+ if (slot->data.buf == NULL) {
+ slot->data.buf = BLI_memarena_alloc(op->arena, sizeof(*slot->data.buf) * ele_buffer_len);
+ }
- slot->len = ele_buffer_len;
- memcpy(slot->data.buf, ele_buffer, ele_buffer_len * sizeof(*slot->data.buf));
+ slot->len = ele_buffer_len;
+ memcpy(slot->data.buf, ele_buffer, ele_buffer_len * sizeof(*slot->data.buf));
}
-
void *BMO_slot_buffer_get_single(BMOpSlot *slot)
{
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE);
- BLI_assert(slot->len == 0 || slot->len == 1);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE);
+ BLI_assert(slot->len == 0 || slot->len == 1);
- return slot->len ? (BMHeader *)slot->data.buf[0] : NULL;
+ return slot->len ? (BMHeader *)slot->data.buf[0] : NULL;
}
/**
* Copies the values from another slot to the end of the output slot.
*/
-void _bmo_slot_buffer_append(
- BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS], const char *slot_name_dst,
- BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS], const char *slot_name_src,
- struct MemArena *arena_dst)
-{
- BMOpSlot *slot_dst = BMO_slot_get(slot_args_dst, slot_name_dst);
- BMOpSlot *slot_src = BMO_slot_get(slot_args_src, slot_name_src);
-
- BLI_assert(slot_dst->slot_type == BMO_OP_SLOT_ELEMENT_BUF &&
- slot_src->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
-
- if (slot_dst->len == 0) {
- /* output slot is empty, copy rather than append */
- _bmo_slot_copy(slot_args_src, slot_name_src,
- slot_args_dst, slot_name_dst,
- arena_dst);
- }
- else if (slot_src->len != 0) {
- int elem_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type];
- int alloc_size = elem_size * (slot_dst->len + slot_src->len);
- /* allocate new buffer */
- void *buf = BLI_memarena_alloc(arena_dst, alloc_size);
-
- /* copy slot data */
- memcpy(buf, slot_dst->data.buf, elem_size * slot_dst->len);
- memcpy(((char *)buf) + elem_size * slot_dst->len, slot_src->data.buf, elem_size * slot_src->len);
-
- slot_dst->data.buf = buf;
- slot_dst->len += slot_src->len;
- }
+void _bmo_slot_buffer_append(BMOpSlot slot_args_dst[BMO_OP_MAX_SLOTS],
+ const char *slot_name_dst,
+ BMOpSlot slot_args_src[BMO_OP_MAX_SLOTS],
+ const char *slot_name_src,
+ struct MemArena *arena_dst)
+{
+ BMOpSlot *slot_dst = BMO_slot_get(slot_args_dst, slot_name_dst);
+ BMOpSlot *slot_src = BMO_slot_get(slot_args_src, slot_name_src);
+
+ BLI_assert(slot_dst->slot_type == BMO_OP_SLOT_ELEMENT_BUF &&
+ slot_src->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+
+ if (slot_dst->len == 0) {
+ /* output slot is empty, copy rather than append */
+ _bmo_slot_copy(slot_args_src, slot_name_src, slot_args_dst, slot_name_dst, arena_dst);
+ }
+ else if (slot_src->len != 0) {
+ int elem_size = BMO_OPSLOT_TYPEINFO[slot_dst->slot_type];
+ int alloc_size = elem_size * (slot_dst->len + slot_src->len);
+ /* allocate new buffer */
+ void *buf = BLI_memarena_alloc(arena_dst, alloc_size);
+
+ /* copy slot data */
+ memcpy(buf, slot_dst->data.buf, elem_size * slot_dst->len);
+ memcpy(
+ ((char *)buf) + elem_size * slot_dst->len, slot_src->data.buf, elem_size * slot_src->len);
+
+ slot_dst->data.buf = buf;
+ slot_dst->len += slot_src->len;
+ }
}
/**
@@ -1007,85 +1042,91 @@ void _bmo_slot_buffer_append(
* Copies elements of a certain type, which have a certain flag set
* into an output slot for an operator.
*/
-static void bmo_slot_buffer_from_flag(
- BMesh *bm, BMOperator *op,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const short oflag,
- const bool test_for_enabled)
-{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- int totelement, i = 0;
-
- BLI_assert(op->slots_in == slot_args || op->slots_out == slot_args);
-
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
- BLI_assert((slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) == 0);
-
- if (test_for_enabled) {
- totelement = BMO_mesh_enabled_flag_count(bm, htype, oflag);
- }
- else {
- totelement = BMO_mesh_disabled_flag_count(bm, htype, oflag);
- }
-
- if (totelement) {
- BMIter iter;
- BMHeader *ele;
- BMHeader **ele_array;
-
- BMO_slot_buffer_alloc(op, slot_args, slot_name, totelement);
-
- ele_array = (BMHeader **)slot->data.buf;
-
- /* TODO - collapse these loops into one */
-
- if (htype & BM_VERT) {
- BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
- if (BMO_vert_flag_test_bool(bm, (BMVert *)ele, oflag) == test_for_enabled) {
- ele_array[i] = ele;
- i++;
- }
- }
- }
-
- if (htype & BM_EDGE) {
- BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
- if (BMO_edge_flag_test_bool(bm, (BMEdge *)ele, oflag) == test_for_enabled) {
- ele_array[i] = ele;
- i++;
- }
- }
- }
-
- if (htype & BM_FACE) {
- BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
- if (BMO_face_flag_test_bool(bm, (BMFace *)ele, oflag) == test_for_enabled) {
- ele_array[i] = ele;
- i++;
- }
- }
- }
- }
- else {
- slot->len = 0;
- }
-}
-
-void BMO_slot_buffer_from_enabled_flag(
- BMesh *bm, BMOperator *op,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const short oflag)
-{
- bmo_slot_buffer_from_flag(bm, op, slot_args, slot_name, htype, oflag, true);
-}
-
-void BMO_slot_buffer_from_disabled_flag(
- BMesh *bm, BMOperator *op,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const short oflag)
-{
- bmo_slot_buffer_from_flag(bm, op, slot_args, slot_name, htype, oflag, false);
+static void bmo_slot_buffer_from_flag(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const short oflag,
+ const bool test_for_enabled)
+{
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ int totelement, i = 0;
+
+ BLI_assert(op->slots_in == slot_args || op->slots_out == slot_args);
+
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
+ BLI_assert((slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) == 0);
+
+ if (test_for_enabled) {
+ totelement = BMO_mesh_enabled_flag_count(bm, htype, oflag);
+ }
+ else {
+ totelement = BMO_mesh_disabled_flag_count(bm, htype, oflag);
+ }
+
+ if (totelement) {
+ BMIter iter;
+ BMHeader *ele;
+ BMHeader **ele_array;
+
+ BMO_slot_buffer_alloc(op, slot_args, slot_name, totelement);
+
+ ele_array = (BMHeader **)slot->data.buf;
+
+ /* TODO - collapse these loops into one */
+
+ if (htype & BM_VERT) {
+ BM_ITER_MESH (ele, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BMO_vert_flag_test_bool(bm, (BMVert *)ele, oflag) == test_for_enabled) {
+ ele_array[i] = ele;
+ i++;
+ }
+ }
+ }
+
+ if (htype & BM_EDGE) {
+ BM_ITER_MESH (ele, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BMO_edge_flag_test_bool(bm, (BMEdge *)ele, oflag) == test_for_enabled) {
+ ele_array[i] = ele;
+ i++;
+ }
+ }
+ }
+
+ if (htype & BM_FACE) {
+ BM_ITER_MESH (ele, &iter, bm, BM_FACES_OF_MESH) {
+ if (BMO_face_flag_test_bool(bm, (BMFace *)ele, oflag) == test_for_enabled) {
+ ele_array[i] = ele;
+ i++;
+ }
+ }
+ }
+ }
+ else {
+ slot->len = 0;
+ }
+}
+
+void BMO_slot_buffer_from_enabled_flag(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const short oflag)
+{
+ bmo_slot_buffer_from_flag(bm, op, slot_args, slot_name, htype, oflag, true);
+}
+
+void BMO_slot_buffer_from_disabled_flag(BMesh *bm,
+ BMOperator *op,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const short oflag)
+{
+ bmo_slot_buffer_from_flag(bm, op, slot_args, slot_name, htype, oflag, false);
}
/**
@@ -1094,36 +1135,38 @@ void BMO_slot_buffer_from_disabled_flag(
* Header Flags elements in a slots buffer, automatically
* using the selection API where appropriate.
*/
-void BMO_slot_buffer_hflag_enable(
- BMesh *bm,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag, const bool do_flush)
+void BMO_slot_buffer_hflag_enable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const char hflag,
+ const bool do_flush)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BMElem **data = (BMElem **)slot->data.buf;
- int i;
- const bool do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT));
- const bool do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BMElem **data = (BMElem **)slot->data.buf;
+ int i;
+ const bool do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT));
+ const bool do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
- BLI_assert((slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) == 0);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
+ BLI_assert((slot->slot_subtype.elem & BMO_OP_SLOT_SUBTYPE_ELEM_IS_SINGLE) == 0);
- for (i = 0; i < slot->len; i++, data++) {
- if (!(htype & (*data)->head.htype)) {
- continue;
- }
+ for (i = 0; i < slot->len; i++, data++) {
+ if (!(htype & (*data)->head.htype)) {
+ continue;
+ }
- if (do_flush_select) {
- BM_elem_select_set(bm, *data, true);
- }
+ if (do_flush_select) {
+ BM_elem_select_set(bm, *data, true);
+ }
- if (do_flush_hide) {
- BM_elem_hide_set(bm, *data, false);
- }
+ if (do_flush_hide) {
+ BM_elem_hide_set(bm, *data, false);
+ }
- BM_elem_flag_enable(*data, hflag);
- }
+ BM_elem_flag_enable(*data, hflag);
+ }
}
/**
@@ -1132,35 +1175,37 @@ void BMO_slot_buffer_hflag_enable(
* Removes flags from elements in a slots buffer, automatically
* using the selection API where appropriate.
*/
-void BMO_slot_buffer_hflag_disable(
- BMesh *bm,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const char hflag, const bool do_flush)
+void BMO_slot_buffer_hflag_disable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const char hflag,
+ const bool do_flush)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BMElem **data = (BMElem **)slot->data.buf;
- int i;
- const bool do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT));
- const bool do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BMElem **data = (BMElem **)slot->data.buf;
+ int i;
+ const bool do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT));
+ const bool do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN));
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
- for (i = 0; i < slot->len; i++, data++) {
- if (!(htype & (*data)->head.htype)) {
- continue;
- }
+ for (i = 0; i < slot->len; i++, data++) {
+ if (!(htype & (*data)->head.htype)) {
+ continue;
+ }
- if (do_flush_select) {
- BM_elem_select_set(bm, *data, false);
- }
+ if (do_flush_select) {
+ BM_elem_select_set(bm, *data, false);
+ }
- if (do_flush_hide) {
- BM_elem_hide_set(bm, *data, false);
- }
+ if (do_flush_hide) {
+ BM_elem_hide_set(bm, *data, false);
+ }
- BM_elem_flag_disable(*data, hflag);
- }
+ BM_elem_flag_disable(*data, hflag);
+ }
}
/**
@@ -1168,25 +1213,26 @@ void BMO_slot_buffer_hflag_disable(
*
* Flags elements in a slots buffer
*/
-void BMO_slot_buffer_flag_enable(
- BMesh *bm,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const short oflag)
+void BMO_slot_buffer_flag_enable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const short oflag)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BMHeader **data = slot->data.p;
- int i;
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BMHeader **data = slot->data.p;
+ int i;
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
- for (i = 0; i < slot->len; i++) {
- if (!(htype & data[i]->htype)) {
- continue;
- }
+ for (i = 0; i < slot->len; i++) {
+ if (!(htype & data[i]->htype)) {
+ continue;
+ }
- BMO_elem_flag_enable(bm, (BMElemF *)data[i], oflag);
- }
+ BMO_elem_flag_enable(bm, (BMElemF *)data[i], oflag);
+ }
}
/**
@@ -1194,28 +1240,28 @@ void BMO_slot_buffer_flag_enable(
*
* Removes flags from elements in a slots buffer
*/
-void BMO_slot_buffer_flag_disable(
- BMesh *bm,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char htype, const short oflag)
+void BMO_slot_buffer_flag_disable(BMesh *bm,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char htype,
+ const short oflag)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- BMHeader **data = (BMHeader **)slot->data.buf;
- int i;
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BMHeader **data = (BMHeader **)slot->data.buf;
+ int i;
- BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
- BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
+ BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
+ BLI_assert(((slot->slot_subtype.elem & BM_ALL_NOLOOP) & htype) == htype);
- for (i = 0; i < slot->len; i++) {
- if (!(htype & data[i]->htype)) {
- continue;
- }
+ for (i = 0; i < slot->len; i++) {
+ if (!(htype & data[i]->htype)) {
+ continue;
+ }
- BMO_elem_flag_disable(bm, (BMElemF *)data[i], oflag);
- }
+ BMO_elem_flag_disable(bm, (BMElemF *)data[i], oflag);
+ }
}
-
/**
* \brief ALLOC/FREE FLAG LAYER
*
@@ -1231,172 +1277,175 @@ void BMO_slot_buffer_flag_disable(
*/
static void bmo_flag_layer_alloc(BMesh *bm)
{
- /* set the index values since we are looping over all data anyway,
- * may save time later on */
-
- BLI_mempool *voldpool = bm->vtoolflagpool; /* old flag pool */
- BLI_mempool *eoldpool = bm->etoolflagpool; /* old flag pool */
- BLI_mempool *foldpool = bm->ftoolflagpool; /* old flag pool */
-
- /* store memcpy size for reuse */
- const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer));
-
- bm->totflags++;
-
- bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, bm->totvert, 512, BLI_MEMPOOL_NOP);
- bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, bm->totedge, 512, BLI_MEMPOOL_NOP);
- bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer) * bm->totflags, bm->totface, 512, BLI_MEMPOOL_NOP);
-
- /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */
- BMIter iter;
- int i;
-
- BMVert_OFlag *v_oflag;
- BLI_mempool *newpool = bm->vtoolflagpool;
- BM_ITER_MESH_INDEX (v_oflag, &iter, bm, BM_VERTS_OF_MESH, i) {
- void *oldflags = v_oflag->oflags;
- v_oflag->oflags = BLI_mempool_calloc(newpool);
- memcpy(v_oflag->oflags, oldflags, old_totflags_size);
- BM_elem_index_set(&v_oflag->base, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)v_oflag);
- }
-
- BMEdge_OFlag *e_oflag;
- newpool = bm->etoolflagpool;
- BM_ITER_MESH_INDEX (e_oflag, &iter, bm, BM_EDGES_OF_MESH, i) {
- void *oldflags = e_oflag->oflags;
- e_oflag->oflags = BLI_mempool_calloc(newpool);
- memcpy(e_oflag->oflags, oldflags, old_totflags_size);
- BM_elem_index_set(&e_oflag->base, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)e_oflag);
- }
-
- BMFace_OFlag *f_oflag;
- newpool = bm->ftoolflagpool;
- BM_ITER_MESH_INDEX (f_oflag, &iter, bm, BM_FACES_OF_MESH, i) {
- void *oldflags = f_oflag->oflags;
- f_oflag->oflags = BLI_mempool_calloc(newpool);
- memcpy(f_oflag->oflags, oldflags, old_totflags_size);
- BM_elem_index_set(&f_oflag->base, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)f_oflag);
- }
-
- BLI_mempool_destroy(voldpool);
- BLI_mempool_destroy(eoldpool);
- BLI_mempool_destroy(foldpool);
-
- bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
+ /* set the index values since we are looping over all data anyway,
+ * may save time later on */
+
+ BLI_mempool *voldpool = bm->vtoolflagpool; /* old flag pool */
+ BLI_mempool *eoldpool = bm->etoolflagpool; /* old flag pool */
+ BLI_mempool *foldpool = bm->ftoolflagpool; /* old flag pool */
+
+ /* store memcpy size for reuse */
+ const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer));
+
+ bm->totflags++;
+
+ bm->vtoolflagpool = BLI_mempool_create(
+ sizeof(BMFlagLayer) * bm->totflags, bm->totvert, 512, BLI_MEMPOOL_NOP);
+ bm->etoolflagpool = BLI_mempool_create(
+ sizeof(BMFlagLayer) * bm->totflags, bm->totedge, 512, BLI_MEMPOOL_NOP);
+ bm->ftoolflagpool = BLI_mempool_create(
+ sizeof(BMFlagLayer) * bm->totflags, bm->totface, 512, BLI_MEMPOOL_NOP);
+
+ /* now go through and memcpy all the flags. Loops don't get a flag layer at this time.. */
+ BMIter iter;
+ int i;
+
+ BMVert_OFlag *v_oflag;
+ BLI_mempool *newpool = bm->vtoolflagpool;
+ BM_ITER_MESH_INDEX (v_oflag, &iter, bm, BM_VERTS_OF_MESH, i) {
+ void *oldflags = v_oflag->oflags;
+ v_oflag->oflags = BLI_mempool_calloc(newpool);
+ memcpy(v_oflag->oflags, oldflags, old_totflags_size);
+ BM_elem_index_set(&v_oflag->base, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)v_oflag);
+ }
+
+ BMEdge_OFlag *e_oflag;
+ newpool = bm->etoolflagpool;
+ BM_ITER_MESH_INDEX (e_oflag, &iter, bm, BM_EDGES_OF_MESH, i) {
+ void *oldflags = e_oflag->oflags;
+ e_oflag->oflags = BLI_mempool_calloc(newpool);
+ memcpy(e_oflag->oflags, oldflags, old_totflags_size);
+ BM_elem_index_set(&e_oflag->base, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)e_oflag);
+ }
+
+ BMFace_OFlag *f_oflag;
+ newpool = bm->ftoolflagpool;
+ BM_ITER_MESH_INDEX (f_oflag, &iter, bm, BM_FACES_OF_MESH, i) {
+ void *oldflags = f_oflag->oflags;
+ f_oflag->oflags = BLI_mempool_calloc(newpool);
+ memcpy(f_oflag->oflags, oldflags, old_totflags_size);
+ BM_elem_index_set(&f_oflag->base, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)f_oflag);
+ }
+
+ BLI_mempool_destroy(voldpool);
+ BLI_mempool_destroy(eoldpool);
+ BLI_mempool_destroy(foldpool);
+
+ bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
}
static void bmo_flag_layer_free(BMesh *bm)
{
- /* set the index values since we are looping over all data anyway,
- * may save time later on */
-
- BLI_mempool *voldpool = bm->vtoolflagpool;
- BLI_mempool *eoldpool = bm->etoolflagpool;
- BLI_mempool *foldpool = bm->ftoolflagpool;
-
- /* store memcpy size for reuse */
- const size_t new_totflags_size = ((bm->totflags - 1) * sizeof(BMFlagLayer));
-
- /* de-increment the totflags first.. */
- bm->totflags--;
-
- bm->vtoolflagpool = BLI_mempool_create(new_totflags_size, bm->totvert, 512, BLI_MEMPOOL_NOP);
- bm->etoolflagpool = BLI_mempool_create(new_totflags_size, bm->totedge, 512, BLI_MEMPOOL_NOP);
- bm->ftoolflagpool = BLI_mempool_create(new_totflags_size, bm->totface, 512, BLI_MEMPOOL_NOP);
-
- /* now go through and memcpy all the flag */
- BMIter iter;
- int i;
-
- BMVert_OFlag *v_oflag;
- BLI_mempool *newpool = bm->vtoolflagpool;
- BM_ITER_MESH_INDEX (v_oflag, &iter, bm, BM_VERTS_OF_MESH, i) {
- void *oldflags = v_oflag->oflags;
- v_oflag->oflags = BLI_mempool_alloc(newpool);
- memcpy(v_oflag->oflags, oldflags, new_totflags_size);
- BM_elem_index_set(&v_oflag->base, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)v_oflag);
- }
-
- BMEdge_OFlag *e_oflag;
- newpool = bm->etoolflagpool;
- BM_ITER_MESH_INDEX (e_oflag, &iter, bm, BM_EDGES_OF_MESH, i) {
- void *oldflags = e_oflag->oflags;
- e_oflag->oflags = BLI_mempool_alloc(newpool);
- memcpy(e_oflag->oflags, oldflags, new_totflags_size);
- BM_elem_index_set(&e_oflag->base, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)e_oflag);
- }
-
- BMFace_OFlag *f_oflag;
- newpool = bm->ftoolflagpool;
- BM_ITER_MESH_INDEX (f_oflag, &iter, bm, BM_FACES_OF_MESH, i) {
- void *oldflags = f_oflag->oflags;
- f_oflag->oflags = BLI_mempool_alloc(newpool);
- memcpy(f_oflag->oflags, oldflags, new_totflags_size);
- BM_elem_index_set(&f_oflag->base, i); /* set_inline */
- BM_ELEM_API_FLAG_CLEAR((BMElemF *)f_oflag);
- }
-
- BLI_mempool_destroy(voldpool);
- BLI_mempool_destroy(eoldpool);
- BLI_mempool_destroy(foldpool);
-
- bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
+ /* set the index values since we are looping over all data anyway,
+ * may save time later on */
+
+ BLI_mempool *voldpool = bm->vtoolflagpool;
+ BLI_mempool *eoldpool = bm->etoolflagpool;
+ BLI_mempool *foldpool = bm->ftoolflagpool;
+
+ /* store memcpy size for reuse */
+ const size_t new_totflags_size = ((bm->totflags - 1) * sizeof(BMFlagLayer));
+
+ /* de-increment the totflags first.. */
+ bm->totflags--;
+
+ bm->vtoolflagpool = BLI_mempool_create(new_totflags_size, bm->totvert, 512, BLI_MEMPOOL_NOP);
+ bm->etoolflagpool = BLI_mempool_create(new_totflags_size, bm->totedge, 512, BLI_MEMPOOL_NOP);
+ bm->ftoolflagpool = BLI_mempool_create(new_totflags_size, bm->totface, 512, BLI_MEMPOOL_NOP);
+
+ /* now go through and memcpy all the flag */
+ BMIter iter;
+ int i;
+
+ BMVert_OFlag *v_oflag;
+ BLI_mempool *newpool = bm->vtoolflagpool;
+ BM_ITER_MESH_INDEX (v_oflag, &iter, bm, BM_VERTS_OF_MESH, i) {
+ void *oldflags = v_oflag->oflags;
+ v_oflag->oflags = BLI_mempool_alloc(newpool);
+ memcpy(v_oflag->oflags, oldflags, new_totflags_size);
+ BM_elem_index_set(&v_oflag->base, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)v_oflag);
+ }
+
+ BMEdge_OFlag *e_oflag;
+ newpool = bm->etoolflagpool;
+ BM_ITER_MESH_INDEX (e_oflag, &iter, bm, BM_EDGES_OF_MESH, i) {
+ void *oldflags = e_oflag->oflags;
+ e_oflag->oflags = BLI_mempool_alloc(newpool);
+ memcpy(e_oflag->oflags, oldflags, new_totflags_size);
+ BM_elem_index_set(&e_oflag->base, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)e_oflag);
+ }
+
+ BMFace_OFlag *f_oflag;
+ newpool = bm->ftoolflagpool;
+ BM_ITER_MESH_INDEX (f_oflag, &iter, bm, BM_FACES_OF_MESH, i) {
+ void *oldflags = f_oflag->oflags;
+ f_oflag->oflags = BLI_mempool_alloc(newpool);
+ memcpy(f_oflag->oflags, oldflags, new_totflags_size);
+ BM_elem_index_set(&f_oflag->base, i); /* set_inline */
+ BM_ELEM_API_FLAG_CLEAR((BMElemF *)f_oflag);
+ }
+
+ BLI_mempool_destroy(voldpool);
+ BLI_mempool_destroy(eoldpool);
+ BLI_mempool_destroy(foldpool);
+
+ bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
}
static void bmo_flag_layer_clear(BMesh *bm)
{
- /* set the index values since we are looping over all data anyway,
- * may save time later on */
- const BMFlagLayer zero_flag = {0};
-
- const int totflags_offset = bm->totflags - 1;
-
- /* now go through and memcpy all the flag */
- {
- BMIter iter;
- BMVert_OFlag *ele;
- int i;
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
- ele->oflags[totflags_offset] = zero_flag;
- BM_elem_index_set(&ele->base, i); /* set_inline */
- }
- }
- {
- BMIter iter;
- BMEdge_OFlag *ele;
- int i;
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
- ele->oflags[totflags_offset] = zero_flag;
- BM_elem_index_set(&ele->base, i); /* set_inline */
- }
- }
- {
- BMIter iter;
- BMFace_OFlag *ele;
- int i;
- BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
- ele->oflags[totflags_offset] = zero_flag;
- BM_elem_index_set(&ele->base, i); /* set_inline */
- }
- }
-
- bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
+ /* set the index values since we are looping over all data anyway,
+ * may save time later on */
+ const BMFlagLayer zero_flag = {0};
+
+ const int totflags_offset = bm->totflags - 1;
+
+ /* now go through and memcpy all the flag */
+ {
+ BMIter iter;
+ BMVert_OFlag *ele;
+ int i;
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_VERTS_OF_MESH, i) {
+ ele->oflags[totflags_offset] = zero_flag;
+ BM_elem_index_set(&ele->base, i); /* set_inline */
+ }
+ }
+ {
+ BMIter iter;
+ BMEdge_OFlag *ele;
+ int i;
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_EDGES_OF_MESH, i) {
+ ele->oflags[totflags_offset] = zero_flag;
+ BM_elem_index_set(&ele->base, i); /* set_inline */
+ }
+ }
+ {
+ BMIter iter;
+ BMFace_OFlag *ele;
+ int i;
+ BM_ITER_MESH_INDEX (ele, &iter, bm, BM_FACES_OF_MESH, i) {
+ ele->oflags[totflags_offset] = zero_flag;
+ BM_elem_index_set(&ele->base, i); /* set_inline */
+ }
+ }
+
+ bm->elem_index_dirty &= ~(BM_VERT | BM_EDGE | BM_FACE);
}
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);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF) {
- return NULL;
- }
+ if (slot->slot_type != BMO_OP_SLOT_ELEMENT_BUF) {
+ return NULL;
+ }
- return slot->data.buf ? *slot->data.buf : NULL;
+ return slot->data.buf ? *slot->data.buf : NULL;
}
/**
@@ -1405,78 +1454,77 @@ void *BMO_slot_buffer_get_first(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char
* \param restrictmask: restricts the iteration to certain element types
* (e.g. combination of BM_VERT, BM_EDGE, BM_FACE), if iterating
* over an element buffer (not a mapping). */
-void *BMO_iter_new(
- BMOIter *iter,
- BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name,
- const char restrictmask)
+void *BMO_iter_new(BMOIter *iter,
+ BMOpSlot slot_args[BMO_OP_MAX_SLOTS],
+ const char *slot_name,
+ const char restrictmask)
{
- BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
+ BMOpSlot *slot = BMO_slot_get(slot_args, slot_name);
- memset(iter, 0, sizeof(BMOIter));
+ memset(iter, 0, sizeof(BMOIter));
- iter->slot = slot;
- iter->cur = 0;
- iter->restrictmask = restrictmask;
+ iter->slot = slot;
+ iter->cur = 0;
+ iter->restrictmask = restrictmask;
- if (iter->slot->slot_type == BMO_OP_SLOT_MAPPING) {
- BLI_ghashIterator_init(&iter->giter, slot->data.ghash);
- }
- else if (iter->slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
- BLI_assert(restrictmask & slot->slot_subtype.elem);
- }
- else {
- BLI_assert(0);
- }
+ if (iter->slot->slot_type == BMO_OP_SLOT_MAPPING) {
+ BLI_ghashIterator_init(&iter->giter, slot->data.ghash);
+ }
+ else if (iter->slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
+ BLI_assert(restrictmask & slot->slot_subtype.elem);
+ }
+ else {
+ BLI_assert(0);
+ }
- return BMO_iter_step(iter);
+ return BMO_iter_step(iter);
}
void *BMO_iter_step(BMOIter *iter)
{
- BMOpSlot *slot = iter->slot;
- if (slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
- BMHeader *ele;
+ BMOpSlot *slot = iter->slot;
+ if (slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF) {
+ BMHeader *ele;
- if (iter->cur >= slot->len) {
- return NULL;
- }
+ if (iter->cur >= slot->len) {
+ return NULL;
+ }
- ele = slot->data.buf[iter->cur++];
- while (!(iter->restrictmask & ele->htype)) {
- if (iter->cur >= slot->len) {
- return NULL;
- }
+ ele = slot->data.buf[iter->cur++];
+ while (!(iter->restrictmask & ele->htype)) {
+ if (iter->cur >= slot->len) {
+ return NULL;
+ }
- ele = slot->data.buf[iter->cur++];
- BLI_assert((ele == NULL) || (slot->slot_subtype.elem & ele->htype));
- }
+ ele = slot->data.buf[iter->cur++];
+ BLI_assert((ele == NULL) || (slot->slot_subtype.elem & ele->htype));
+ }
- BLI_assert((ele == NULL) || (slot->slot_subtype.elem & ele->htype));
+ BLI_assert((ele == NULL) || (slot->slot_subtype.elem & ele->htype));
- return ele;
- }
- else if (slot->slot_type == BMO_OP_SLOT_MAPPING) {
- void *ret;
+ return ele;
+ }
+ else if (slot->slot_type == BMO_OP_SLOT_MAPPING) {
+ void *ret;
+ if (BLI_ghashIterator_done(&iter->giter) == false) {
+ ret = BLI_ghashIterator_getKey(&iter->giter);
+ iter->val = BLI_ghashIterator_getValue_p(&iter->giter);
- if (BLI_ghashIterator_done(&iter->giter) == false) {
- ret = BLI_ghashIterator_getKey(&iter->giter);
- iter->val = BLI_ghashIterator_getValue_p(&iter->giter);
+ BLI_ghashIterator_step(&iter->giter);
+ }
+ else {
+ ret = NULL;
+ iter->val = NULL;
+ }
- BLI_ghashIterator_step(&iter->giter);
- }
- else {
- ret = NULL;
- iter->val = NULL;
- }
+ return ret;
+ }
+ else {
+ BLI_assert(0);
+ }
- return ret;
- }
- else {
- BLI_assert(0);
- }
-
- return NULL;
+ return NULL;
}
/* used for iterating over mappings */
@@ -1487,149 +1535,154 @@ void *BMO_iter_step(BMOIter *iter)
*/
void **BMO_iter_map_value_p(BMOIter *iter)
{
- return iter->val;
+ return iter->val;
}
void *BMO_iter_map_value_ptr(BMOIter *iter)
{
- BLI_assert(ELEM(iter->slot->slot_subtype.map,
- BMO_OP_SLOT_SUBTYPE_MAP_ELEM, BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL));
- return iter->val ? *iter->val : NULL;
+ BLI_assert(ELEM(iter->slot->slot_subtype.map,
+ BMO_OP_SLOT_SUBTYPE_MAP_ELEM,
+ BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL));
+ return iter->val ? *iter->val : NULL;
}
-
float BMO_iter_map_value_float(BMOIter *iter)
{
- BLI_assert(iter->slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
- return **((float **)iter->val);
+ BLI_assert(iter->slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
+ return **((float **)iter->val);
}
int BMO_iter_map_value_int(BMOIter *iter)
{
- BLI_assert(iter->slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
- return **((int **)iter->val);
+ BLI_assert(iter->slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
+ return **((int **)iter->val);
}
bool BMO_iter_map_value_bool(BMOIter *iter)
{
- BLI_assert(iter->slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
- return **((bool **)iter->val);
+ BLI_assert(iter->slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
+ return **((bool **)iter->val);
}
/* error system */
typedef struct BMOpError {
- struct BMOpError *next, *prev;
- int errorcode;
- BMOperator *op;
- const char *msg;
+ struct BMOpError *next, *prev;
+ int errorcode;
+ BMOperator *op;
+ const char *msg;
} BMOpError;
void BMO_error_clear(BMesh *bm)
{
- while (BMO_error_pop(bm, NULL, NULL)) {
- /* pass */
- }
+ while (BMO_error_pop(bm, NULL, NULL)) {
+ /* pass */
+ }
}
void BMO_error_raise(BMesh *bm, BMOperator *owner, int errcode, const char *msg)
{
- BMOpError *err = MEM_callocN(sizeof(BMOpError), "bmop_error");
+ BMOpError *err = MEM_callocN(sizeof(BMOpError), "bmop_error");
- err->errorcode = errcode;
- if (!msg) {
- msg = bmo_error_messages[errcode];
- }
- err->msg = msg;
- err->op = owner;
+ err->errorcode = errcode;
+ if (!msg) {
+ msg = bmo_error_messages[errcode];
+ }
+ err->msg = msg;
+ err->op = owner;
- BLI_addhead(&bm->errorstack, err);
+ BLI_addhead(&bm->errorstack, err);
}
bool BMO_error_occurred(BMesh *bm)
{
- return (BLI_listbase_is_empty(&bm->errorstack) == false);
+ return (BLI_listbase_is_empty(&bm->errorstack) == false);
}
/* returns error code or 0 if no error */
int BMO_error_get(BMesh *bm, const char **msg, BMOperator **op)
{
- BMOpError *err = bm->errorstack.first;
- if (!err) {
- return 0;
- }
+ BMOpError *err = bm->errorstack.first;
+ if (!err) {
+ return 0;
+ }
- if (msg) {
- *msg = err->msg;
- }
- if (op) {
- *op = err->op;
- }
+ if (msg) {
+ *msg = err->msg;
+ }
+ if (op) {
+ *op = err->op;
+ }
- return err->errorcode;
+ return err->errorcode;
}
int BMO_error_pop(BMesh *bm, const char **msg, BMOperator **op)
{
- int errorcode = BMO_error_get(bm, msg, op);
+ int errorcode = BMO_error_get(bm, msg, op);
- if (errorcode) {
- BMOpError *err = bm->errorstack.first;
+ if (errorcode) {
+ BMOpError *err = bm->errorstack.first;
- BLI_remlink(&bm->errorstack, bm->errorstack.first);
- MEM_freeN(err);
- }
+ BLI_remlink(&bm->errorstack, bm->errorstack.first);
+ MEM_freeN(err);
+ }
- return errorcode;
+ return errorcode;
}
-
#define NEXT_CHAR(fmt) ((fmt)[0] != 0 ? (fmt)[1] : 0)
static int bmo_name_to_slotcode(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
{
- int i = 0;
+ int i = 0;
- while (slot_args->slot_name) {
- if (STREQLEN(identifier, slot_args->slot_name, MAX_SLOTNAME)) {
- return i;
- }
- slot_args++;
- i++;
- }
+ while (slot_args->slot_name) {
+ if (STREQLEN(identifier, slot_args->slot_name, MAX_SLOTNAME)) {
+ return i;
+ }
+ slot_args++;
+ i++;
+ }
- return -1;
+ return -1;
}
static int bmo_name_to_slotcode_check(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *identifier)
{
- int i = bmo_name_to_slotcode(slot_args, identifier);
- if (i < 0) {
- fprintf(stderr, "%s: ! could not find bmesh slot for name %s! (bmesh internal error)\n", __func__, identifier);
- }
+ int i = bmo_name_to_slotcode(slot_args, identifier);
+ if (i < 0) {
+ fprintf(stderr,
+ "%s: ! could not find bmesh slot for name %s! (bmesh internal error)\n",
+ __func__,
+ identifier);
+ }
- return i;
+ return i;
}
int BMO_opcode_from_opname(const char *opname)
{
- const uint tot = bmo_opdefines_total;
- uint i;
- for (i = 0; i < tot; i++) {
- if (STREQ(bmo_opdefines[i]->opname, opname)) {
- return i;
- }
- }
- return -1;
+ const uint tot = bmo_opdefines_total;
+ uint i;
+ for (i = 0; i < tot; i++) {
+ if (STREQ(bmo_opdefines[i]->opname, opname)) {
+ return i;
+ }
+ }
+ return -1;
}
static int BMO_opcode_from_opname_check(const char *opname)
{
- int i = BMO_opcode_from_opname(opname);
- if (i == -1) {
- fprintf(stderr, "%s: could not find bmesh slot for name %s! (bmesh internal error)\n", __func__, opname);
- }
- return i;
+ int i = BMO_opcode_from_opname(opname);
+ if (i == -1) {
+ fprintf(stderr,
+ "%s: could not find bmesh slot for name %s! (bmesh internal error)\n",
+ __func__,
+ opname);
+ }
+ return i;
}
/**
@@ -1688,283 +1741,294 @@ static int BMO_opcode_from_opname_check(const char *opname)
bool BMO_op_vinitf(BMesh *bm, BMOperator *op, const int flag, const char *_fmt, va_list vlist)
{
-// BMOpDefine *def;
- char *opname, *ofmt, *fmt;
- char slot_name[64] = {0};
- int i, type;
- bool noslot, state;
-
-
- /* basic useful info to help find where bmop formatting strings fail */
- const char *err_reason = "Unknown";
- int lineno = -1;
-
-#define GOTO_ERROR(reason) \
- { \
- err_reason = reason; \
- lineno = __LINE__; \
- goto error; \
- } (void)0
-
- /* we muck around in here, so dup it */
- fmt = ofmt = BLI_strdup(_fmt);
-
- /* find operator name */
- i = strcspn(fmt, " ");
-
- opname = fmt;
- noslot = (opname[i] == '\0');
- opname[i] = '\0';
-
- fmt += i + (noslot ? 0 : 1);
-
- i = BMO_opcode_from_opname_check(opname);
-
- if (i == -1) {
- MEM_freeN(ofmt);
- BLI_assert(0);
- return false;
- }
-
- BMO_op_init(bm, op, flag, opname);
-// def = bmo_opdefines[i];
-
- i = 0;
- state = true; /* false: not inside slot_code name, true: inside slot_code name */
-
- while (*fmt) {
- if (state) {
- /* jump past leading whitespace */
- i = strspn(fmt, " ");
- fmt += i;
-
- /* ignore trailing whitespace */
- if (!fmt[i]) {
- break;
- }
-
- /* find end of slot name, only "slot=%f", can be used */
- i = strcspn(fmt, "=");
- if (!fmt[i]) {
- GOTO_ERROR("could not match end of slot name");
- }
-
- fmt[i] = 0;
-
- if (bmo_name_to_slotcode_check(op->slots_in, fmt) < 0) {
- GOTO_ERROR("name to slot code check failed");
- }
-
- BLI_strncpy(slot_name, fmt, sizeof(slot_name));
-
- state = false;
- fmt += i;
- }
- else {
- switch (*fmt) {
- case ' ':
- case '=':
- case '%':
- break;
- case 'm':
- {
- int size;
- const char c = NEXT_CHAR(fmt);
- fmt++;
-
- if (c == '3') { size = 3; }
- else if (c == '4') { size = 4; }
- else { GOTO_ERROR("matrix size was not 3 or 4"); }
-
- BMO_slot_mat_set(op, op->slots_in, slot_name, va_arg(vlist, void *), size);
- state = true;
- break;
- }
- case 'v':
- {
- BMO_slot_vec_set(op->slots_in, slot_name, va_arg(vlist, float *));
- state = true;
- break;
- }
- case 'e':
- {
- BMOpSlot *slot = BMO_slot_get(op->slots_in, slot_name);
-
- if (NEXT_CHAR(fmt) == 'b') {
- BMHeader **ele_buffer = va_arg(vlist, void *);
- int ele_buffer_len = va_arg(vlist, int);
-
- BMO_slot_buffer_from_array(op, slot, ele_buffer, ele_buffer_len);
- fmt++;
- }
- else {
- /* single vert/edge/face */
- BMHeader *ele = va_arg(vlist, void *);
-
- BMO_slot_buffer_from_single(op, slot, ele);
- }
-
- state = true;
- break;
- }
- case 's':
- case 'S':
- {
- BMOperator *op_other = va_arg(vlist, void *);
- const char *slot_name_other = va_arg(vlist, char *);
-
- if (*fmt == 's') {
- BLI_assert(bmo_name_to_slotcode_check(op_other->slots_in, slot_name_other) != -1);
- BMO_slot_copy(op_other, slots_in, slot_name_other,
- op, slots_in, slot_name);
- }
- else {
- BLI_assert(bmo_name_to_slotcode_check(op_other->slots_out, slot_name_other) != -1);
- BMO_slot_copy(op_other, slots_out, slot_name_other,
- op, slots_in, slot_name);
- }
- state = true;
- break;
- }
- case 'i':
- BMO_slot_int_set(op->slots_in, slot_name, va_arg(vlist, int));
- state = true;
- break;
- case 'b':
- BMO_slot_bool_set(op->slots_in, slot_name, va_arg(vlist, int));
- state = true;
- break;
- case 'p':
- BMO_slot_ptr_set(op->slots_in, slot_name, va_arg(vlist, void *));
- state = true;
- break;
- case 'f':
- case 'F':
- case 'h':
- case 'H':
- case 'a':
- type = *fmt;
-
- if (NEXT_CHAR(fmt) == ' ' || NEXT_CHAR(fmt) == '\0') {
- BMO_slot_float_set(op->slots_in, slot_name, va_arg(vlist, double));
- }
- else {
- char htype = 0;
-
- while (1) {
- char htype_set;
- const char c = NEXT_CHAR(fmt);
- if (c == 'f') { htype_set = BM_FACE; }
- else if (c == 'e') { htype_set = BM_EDGE; }
- else if (c == 'v') { htype_set = BM_VERT; }
- else {
- break;
- }
-
- if (UNLIKELY(htype & htype_set)) {
- GOTO_ERROR("htype duplicated");
- }
-
- htype |= htype_set;
- fmt++;
- }
-
- if (type == 'h') {
- BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
- }
- else if (type == 'H') {
- BMO_slot_buffer_from_disabled_hflag(bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
- }
- else if (type == 'a') {
- if ((op->flag & BMO_FLAG_RESPECT_HIDE) == 0) {
- BMO_slot_buffer_from_all(bm, op, op->slots_in, slot_name, htype);
- }
- else {
- BMO_slot_buffer_from_disabled_hflag(bm, op, op->slots_in, slot_name, htype, BM_ELEM_HIDDEN);
- }
- }
- else if (type == 'f') {
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
- }
- else if (type == 'F') {
- BMO_slot_buffer_from_disabled_flag(bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
- }
- }
-
- state = true;
- break;
- default:
- fprintf(stderr,
- "%s: unrecognized bmop format char: '%c', %d in '%s'\n",
- __func__, *fmt, (int)(fmt - ofmt), ofmt);
- break;
- }
- }
- fmt++;
- }
-
- MEM_freeN(ofmt);
- return true;
+ // BMOpDefine *def;
+ char *opname, *ofmt, *fmt;
+ char slot_name[64] = {0};
+ int i, type;
+ bool noslot, state;
+
+ /* basic useful info to help find where bmop formatting strings fail */
+ const char *err_reason = "Unknown";
+ int lineno = -1;
+
+#define GOTO_ERROR(reason) \
+ { \
+ err_reason = reason; \
+ lineno = __LINE__; \
+ goto error; \
+ } \
+ (void)0
+
+ /* we muck around in here, so dup it */
+ fmt = ofmt = BLI_strdup(_fmt);
+
+ /* find operator name */
+ i = strcspn(fmt, " ");
+
+ opname = fmt;
+ noslot = (opname[i] == '\0');
+ opname[i] = '\0';
+
+ fmt += i + (noslot ? 0 : 1);
+
+ i = BMO_opcode_from_opname_check(opname);
+
+ if (i == -1) {
+ MEM_freeN(ofmt);
+ BLI_assert(0);
+ return false;
+ }
+
+ BMO_op_init(bm, op, flag, opname);
+ // def = bmo_opdefines[i];
+
+ i = 0;
+ state = true; /* false: not inside slot_code name, true: inside slot_code name */
+
+ while (*fmt) {
+ if (state) {
+ /* jump past leading whitespace */
+ i = strspn(fmt, " ");
+ fmt += i;
+
+ /* ignore trailing whitespace */
+ if (!fmt[i]) {
+ break;
+ }
+
+ /* find end of slot name, only "slot=%f", can be used */
+ i = strcspn(fmt, "=");
+ if (!fmt[i]) {
+ GOTO_ERROR("could not match end of slot name");
+ }
+
+ fmt[i] = 0;
+
+ if (bmo_name_to_slotcode_check(op->slots_in, fmt) < 0) {
+ GOTO_ERROR("name to slot code check failed");
+ }
+
+ BLI_strncpy(slot_name, fmt, sizeof(slot_name));
+
+ state = false;
+ fmt += i;
+ }
+ else {
+ switch (*fmt) {
+ case ' ':
+ case '=':
+ case '%':
+ break;
+ case 'm': {
+ int size;
+ const char c = NEXT_CHAR(fmt);
+ fmt++;
+
+ if (c == '3') {
+ size = 3;
+ }
+ else if (c == '4') {
+ size = 4;
+ }
+ else {
+ GOTO_ERROR("matrix size was not 3 or 4");
+ }
+
+ BMO_slot_mat_set(op, op->slots_in, slot_name, va_arg(vlist, void *), size);
+ state = true;
+ break;
+ }
+ case 'v': {
+ BMO_slot_vec_set(op->slots_in, slot_name, va_arg(vlist, float *));
+ state = true;
+ break;
+ }
+ case 'e': {
+ BMOpSlot *slot = BMO_slot_get(op->slots_in, slot_name);
+
+ if (NEXT_CHAR(fmt) == 'b') {
+ BMHeader **ele_buffer = va_arg(vlist, void *);
+ int ele_buffer_len = va_arg(vlist, int);
+
+ BMO_slot_buffer_from_array(op, slot, ele_buffer, ele_buffer_len);
+ fmt++;
+ }
+ else {
+ /* single vert/edge/face */
+ BMHeader *ele = va_arg(vlist, void *);
+
+ BMO_slot_buffer_from_single(op, slot, ele);
+ }
+
+ state = true;
+ break;
+ }
+ case 's':
+ case 'S': {
+ BMOperator *op_other = va_arg(vlist, void *);
+ const char *slot_name_other = va_arg(vlist, char *);
+
+ if (*fmt == 's') {
+ BLI_assert(bmo_name_to_slotcode_check(op_other->slots_in, slot_name_other) != -1);
+ BMO_slot_copy(op_other, slots_in, slot_name_other, op, slots_in, slot_name);
+ }
+ else {
+ BLI_assert(bmo_name_to_slotcode_check(op_other->slots_out, slot_name_other) != -1);
+ BMO_slot_copy(op_other, slots_out, slot_name_other, op, slots_in, slot_name);
+ }
+ state = true;
+ break;
+ }
+ case 'i':
+ BMO_slot_int_set(op->slots_in, slot_name, va_arg(vlist, int));
+ state = true;
+ break;
+ case 'b':
+ BMO_slot_bool_set(op->slots_in, slot_name, va_arg(vlist, int));
+ state = true;
+ break;
+ case 'p':
+ BMO_slot_ptr_set(op->slots_in, slot_name, va_arg(vlist, void *));
+ state = true;
+ break;
+ case 'f':
+ case 'F':
+ case 'h':
+ case 'H':
+ case 'a':
+ type = *fmt;
+
+ if (NEXT_CHAR(fmt) == ' ' || NEXT_CHAR(fmt) == '\0') {
+ BMO_slot_float_set(op->slots_in, slot_name, va_arg(vlist, double));
+ }
+ else {
+ char htype = 0;
+
+ while (1) {
+ char htype_set;
+ const char c = NEXT_CHAR(fmt);
+ if (c == 'f') {
+ htype_set = BM_FACE;
+ }
+ else if (c == 'e') {
+ htype_set = BM_EDGE;
+ }
+ else if (c == 'v') {
+ htype_set = BM_VERT;
+ }
+ else {
+ break;
+ }
+
+ if (UNLIKELY(htype & htype_set)) {
+ GOTO_ERROR("htype duplicated");
+ }
+
+ htype |= htype_set;
+ fmt++;
+ }
+
+ if (type == 'h') {
+ BMO_slot_buffer_from_enabled_hflag(
+ bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
+ }
+ else if (type == 'H') {
+ BMO_slot_buffer_from_disabled_hflag(
+ bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
+ }
+ else if (type == 'a') {
+ if ((op->flag & BMO_FLAG_RESPECT_HIDE) == 0) {
+ BMO_slot_buffer_from_all(bm, op, op->slots_in, slot_name, htype);
+ }
+ else {
+ BMO_slot_buffer_from_disabled_hflag(
+ bm, op, op->slots_in, slot_name, htype, BM_ELEM_HIDDEN);
+ }
+ }
+ else if (type == 'f') {
+ BMO_slot_buffer_from_enabled_flag(
+ bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
+ }
+ else if (type == 'F') {
+ BMO_slot_buffer_from_disabled_flag(
+ bm, op, op->slots_in, slot_name, htype, va_arg(vlist, int));
+ }
+ }
+
+ state = true;
+ break;
+ default:
+ fprintf(stderr,
+ "%s: unrecognized bmop format char: '%c', %d in '%s'\n",
+ __func__,
+ *fmt,
+ (int)(fmt - ofmt),
+ ofmt);
+ break;
+ }
+ }
+ fmt++;
+ }
+
+ MEM_freeN(ofmt);
+ return true;
error:
- /* non urgent todo - explain exactly what is failing */
- fprintf(stderr, "%s: error parsing formatting string\n", __func__);
-
- fprintf(stderr, "string: '%s', position %d\n", _fmt, (int)(fmt - ofmt));
- fprintf(stderr, " ");
- {
- int pos = (int)(fmt - ofmt);
- for (i = 0; i < pos; i++) {
- fprintf(stderr, " ");
- }
- fprintf(stderr, "^\n");
- }
+ /* non urgent todo - explain exactly what is failing */
+ fprintf(stderr, "%s: error parsing formatting string\n", __func__);
- fprintf(stderr, "source code: %s:%d\n", __FILE__, lineno);
+ fprintf(stderr, "string: '%s', position %d\n", _fmt, (int)(fmt - ofmt));
+ fprintf(stderr, " ");
+ {
+ int pos = (int)(fmt - ofmt);
+ for (i = 0; i < pos; i++) {
+ fprintf(stderr, " ");
+ }
+ fprintf(stderr, "^\n");
+ }
- fprintf(stderr, "reason: %s\n", err_reason);
+ fprintf(stderr, "source code: %s:%d\n", __FILE__, lineno);
+ fprintf(stderr, "reason: %s\n", err_reason);
- MEM_freeN(ofmt);
+ MEM_freeN(ofmt);
- BMO_op_finish(bm, op);
- return false;
+ BMO_op_finish(bm, op);
+ return false;
#undef GOTO_ERROR
-
}
-
bool BMO_op_initf(BMesh *bm, BMOperator *op, const int flag, const char *fmt, ...)
{
- va_list list;
+ va_list list;
- va_start(list, fmt);
- if (!BMO_op_vinitf(bm, op, flag, fmt, list)) {
- printf("%s: failed\n", __func__);
- va_end(list);
- return false;
- }
- va_end(list);
+ va_start(list, fmt);
+ if (!BMO_op_vinitf(bm, op, flag, fmt, list)) {
+ printf("%s: failed\n", __func__);
+ va_end(list);
+ return false;
+ }
+ va_end(list);
- return true;
+ return true;
}
bool BMO_op_callf(BMesh *bm, const int flag, const char *fmt, ...)
{
- va_list list;
- BMOperator op;
+ va_list list;
+ BMOperator op;
- va_start(list, fmt);
- if (!BMO_op_vinitf(bm, &op, flag, fmt, list)) {
- printf("%s: failed, format is:\n \"%s\"\n", __func__, fmt);
- va_end(list);
- return false;
- }
+ va_start(list, fmt);
+ if (!BMO_op_vinitf(bm, &op, flag, fmt, list)) {
+ printf("%s: failed, format is:\n \"%s\"\n", __func__, fmt);
+ va_end(list);
+ return false;
+ }
- BMO_op_exec(bm, &op);
- BMO_op_finish(bm, &op);
+ BMO_op_exec(bm, &op);
+ BMO_op_finish(bm, &op);
- va_end(list);
- return true;
+ va_end(list);
+ return true;
}
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 6c0a6854d8e..0279e4dd23e 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -27,132 +27,143 @@
/*quad innervert values*/
enum {
- SUBD_CORNER_INNERVERT,
- SUBD_CORNER_PATH,
- SUBD_CORNER_FAN,
- SUBD_CORNER_STRAIGHT_CUT,
+ SUBD_CORNER_INNERVERT,
+ SUBD_CORNER_PATH,
+ SUBD_CORNER_FAN,
+ SUBD_CORNER_STRAIGHT_CUT,
};
/* aligned with PROP_SMOOTH and friends */
enum {
- SUBD_FALLOFF_SMOOTH = 0,
- SUBD_FALLOFF_SPHERE,
- SUBD_FALLOFF_ROOT,
- SUBD_FALLOFF_SHARP,
- SUBD_FALLOFF_LIN,
- SUBD_FALLOFF_INVSQUARE = 7, /* matching PROP_INVSQUARE */
+ SUBD_FALLOFF_SMOOTH = 0,
+ SUBD_FALLOFF_SPHERE,
+ SUBD_FALLOFF_ROOT,
+ SUBD_FALLOFF_SHARP,
+ SUBD_FALLOFF_LIN,
+ SUBD_FALLOFF_INVSQUARE = 7, /* matching PROP_INVSQUARE */
};
enum {
- SUBDIV_SELECT_NONE,
- SUBDIV_SELECT_ORIG,
- SUBDIV_SELECT_INNER,
- SUBDIV_SELECT_LOOPCUT,
+ SUBDIV_SELECT_NONE,
+ SUBDIV_SELECT_ORIG,
+ SUBDIV_SELECT_INNER,
+ SUBDIV_SELECT_LOOPCUT,
};
/* subdivide_edgering */
enum {
- /* just subdiv */
- SUBD_RING_INTERP_LINEAR,
+ /* just subdiv */
+ SUBD_RING_INTERP_LINEAR,
- /* single bezier spline - curve follows bezier rotation */
- SUBD_RING_INTERP_PATH,
+ /* single bezier spline - curve follows bezier rotation */
+ SUBD_RING_INTERP_PATH,
- /* beziers based on adjacent faces (fallback to tangent) */
- SUBD_RING_INTERP_SURF,
+ /* beziers based on adjacent faces (fallback to tangent) */
+ SUBD_RING_INTERP_SURF,
};
/* similar face selection slot values */
enum {
- SIMFACE_MATERIAL = 201,
- SIMFACE_AREA,
- SIMFACE_SIDES,
- SIMFACE_PERIMETER,
- SIMFACE_NORMAL,
- SIMFACE_COPLANAR,
- SIMFACE_SMOOTH,
- SIMFACE_FACEMAP,
- SIMFACE_FREESTYLE,
+ SIMFACE_MATERIAL = 201,
+ SIMFACE_AREA,
+ SIMFACE_SIDES,
+ SIMFACE_PERIMETER,
+ SIMFACE_NORMAL,
+ SIMFACE_COPLANAR,
+ SIMFACE_SMOOTH,
+ SIMFACE_FACEMAP,
+ SIMFACE_FREESTYLE,
};
/* similar edge selection slot values */
enum {
- SIMEDGE_LENGTH = 101,
- SIMEDGE_DIR,
- SIMEDGE_FACE,
- SIMEDGE_FACE_ANGLE,
- SIMEDGE_CREASE,
- SIMEDGE_BEVEL,
- SIMEDGE_SEAM,
- SIMEDGE_SHARP,
- SIMEDGE_FREESTYLE,
+ SIMEDGE_LENGTH = 101,
+ SIMEDGE_DIR,
+ SIMEDGE_FACE,
+ SIMEDGE_FACE_ANGLE,
+ SIMEDGE_CREASE,
+ SIMEDGE_BEVEL,
+ SIMEDGE_SEAM,
+ SIMEDGE_SHARP,
+ SIMEDGE_FREESTYLE,
};
/* similar vertex selection slot values */
enum {
- SIMVERT_NORMAL = 0,
- SIMVERT_FACE,
- SIMVERT_VGROUP,
- SIMVERT_EDGE,
+ SIMVERT_NORMAL = 0,
+ SIMVERT_FACE,
+ SIMVERT_VGROUP,
+ SIMVERT_EDGE,
};
/* Poke face center calculation */
enum {
- BMOP_POKE_MEDIAN_WEIGHTED = 0,
- BMOP_POKE_MEDIAN,
- BMOP_POKE_BOUNDS,
+ BMOP_POKE_MEDIAN_WEIGHTED = 0,
+ BMOP_POKE_MEDIAN,
+ BMOP_POKE_BOUNDS,
};
/* Bevel offset_type slot values */
enum {
- BEVEL_AMT_OFFSET,
- BEVEL_AMT_WIDTH,
- BEVEL_AMT_DEPTH,
- BEVEL_AMT_PERCENT,
+ BEVEL_AMT_OFFSET,
+ BEVEL_AMT_WIDTH,
+ BEVEL_AMT_DEPTH,
+ BEVEL_AMT_PERCENT,
};
/* Bevel face_strength_mode values: should match face_str mode enum in DNA_modifer_types.h */
enum {
- BEVEL_FACE_STRENGTH_NONE,
- BEVEL_FACE_STRENGTH_NEW,
- BEVEL_FACE_STRENGTH_AFFECTED,
- BEVEL_FACE_STRENGTH_ALL,
+ BEVEL_FACE_STRENGTH_NONE,
+ BEVEL_FACE_STRENGTH_NEW,
+ BEVEL_FACE_STRENGTH_AFFECTED,
+ BEVEL_FACE_STRENGTH_ALL,
};
/* Bevel miter slot values */
enum {
- BEVEL_MITER_SHARP,
- BEVEL_MITER_PATCH,
- BEVEL_MITER_ARC,
+ BEVEL_MITER_SHARP,
+ BEVEL_MITER_PATCH,
+ BEVEL_MITER_ARC,
};
extern const BMOpDefine *bmo_opdefines[];
-extern const int bmo_opdefines_total;
+extern const int bmo_opdefines_total;
/*------specific operator helper functions-------*/
-void BM_mesh_esubdivide(
- BMesh *bm, const char edge_hflag,
- const float smooth, const short smooth_falloff, const bool use_smooth_even,
- const float fractal, const float along_normal,
- const int numcuts,
- const int seltype, const int cornertype,
- const short use_single_edge, const short use_grid_fill,
- const short use_only_quads,
- const int seed);
-
-void BM_mesh_calc_uvs_grid(
- BMesh *bm, const uint x_segments, const uint y_segments,
- const short oflag, const int cd_loop_uv_offset);
-void BM_mesh_calc_uvs_sphere(
- BMesh *bm,
- const short oflag, const int cd_loop_uv_offset);
-void BM_mesh_calc_uvs_circle(
- BMesh *bm, float mat[4][4], const float radius,
- const short oflag, const int cd_loop_uv_offset);
-void BM_mesh_calc_uvs_cone(
- BMesh *bm, float mat[4][4],
- const float radius_top, const float radius_bottom, const int segments, const bool cap_ends,
- const short oflag, const int cd_loop_uv_offset);
+void BM_mesh_esubdivide(BMesh *bm,
+ const char edge_hflag,
+ const float smooth,
+ const short smooth_falloff,
+ const bool use_smooth_even,
+ const float fractal,
+ const float along_normal,
+ const int numcuts,
+ const int seltype,
+ const int cornertype,
+ const short use_single_edge,
+ const short use_grid_fill,
+ const short use_only_quads,
+ const int seed);
+
+void BM_mesh_calc_uvs_grid(BMesh *bm,
+ const uint x_segments,
+ const uint y_segments,
+ const short oflag,
+ const int cd_loop_uv_offset);
+void BM_mesh_calc_uvs_sphere(BMesh *bm, const short oflag, const int cd_loop_uv_offset);
+void BM_mesh_calc_uvs_circle(BMesh *bm,
+ float mat[4][4],
+ const float radius,
+ const short oflag,
+ const int cd_loop_uv_offset);
+void BM_mesh_calc_uvs_cone(BMesh *bm,
+ float mat[4][4],
+ const float radius_top,
+ const float radius_bottom,
+ const int segments,
+ const bool cap_ends,
+ const short oflag,
+ const int cd_loop_uv_offset);
void BM_mesh_calc_uvs_cube(BMesh *bm, const short oflag);
#include "intern/bmesh_operator_api_inline.h"
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 4cc3cf3e4c1..2a734c242ba 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -50,24 +50,24 @@
*/
static float bm_face_calc_poly_normal(const BMFace *f, float n[3])
{
- BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
- BMLoop *l_iter = l_first;
- const float *v_prev = l_first->prev->v->co;
- const float *v_curr = l_first->v->co;
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter = l_first;
+ const float *v_prev = l_first->prev->v->co;
+ const float *v_curr = l_first->v->co;
- zero_v3(n);
+ zero_v3(n);
- /* Newell's Method */
- do {
- add_newell_cross_v3_v3v3(n, v_prev, v_curr);
+ /* Newell's Method */
+ do {
+ add_newell_cross_v3_v3v3(n, v_prev, v_curr);
- l_iter = l_iter->next;
- v_prev = v_curr;
- v_curr = l_iter->v->co;
+ l_iter = l_iter->next;
+ v_prev = v_curr;
+ v_curr = l_iter->v->co;
- } while (l_iter != l_first);
+ } while (l_iter != l_first);
- return normalize_v3(n);
+ return normalize_v3(n);
}
/**
@@ -76,46 +76,46 @@ static float bm_face_calc_poly_normal(const BMFace *f, float n[3])
* Same as #bm_face_calc_poly_normal
* but takes an array of vertex locations.
*/
-static float bm_face_calc_poly_normal_vertex_cos(
- const BMFace *f, float r_no[3],
- float const (*vertexCos)[3])
+static float bm_face_calc_poly_normal_vertex_cos(const BMFace *f,
+ float r_no[3],
+ float const (*vertexCos)[3])
{
- BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
- BMLoop *l_iter = l_first;
- const float *v_prev = vertexCos[BM_elem_index_get(l_first->prev->v)];
- const float *v_curr = vertexCos[BM_elem_index_get(l_first->v)];
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter = l_first;
+ const float *v_prev = vertexCos[BM_elem_index_get(l_first->prev->v)];
+ const float *v_curr = vertexCos[BM_elem_index_get(l_first->v)];
- zero_v3(r_no);
+ zero_v3(r_no);
- /* Newell's Method */
- do {
- add_newell_cross_v3_v3v3(r_no, v_prev, v_curr);
+ /* Newell's Method */
+ do {
+ add_newell_cross_v3_v3v3(r_no, v_prev, v_curr);
- l_iter = l_iter->next;
- v_prev = v_curr;
- v_curr = vertexCos[BM_elem_index_get(l_iter->v)];
- } while (l_iter != l_first);
+ l_iter = l_iter->next;
+ v_prev = v_curr;
+ v_curr = vertexCos[BM_elem_index_get(l_iter->v)];
+ } while (l_iter != l_first);
- return normalize_v3(r_no);
+ return normalize_v3(r_no);
}
/**
* \brief COMPUTE POLY CENTER (BMFace)
*/
-static void bm_face_calc_poly_center_median_vertex_cos(
- const BMFace *f, float r_cent[3],
- float const (*vertexCos)[3])
+static void bm_face_calc_poly_center_median_vertex_cos(const BMFace *f,
+ float r_cent[3],
+ float const (*vertexCos)[3])
{
- const BMLoop *l_first, *l_iter;
+ const BMLoop *l_first, *l_iter;
- zero_v3(r_cent);
+ zero_v3(r_cent);
- /* Newell's Method */
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- add_v3_v3(r_cent, vertexCos[BM_elem_index_get(l_iter->v)]);
- } while ((l_iter = l_iter->next) != l_first);
- mul_v3_fl(r_cent, 1.0f / f->len);
+ /* Newell's Method */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ add_v3_v3(r_cent, vertexCos[BM_elem_index_get(l_iter->v)]);
+ } while ((l_iter = l_iter->next) != l_first);
+ mul_v3_fl(r_cent, 1.0f / f->len);
}
/**
@@ -126,54 +126,55 @@ static void bm_face_calc_poly_center_median_vertex_cos(
* \param r_loops: Store face loop pointers, (f->len)
* \param r_index: Store triangle triples, indices into \a r_loops, `((f->len - 2) * 3)`
*/
-void BM_face_calc_tessellation(
- const BMFace *f, const bool use_fixed_quad,
- BMLoop **r_loops, uint (*r_index)[3])
+void BM_face_calc_tessellation(const BMFace *f,
+ const bool use_fixed_quad,
+ BMLoop **r_loops,
+ uint (*r_index)[3])
{
- BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
- BMLoop *l_iter;
-
- 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] = 0;
- r_index[0][1] = 1;
- r_index[0][2] = 2;
- }
- else if (f->len == 4 && use_fixed_quad) {
- *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] = 0;
- r_index[0][1] = 1;
- r_index[0][2] = 2;
-
- r_index[1][0] = 0;
- r_index[1][1] = 2;
- r_index[1][2] = 3;
- }
- else {
- float axis_mat[3][3];
- float (*projverts)[2] = BLI_array_alloca(projverts, f->len);
- int j;
-
- axis_dominant_v3_to_m3(axis_mat, f->no);
-
- j = 0;
- l_iter = l_first;
- do {
- mul_v2_m3v3(projverts[j], axis_mat, l_iter->v->co);
- r_loops[j] = l_iter;
- j++;
- } while ((l_iter = l_iter->next) != l_first);
-
- /* complete the loop */
- BLI_polyfill_calc(projverts, f->len, -1, r_index);
- }
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l_iter;
+
+ 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] = 0;
+ r_index[0][1] = 1;
+ r_index[0][2] = 2;
+ }
+ else if (f->len == 4 && use_fixed_quad) {
+ *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] = 0;
+ r_index[0][1] = 1;
+ r_index[0][2] = 2;
+
+ r_index[1][0] = 0;
+ r_index[1][1] = 2;
+ r_index[1][2] = 3;
+ }
+ else {
+ float axis_mat[3][3];
+ float(*projverts)[2] = BLI_array_alloca(projverts, f->len);
+ int j;
+
+ axis_dominant_v3_to_m3(axis_mat, f->no);
+
+ j = 0;
+ l_iter = l_first;
+ do {
+ mul_v2_m3v3(projverts[j], axis_mat, l_iter->v->co);
+ r_loops[j] = l_iter;
+ j++;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ /* complete the loop */
+ BLI_polyfill_calc(projverts, f->len, -1, r_index);
+ }
}
/**
@@ -181,39 +182,40 @@ void BM_face_calc_tessellation(
*/
void BM_face_calc_point_in_face(const BMFace *f, float r_co[3])
{
- const BMLoop *l_tri[3];
-
- if (f->len == 3) {
- const BMLoop *l = BM_FACE_FIRST_LOOP(f);
- ARRAY_SET_ITEMS(l_tri, l, l->next, l->prev);
- }
- else {
- /* tessellation here seems overkill when in many cases this will be the center,
- * but without this we can't be sure the point is inside a concave face. */
- const int tottri = f->len - 2;
- BMLoop **loops = BLI_array_alloca(loops, f->len);
- uint (*index)[3] = BLI_array_alloca(index, tottri);
- int j;
- int j_best = 0; /* use as fallback when unset */
- float area_best = -1.0f;
-
- BM_face_calc_tessellation(f, false, loops, index);
-
- 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;
- const float area = area_squared_tri_v3(p1, p2, p3);
- if (area > area_best) {
- j_best = j;
- area_best = area;
- }
- }
-
- ARRAY_SET_ITEMS(l_tri, loops[index[j_best][0]], loops[index[j_best][1]], loops[index[j_best][2]]);
- }
-
- mid_v3_v3v3v3(r_co, l_tri[0]->v->co, l_tri[1]->v->co, l_tri[2]->v->co);
+ const BMLoop *l_tri[3];
+
+ if (f->len == 3) {
+ const BMLoop *l = BM_FACE_FIRST_LOOP(f);
+ ARRAY_SET_ITEMS(l_tri, l, l->next, l->prev);
+ }
+ else {
+ /* tessellation here seems overkill when in many cases this will be the center,
+ * but without this we can't be sure the point is inside a concave face. */
+ const int tottri = f->len - 2;
+ BMLoop **loops = BLI_array_alloca(loops, f->len);
+ uint(*index)[3] = BLI_array_alloca(index, tottri);
+ int j;
+ int j_best = 0; /* use as fallback when unset */
+ float area_best = -1.0f;
+
+ BM_face_calc_tessellation(f, false, loops, index);
+
+ 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;
+ const float area = area_squared_tri_v3(p1, p2, p3);
+ if (area > area_best) {
+ j_best = j;
+ area_best = area;
+ }
+ }
+
+ ARRAY_SET_ITEMS(
+ l_tri, loops[index[j_best][0]], loops[index[j_best][1]], loops[index[j_best][2]]);
+ }
+
+ mid_v3_v3v3v3(r_co, l_tri[0]->v->co, l_tri[1]->v->co, l_tri[2]->v->co);
}
/**
@@ -221,16 +223,16 @@ void BM_face_calc_point_in_face(const BMFace *f, float r_co[3])
*/
float BM_face_calc_area(const BMFace *f)
{
- /* inline 'area_poly_v3' logic, avoid creating a temp array */
- const BMLoop *l_iter, *l_first;
- float n[3];
-
- zero_v3(n);
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- add_newell_cross_v3_v3v3(n, l_iter->v->co, l_iter->next->v->co);
- } while ((l_iter = l_iter->next) != l_first);
- return len_v3(n) * 0.5f;
+ /* inline 'area_poly_v3' logic, avoid creating a temp array */
+ const BMLoop *l_iter, *l_first;
+ float n[3];
+
+ zero_v3(n);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ add_newell_cross_v3_v3v3(n, l_iter->v->co, l_iter->next->v->co);
+ } while ((l_iter = l_iter->next) != l_first);
+ return len_v3(n) * 0.5f;
}
/**
@@ -238,21 +240,21 @@ float BM_face_calc_area(const BMFace *f)
*/
float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3])
{
- /* inline 'area_poly_v3' logic, avoid creating a temp array */
- const BMLoop *l_iter, *l_first;
- float co[3];
- float n[3];
-
- zero_v3(n);
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- mul_v3_m3v3(co, mat3, l_iter->v->co);
- do {
- float co_next[3];
- mul_v3_m3v3(co_next, mat3, l_iter->next->v->co);
- add_newell_cross_v3_v3v3(n, co, co_next);
- copy_v3_v3(co, co_next);
- } while ((l_iter = l_iter->next) != l_first);
- return len_v3(n) * 0.5f;
+ /* inline 'area_poly_v3' logic, avoid creating a temp array */
+ const BMLoop *l_iter, *l_first;
+ float co[3];
+ float n[3];
+
+ zero_v3(n);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ mul_v3_m3v3(co, mat3, l_iter->v->co);
+ do {
+ float co_next[3];
+ mul_v3_m3v3(co_next, mat3, l_iter->next->v->co);
+ add_newell_cross_v3_v3v3(n, co, co_next);
+ copy_v3_v3(co, co_next);
+ } while ((l_iter = l_iter->next) != l_first);
+ return len_v3(n) * 0.5f;
}
/**
@@ -260,18 +262,18 @@ float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3])
*/
float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset)
{
- /* inline 'area_poly_v2' logic, avoid creating a temp array */
- const BMLoop *l_iter, *l_first;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- /* The Trapezium Area Rule */
- float cross = 0.0f;
- do {
- const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
- const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l_iter->next, cd_loop_uv_offset);
- cross += (luv_next->uv[0] - luv->uv[0]) * (luv_next->uv[1] + luv->uv[1]);
- } while ((l_iter = l_iter->next) != l_first);
- return fabsf(cross * 0.5f);
+ /* inline 'area_poly_v2' logic, avoid creating a temp array */
+ const BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ /* The Trapezium Area Rule */
+ float cross = 0.0f;
+ do {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l_iter, cd_loop_uv_offset);
+ const MLoopUV *luv_next = BM_ELEM_CD_GET_VOID_P(l_iter->next, cd_loop_uv_offset);
+ cross += (luv_next->uv[0] - luv->uv[0]) * (luv_next->uv[1] + luv->uv[1]);
+ } while ((l_iter = l_iter->next) != l_first);
+ return fabsf(cross * 0.5f);
}
/**
@@ -279,15 +281,15 @@ float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset)
*/
float BM_face_calc_perimeter(const BMFace *f)
{
- const BMLoop *l_iter, *l_first;
- float perimeter = 0.0f;
+ const BMLoop *l_iter, *l_first;
+ float perimeter = 0.0f;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- perimeter += len_v3v3(l_iter->v->co, l_iter->next->v->co);
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ perimeter += len_v3v3(l_iter->v->co, l_iter->next->v->co);
+ } while ((l_iter = l_iter->next) != l_first);
- return perimeter;
+ return perimeter;
}
/**
@@ -295,20 +297,20 @@ float BM_face_calc_perimeter(const BMFace *f)
*/
float BM_face_calc_perimeter_with_mat3(const BMFace *f, const float mat3[3][3])
{
- const BMLoop *l_iter, *l_first;
- float co[3];
- float perimeter = 0.0f;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- mul_v3_m3v3(co, mat3, l_iter->v->co);
- do {
- float co_next[3];
- mul_v3_m3v3(co_next, mat3, l_iter->next->v->co);
- perimeter += len_v3v3(co, co_next);
- copy_v3_v3(co, co_next);
- } while ((l_iter = l_iter->next) != l_first);
-
- return perimeter;
+ const BMLoop *l_iter, *l_first;
+ float co[3];
+ float perimeter = 0.0f;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ mul_v3_m3v3(co, mat3, l_iter->v->co);
+ do {
+ float co_next[3];
+ mul_v3_m3v3(co_next, mat3, l_iter->next->v->co);
+ perimeter += len_v3v3(co, co_next);
+ copy_v3_v3(co, co_next);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ return perimeter;
}
/**
@@ -318,42 +320,39 @@ float BM_face_calc_perimeter_with_mat3(const BMFace *f, const float mat3[3][3])
*/
static int bm_vert_tri_find_unique_edge(BMVert *verts[3])
{
- /* find the most 'unique' loop, (greatest difference to others) */
+ /* find the most 'unique' loop, (greatest difference to others) */
#if 1
- /* optimized version that avoids sqrt */
- float difs[3];
- for (int i_prev = 1, i_curr = 2, i_next = 0;
- i_next < 3;
- i_prev = i_curr, i_curr = i_next++)
- {
- const float *co = verts[i_curr]->co;
- const float *co_other[2] = {verts[i_prev]->co, verts[i_next]->co};
- float proj_dir[3];
- mid_v3_v3v3(proj_dir, co_other[0], co_other[1]);
- sub_v3_v3(proj_dir, co);
-
- float proj_pair[2][3];
- project_v3_v3v3(proj_pair[0], co_other[0], proj_dir);
- project_v3_v3v3(proj_pair[1], co_other[1], proj_dir);
- difs[i_next] = len_squared_v3v3(proj_pair[0], proj_pair[1]);
- }
+ /* optimized version that avoids sqrt */
+ float difs[3];
+ for (int i_prev = 1, i_curr = 2, i_next = 0; i_next < 3; i_prev = i_curr, i_curr = i_next++) {
+ const float *co = verts[i_curr]->co;
+ const float *co_other[2] = {verts[i_prev]->co, verts[i_next]->co};
+ float proj_dir[3];
+ mid_v3_v3v3(proj_dir, co_other[0], co_other[1]);
+ sub_v3_v3(proj_dir, co);
+
+ float proj_pair[2][3];
+ project_v3_v3v3(proj_pair[0], co_other[0], proj_dir);
+ project_v3_v3v3(proj_pair[1], co_other[1], proj_dir);
+ difs[i_next] = len_squared_v3v3(proj_pair[0], proj_pair[1]);
+ }
#else
- const float lens[3] = {
- len_v3v3(verts[0]->co, verts[1]->co),
- len_v3v3(verts[1]->co, verts[2]->co),
- len_v3v3(verts[2]->co, verts[0]->co),
- };
- const float difs[3] = {
- fabsf(lens[1] - lens[2]),
- fabsf(lens[2] - lens[0]),
- fabsf(lens[0] - lens[1]),
- };
+ const float lens[3] = {
+ len_v3v3(verts[0]->co, verts[1]->co),
+ len_v3v3(verts[1]->co, verts[2]->co),
+ len_v3v3(verts[2]->co, verts[0]->co),
+ };
+ const float difs[3] = {
+ fabsf(lens[1] - lens[2]),
+ fabsf(lens[2] - lens[0]),
+ fabsf(lens[0] - lens[1]),
+ };
#endif
- int order[3] = {0, 1, 2};
- axis_sort_v3(difs, order);
+ int order[3] = {0, 1, 2};
+ axis_sort_v3(difs, order);
- return order[0];
+ return order[0];
}
/**
@@ -366,11 +365,11 @@ static int bm_vert_tri_find_unique_edge(BMVert *verts[3])
*/
void BM_vert_tri_calc_tangent_edge(BMVert *verts[3], float r_tangent[3])
{
- const int index = bm_vert_tri_find_unique_edge(verts);
+ const int index = bm_vert_tri_find_unique_edge(verts);
- sub_v3_v3v3(r_tangent, verts[index]->co, verts[(index + 1) % 3]->co);
+ sub_v3_v3v3(r_tangent, verts[index]->co, verts[(index + 1) % 3]->co);
- normalize_v3(r_tangent);
+ normalize_v3(r_tangent);
}
/**
@@ -383,29 +382,28 @@ void BM_vert_tri_calc_tangent_edge(BMVert *verts[3], float r_tangent[3])
*/
void BM_vert_tri_calc_tangent_edge_pair(BMVert *verts[3], float r_tangent[3])
{
- const int index = bm_vert_tri_find_unique_edge(verts);
+ const int index = bm_vert_tri_find_unique_edge(verts);
- const float *v_a = verts[index]->co;
- const float *v_b = verts[(index + 1) % 3]->co;
- const float *v_other = verts[(index + 2) % 3]->co;
+ const float *v_a = verts[index]->co;
+ const float *v_b = verts[(index + 1) % 3]->co;
+ const float *v_other = verts[(index + 2) % 3]->co;
- mid_v3_v3v3(r_tangent, v_a, v_b);
- sub_v3_v3v3(r_tangent, v_other, r_tangent);
+ mid_v3_v3v3(r_tangent, v_a, v_b);
+ sub_v3_v3v3(r_tangent, v_other, r_tangent);
- normalize_v3(r_tangent);
+ normalize_v3(r_tangent);
}
/**
* Compute the tangent of the face, using the longest edge.
*/
-void BM_face_calc_tangent_edge(const BMFace *f, float r_tangent[3])
+void BM_face_calc_tangent_edge(const BMFace *f, float r_tangent[3])
{
- const BMLoop *l_long = BM_face_find_longest_loop((BMFace *)f);
+ const BMLoop *l_long = BM_face_find_longest_loop((BMFace *)f);
- sub_v3_v3v3(r_tangent, l_long->v->co, l_long->next->v->co);
-
- normalize_v3(r_tangent);
+ sub_v3_v3v3(r_tangent, l_long->v->co, l_long->next->v->co);
+ normalize_v3(r_tangent);
}
/**
@@ -413,64 +411,64 @@ void BM_face_calc_tangent_edge(const BMFace *f, float r_tangent[3])
*
* \param r_tangent: Calculated unit length tangent (return value).
*/
-void BM_face_calc_tangent_edge_pair(const BMFace *f, float r_tangent[3])
+void BM_face_calc_tangent_edge_pair(const BMFace *f, float r_tangent[3])
{
- if (f->len == 3) {
- BMVert *verts[3];
-
- BM_face_as_array_vert_tri((BMFace *)f, verts);
-
- BM_vert_tri_calc_tangent_edge_pair(verts, r_tangent);
- }
- else if (f->len == 4) {
- /* Use longest edge pair */
- BMVert *verts[4];
- float vec[3], vec_a[3], vec_b[3];
-
- BM_face_as_array_vert_quad((BMFace *)f, verts);
-
- sub_v3_v3v3(vec_a, verts[3]->co, verts[2]->co);
- sub_v3_v3v3(vec_b, verts[0]->co, verts[1]->co);
- add_v3_v3v3(r_tangent, vec_a, vec_b);
-
- sub_v3_v3v3(vec_a, verts[0]->co, verts[3]->co);
- sub_v3_v3v3(vec_b, verts[1]->co, verts[2]->co);
- add_v3_v3v3(vec, vec_a, vec_b);
- /* use the longest edge length */
- if (len_squared_v3(r_tangent) < len_squared_v3(vec)) {
- copy_v3_v3(r_tangent, vec);
- }
- }
- else {
- /* For ngons use two longest disconnected edges */
- BMLoop *l_long = BM_face_find_longest_loop((BMFace *)f);
- BMLoop *l_long_other = NULL;
-
- float len_max_sq = 0.0f;
- float vec_a[3], vec_b[3];
-
- BMLoop *l_iter = l_long->prev->prev;
- BMLoop *l_last = l_long->next;
-
- do {
- const float len_sq = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
- if (len_sq >= len_max_sq) {
- l_long_other = l_iter;
- len_max_sq = len_sq;
- }
- } while ((l_iter = l_iter->prev) != l_last);
-
- sub_v3_v3v3(vec_a, l_long->next->v->co, l_long->v->co);
- sub_v3_v3v3(vec_b, l_long_other->v->co, l_long_other->next->v->co);
- add_v3_v3v3(r_tangent, vec_a, vec_b);
-
- /* Edges may not be opposite side of the ngon,
- * this could cause problems for ngons with multiple-aligned edges of the same length.
- * Fallback to longest edge. */
- if (UNLIKELY(normalize_v3(r_tangent) == 0.0f)) {
- normalize_v3_v3(r_tangent, vec_a);
- }
- }
+ if (f->len == 3) {
+ BMVert *verts[3];
+
+ BM_face_as_array_vert_tri((BMFace *)f, verts);
+
+ BM_vert_tri_calc_tangent_edge_pair(verts, r_tangent);
+ }
+ else if (f->len == 4) {
+ /* Use longest edge pair */
+ BMVert *verts[4];
+ float vec[3], vec_a[3], vec_b[3];
+
+ BM_face_as_array_vert_quad((BMFace *)f, verts);
+
+ sub_v3_v3v3(vec_a, verts[3]->co, verts[2]->co);
+ sub_v3_v3v3(vec_b, verts[0]->co, verts[1]->co);
+ add_v3_v3v3(r_tangent, vec_a, vec_b);
+
+ sub_v3_v3v3(vec_a, verts[0]->co, verts[3]->co);
+ sub_v3_v3v3(vec_b, verts[1]->co, verts[2]->co);
+ add_v3_v3v3(vec, vec_a, vec_b);
+ /* use the longest edge length */
+ if (len_squared_v3(r_tangent) < len_squared_v3(vec)) {
+ copy_v3_v3(r_tangent, vec);
+ }
+ }
+ else {
+ /* For ngons use two longest disconnected edges */
+ BMLoop *l_long = BM_face_find_longest_loop((BMFace *)f);
+ BMLoop *l_long_other = NULL;
+
+ float len_max_sq = 0.0f;
+ float vec_a[3], vec_b[3];
+
+ BMLoop *l_iter = l_long->prev->prev;
+ BMLoop *l_last = l_long->next;
+
+ do {
+ const float len_sq = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
+ if (len_sq >= len_max_sq) {
+ l_long_other = l_iter;
+ len_max_sq = len_sq;
+ }
+ } while ((l_iter = l_iter->prev) != l_last);
+
+ sub_v3_v3v3(vec_a, l_long->next->v->co, l_long->v->co);
+ sub_v3_v3v3(vec_b, l_long_other->v->co, l_long_other->next->v->co);
+ add_v3_v3v3(r_tangent, vec_a, vec_b);
+
+ /* Edges may not be opposite side of the ngon,
+ * this could cause problems for ngons with multiple-aligned edges of the same length.
+ * Fallback to longest edge. */
+ if (UNLIKELY(normalize_v3(r_tangent) == 0.0f)) {
+ normalize_v3_v3(r_tangent, vec_a);
+ }
+ }
}
/**
@@ -478,35 +476,36 @@ void BM_face_calc_tangent_edge_pair(const BMFace *f, float r_tangent[3])
*
* \param r_tangent: Calculated unit length tangent (return value).
*/
-void BM_face_calc_tangent_edge_diagonal(const BMFace *f, float r_tangent[3])
+void BM_face_calc_tangent_edge_diagonal(const BMFace *f, float r_tangent[3])
{
- BMLoop *l_iter, *l_first;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
-
- /* incase of degenerate faces */
- zero_v3(r_tangent);
-
- /* warning: O(n^2) loop here, take care! */
- float dist_max_sq = 0.0f;
- do {
- BMLoop *l_iter_other = l_iter->next;
- BMLoop *l_iter_last = l_iter->prev;
- do {
- BLI_assert(!ELEM(l_iter->v->co, l_iter_other->v->co, l_iter_other->next->v->co));
- float co_other[3], vec[3];
- closest_to_line_segment_v3(co_other, l_iter->v->co, l_iter_other->v->co, l_iter_other->next->v->co);
- sub_v3_v3v3(vec, l_iter->v->co, co_other);
-
- const float dist_sq = len_squared_v3(vec);
- if (dist_sq > dist_max_sq) {
- dist_max_sq = dist_sq;
- copy_v3_v3(r_tangent, vec);
- }
- } while ((l_iter_other = l_iter_other->next) != l_iter_last);
- } while ((l_iter = l_iter->next) != l_first);
-
- normalize_v3(r_tangent);
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+
+ /* incase of degenerate faces */
+ zero_v3(r_tangent);
+
+ /* warning: O(n^2) loop here, take care! */
+ float dist_max_sq = 0.0f;
+ do {
+ BMLoop *l_iter_other = l_iter->next;
+ BMLoop *l_iter_last = l_iter->prev;
+ do {
+ BLI_assert(!ELEM(l_iter->v->co, l_iter_other->v->co, l_iter_other->next->v->co));
+ float co_other[3], vec[3];
+ closest_to_line_segment_v3(
+ co_other, l_iter->v->co, l_iter_other->v->co, l_iter_other->next->v->co);
+ sub_v3_v3v3(vec, l_iter->v->co, co_other);
+
+ const float dist_sq = len_squared_v3(vec);
+ if (dist_sq > dist_max_sq) {
+ dist_max_sq = dist_sq;
+ copy_v3_v3(r_tangent, vec);
+ }
+ } while ((l_iter_other = l_iter_other->next) != l_iter_last);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ normalize_v3(r_tangent);
}
/**
@@ -514,32 +513,32 @@ void BM_face_calc_tangent_edge_diagonal(const BMFace *f, float r_tangent[3])
*
* \note The logic is almost identical to #BM_face_calc_tangent_edge_diagonal
*/
-void BM_face_calc_tangent_vert_diagonal(const BMFace *f, float r_tangent[3])
+void BM_face_calc_tangent_vert_diagonal(const BMFace *f, float r_tangent[3])
{
- BMLoop *l_iter, *l_first;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
-
- /* incase of degenerate faces */
- zero_v3(r_tangent);
-
- /* warning: O(n^2) loop here, take care! */
- float dist_max_sq = 0.0f;
- do {
- BMLoop *l_iter_other = l_iter->next;
- do {
- float vec[3];
- sub_v3_v3v3(vec, l_iter->v->co, l_iter_other->v->co);
-
- const float dist_sq = len_squared_v3(vec);
- if (dist_sq > dist_max_sq) {
- dist_max_sq = dist_sq;
- copy_v3_v3(r_tangent, vec);
- }
- } while ((l_iter_other = l_iter_other->next) != l_iter);
- } while ((l_iter = l_iter->next) != l_first);
-
- normalize_v3(r_tangent);
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+
+ /* incase of degenerate faces */
+ zero_v3(r_tangent);
+
+ /* warning: O(n^2) loop here, take care! */
+ float dist_max_sq = 0.0f;
+ do {
+ BMLoop *l_iter_other = l_iter->next;
+ do {
+ float vec[3];
+ sub_v3_v3v3(vec, l_iter->v->co, l_iter_other->v->co);
+
+ const float dist_sq = len_squared_v3(vec);
+ if (dist_sq > dist_max_sq) {
+ dist_max_sq = dist_sq;
+ copy_v3_v3(r_tangent, vec);
+ }
+ } while ((l_iter_other = l_iter_other->next) != l_iter);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ normalize_v3(r_tangent);
}
/**
@@ -549,20 +548,20 @@ void BM_face_calc_tangent_vert_diagonal(const BMFace *f, float r_tangent[3])
*/
void BM_face_calc_tangent_auto(const BMFace *f, float r_tangent[3])
{
- if (f->len == 3) {
- /* most 'unique' edge of a triangle */
- BMVert *verts[3];
- BM_face_as_array_vert_tri((BMFace *)f, verts);
- BM_vert_tri_calc_tangent_edge(verts, r_tangent);
- }
- else if (f->len == 4) {
- /* longest edge pair of a quad */
- BM_face_calc_tangent_edge_pair((BMFace *)f, r_tangent);
- }
- else {
- /* longest edge of an ngon */
- BM_face_calc_tangent_edge((BMFace *)f, r_tangent);
- }
+ if (f->len == 3) {
+ /* most 'unique' edge of a triangle */
+ BMVert *verts[3];
+ BM_face_as_array_vert_tri((BMFace *)f, verts);
+ BM_vert_tri_calc_tangent_edge(verts, r_tangent);
+ }
+ else if (f->len == 4) {
+ /* longest edge pair of a quad */
+ BM_face_calc_tangent_edge_pair((BMFace *)f, r_tangent);
+ }
+ else {
+ /* longest edge of an ngon */
+ BM_face_calc_tangent_edge((BMFace *)f, r_tangent);
+ }
}
/**
@@ -570,11 +569,11 @@ void BM_face_calc_tangent_auto(const BMFace *f, float r_tangent[3])
*/
void BM_face_calc_bounds_expand(const BMFace *f, float min[3], float max[3])
{
- const BMLoop *l_iter, *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- minmax_v3v3_v3(min, max, l_iter->v->co);
- } while ((l_iter = l_iter->next) != l_first);
+ const BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ minmax_v3v3_v3(min, max, l_iter->v->co);
+ } while ((l_iter = l_iter->next) != l_first);
}
/**
@@ -582,17 +581,17 @@ void BM_face_calc_bounds_expand(const BMFace *f, float min[3], float max[3])
*/
void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3])
{
- const BMLoop *l_iter, *l_first;
- float min[3], max[3];
+ const BMLoop *l_iter, *l_first;
+ float min[3], max[3];
- INIT_MINMAX(min, max);
+ INIT_MINMAX(min, max);
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- minmax_v3v3_v3(min, max, l_iter->v->co);
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ minmax_v3v3_v3(min, max, l_iter->v->co);
+ } while ((l_iter = l_iter->next) != l_first);
- mid_v3_v3v3(r_cent, min, max);
+ mid_v3_v3v3(r_cent, min, max);
}
/**
@@ -600,15 +599,15 @@ void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3])
*/
void BM_face_calc_center_median(const BMFace *f, float r_cent[3])
{
- const BMLoop *l_iter, *l_first;
+ const BMLoop *l_iter, *l_first;
- zero_v3(r_cent);
+ zero_v3(r_cent);
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- add_v3_v3(r_cent, l_iter->v->co);
- } while ((l_iter = l_iter->next) != l_first);
- mul_v3_fl(r_cent, 1.0f / (float) f->len);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ add_v3_v3(r_cent, l_iter->v->co);
+ } while ((l_iter = l_iter->next) != l_first);
+ mul_v3_fl(r_cent, 1.0f / (float)f->len);
}
/**
@@ -617,27 +616,26 @@ void BM_face_calc_center_median(const BMFace *f, float r_cent[3])
*/
void BM_face_calc_center_median_weighted(const BMFace *f, float r_cent[3])
{
- const BMLoop *l_iter;
- const BMLoop *l_first;
- float totw = 0.0f;
- float w_prev;
-
- zero_v3(r_cent);
-
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- w_prev = BM_edge_calc_length(l_iter->prev->e);
- do {
- const float w_curr = BM_edge_calc_length(l_iter->e);
- const float w = (w_curr + w_prev);
- madd_v3_v3fl(r_cent, l_iter->v->co, w);
- totw += w;
- w_prev = w_curr;
- } while ((l_iter = l_iter->next) != l_first);
-
- if (totw != 0.0f) {
- mul_v3_fl(r_cent, 1.0f / (float) totw);
- }
+ const BMLoop *l_iter;
+ const BMLoop *l_first;
+ float totw = 0.0f;
+ float w_prev;
+
+ zero_v3(r_cent);
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ w_prev = BM_edge_calc_length(l_iter->prev->e);
+ do {
+ const float w_curr = BM_edge_calc_length(l_iter->e);
+ const float w = (w_curr + w_prev);
+ madd_v3_v3fl(r_cent, l_iter->v->co, w);
+ totw += w;
+ w_prev = w_curr;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (totw != 0.0f) {
+ mul_v3_fl(r_cent, 1.0f / (float)totw);
+ }
}
/**
@@ -648,17 +646,17 @@ void BM_face_calc_center_median_weighted(const BMFace *f, float r_cent[3])
*/
void poly_rotate_plane(const float normal[3], float (*verts)[3], const uint nverts)
{
- float mat[3][3];
- float co[3];
- uint i;
+ float mat[3][3];
+ float co[3];
+ uint i;
- co[2] = 0.0f;
+ co[2] = 0.0f;
- axis_dominant_v3_to_m3(mat, normal);
- for (i = 0; i < nverts; i++) {
- mul_v2_m3v3(co, mat, verts[i]);
- copy_v3_v3(verts[i], co);
- }
+ axis_dominant_v3_to_m3(mat, normal);
+ for (i = 0; i < nverts; i++) {
+ mul_v2_m3v3(co, mat, verts[i]);
+ copy_v3_v3(verts[i], co);
+ }
}
/**
@@ -666,119 +664,119 @@ void poly_rotate_plane(const float normal[3], float (*verts)[3], const uint nver
*/
void BM_edge_normals_update(BMEdge *e)
{
- BMIter iter;
- BMFace *f;
+ BMIter iter;
+ BMFace *f;
- BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
- BM_face_normal_update(f);
- }
+ BM_ITER_ELEM (f, &iter, e, BM_FACES_OF_EDGE) {
+ BM_face_normal_update(f);
+ }
- BM_vert_normal_update(e->v1);
- BM_vert_normal_update(e->v2);
+ BM_vert_normal_update(e->v1);
+ BM_vert_normal_update(e->v2);
}
static void bm_loop_normal_accum(const BMLoop *l, float no[3])
{
- float vec1[3], vec2[3], fac;
+ float vec1[3], vec2[3], fac;
- /* Same calculation used in BM_mesh_normals_update */
- sub_v3_v3v3(vec1, l->v->co, l->prev->v->co);
- sub_v3_v3v3(vec2, l->next->v->co, l->v->co);
- normalize_v3(vec1);
- normalize_v3(vec2);
+ /* Same calculation used in BM_mesh_normals_update */
+ sub_v3_v3v3(vec1, l->v->co, l->prev->v->co);
+ sub_v3_v3v3(vec2, l->next->v->co, l->v->co);
+ normalize_v3(vec1);
+ normalize_v3(vec2);
- fac = saacos(-dot_v3v3(vec1, vec2));
+ fac = saacos(-dot_v3v3(vec1, vec2));
- madd_v3_v3fl(no, l->f->no, fac);
+ madd_v3_v3fl(no, l->f->no, fac);
}
bool BM_vert_calc_normal_ex(const BMVert *v, const char hflag, float r_no[3])
{
- int len = 0;
-
- zero_v3(r_no);
-
- if (v->e) {
- const BMEdge *e = v->e;
- do {
- if (e->l) {
- const BMLoop *l = e->l;
- do {
- if (l->v == v) {
- if (BM_elem_flag_test(l->f, hflag)) {
- bm_loop_normal_accum(l, r_no);
- len++;
- }
- }
- } while ((l = l->radial_next) != e->l);
- }
- } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
- }
-
- if (len) {
- normalize_v3(r_no);
- return true;
- }
- else {
- return false;
- }
+ int len = 0;
+
+ zero_v3(r_no);
+
+ if (v->e) {
+ const BMEdge *e = v->e;
+ do {
+ if (e->l) {
+ const BMLoop *l = e->l;
+ do {
+ if (l->v == v) {
+ if (BM_elem_flag_test(l->f, hflag)) {
+ bm_loop_normal_accum(l, r_no);
+ len++;
+ }
+ }
+ } while ((l = l->radial_next) != e->l);
+ }
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
+ }
+
+ if (len) {
+ normalize_v3(r_no);
+ return true;
+ }
+ else {
+ return false;
+ }
}
bool BM_vert_calc_normal(const BMVert *v, float r_no[3])
{
- int len = 0;
-
- zero_v3(r_no);
-
- if (v->e) {
- const BMEdge *e = v->e;
- do {
- if (e->l) {
- const BMLoop *l = e->l;
- do {
- if (l->v == v) {
- bm_loop_normal_accum(l, r_no);
- len++;
- }
- } while ((l = l->radial_next) != e->l);
- }
- } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
- }
-
- if (len) {
- normalize_v3(r_no);
- return true;
- }
- else {
- return false;
- }
+ int len = 0;
+
+ zero_v3(r_no);
+
+ if (v->e) {
+ const BMEdge *e = v->e;
+ do {
+ if (e->l) {
+ const BMLoop *l = e->l;
+ do {
+ if (l->v == v) {
+ bm_loop_normal_accum(l, r_no);
+ len++;
+ }
+ } while ((l = l->radial_next) != e->l);
+ }
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
+ }
+
+ if (len) {
+ normalize_v3(r_no);
+ return true;
+ }
+ else {
+ return false;
+ }
}
void BM_vert_normal_update_all(BMVert *v)
{
- int len = 0;
-
- zero_v3(v->no);
-
- if (v->e) {
- const BMEdge *e = v->e;
- do {
- if (e->l) {
- const BMLoop *l = e->l;
- do {
- if (l->v == v) {
- BM_face_normal_update(l->f);
- bm_loop_normal_accum(l, v->no);
- len++;
- }
- } while ((l = l->radial_next) != e->l);
- }
- } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
- }
-
- if (len) {
- normalize_v3(v->no);
- }
+ int len = 0;
+
+ zero_v3(v->no);
+
+ if (v->e) {
+ const BMEdge *e = v->e;
+ do {
+ if (e->l) {
+ const BMLoop *l = e->l;
+ do {
+ if (l->v == v) {
+ BM_face_normal_update(l->f);
+ bm_loop_normal_accum(l, v->no);
+ len++;
+ }
+ } while ((l = l->radial_next) != e->l);
+ }
+ } while ((e = bmesh_disk_edge_next(e, v)) != v->e);
+ }
+
+ if (len) {
+ normalize_v3(v->no);
+ }
}
/**
@@ -786,7 +784,7 @@ void BM_vert_normal_update_all(BMVert *v)
*/
void BM_vert_normal_update(BMVert *v)
{
- BM_vert_calc_normal(v, v->no);
+ BM_vert_calc_normal(v, v->no);
}
/**
@@ -801,73 +799,68 @@ void BM_vert_normal_update(BMVert *v)
float BM_face_calc_normal(const BMFace *f, float r_no[3])
{
- BMLoop *l;
-
- /* common cases first */
- switch (f->len) {
- case 4:
- {
- const float *co1 = (l = BM_FACE_FIRST_LOOP(f))->v->co;
- const float *co2 = (l = l->next)->v->co;
- const float *co3 = (l = l->next)->v->co;
- const float *co4 = (l->next)->v->co;
-
- return normal_quad_v3(r_no, co1, co2, co3, co4);
- }
- case 3:
- {
- const float *co1 = (l = BM_FACE_FIRST_LOOP(f))->v->co;
- const float *co2 = (l = l->next)->v->co;
- const float *co3 = (l->next)->v->co;
-
- return normal_tri_v3(r_no, co1, co2, co3);
- }
- default:
- {
- return bm_face_calc_poly_normal(f, r_no);
- }
- }
+ BMLoop *l;
+
+ /* common cases first */
+ switch (f->len) {
+ case 4: {
+ const float *co1 = (l = BM_FACE_FIRST_LOOP(f))->v->co;
+ const float *co2 = (l = l->next)->v->co;
+ const float *co3 = (l = l->next)->v->co;
+ const float *co4 = (l->next)->v->co;
+
+ return normal_quad_v3(r_no, co1, co2, co3, co4);
+ }
+ case 3: {
+ const float *co1 = (l = BM_FACE_FIRST_LOOP(f))->v->co;
+ const float *co2 = (l = l->next)->v->co;
+ const float *co3 = (l->next)->v->co;
+
+ return normal_tri_v3(r_no, co1, co2, co3);
+ }
+ default: {
+ return bm_face_calc_poly_normal(f, r_no);
+ }
+ }
}
void BM_face_normal_update(BMFace *f)
{
- BM_face_calc_normal(f, f->no);
+ BM_face_calc_normal(f, f->no);
}
/* exact same as 'BM_face_calc_normal' but accepts vertex coords */
-float BM_face_calc_normal_vcos(
- const BMesh *bm, const BMFace *f, float r_no[3],
- float const (*vertexCos)[3])
+float BM_face_calc_normal_vcos(const BMesh *bm,
+ const BMFace *f,
+ float r_no[3],
+ float const (*vertexCos)[3])
{
- BMLoop *l;
-
- /* must have valid index data */
- BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
- (void)bm;
-
- /* common cases first */
- switch (f->len) {
- case 4:
- {
- const float *co1 = vertexCos[BM_elem_index_get((l = BM_FACE_FIRST_LOOP(f))->v)];
- const float *co2 = vertexCos[BM_elem_index_get((l = l->next)->v)];
- const float *co3 = vertexCos[BM_elem_index_get((l = l->next)->v)];
- const float *co4 = vertexCos[BM_elem_index_get((l->next)->v)];
-
- return normal_quad_v3(r_no, co1, co2, co3, co4);
- }
- case 3:
- {
- const float *co1 = vertexCos[BM_elem_index_get((l = BM_FACE_FIRST_LOOP(f))->v)];
- const float *co2 = vertexCos[BM_elem_index_get((l = l->next)->v)];
- const float *co3 = vertexCos[BM_elem_index_get((l->next)->v)];
-
- return normal_tri_v3(r_no, co1, co2, co3);
- }
- default:
- {
- return bm_face_calc_poly_normal_vertex_cos(f, r_no, vertexCos);
- }
- }
+ BMLoop *l;
+
+ /* must have valid index data */
+ BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
+ (void)bm;
+
+ /* common cases first */
+ switch (f->len) {
+ case 4: {
+ const float *co1 = vertexCos[BM_elem_index_get((l = BM_FACE_FIRST_LOOP(f))->v)];
+ const float *co2 = vertexCos[BM_elem_index_get((l = l->next)->v)];
+ const float *co3 = vertexCos[BM_elem_index_get((l = l->next)->v)];
+ const float *co4 = vertexCos[BM_elem_index_get((l->next)->v)];
+
+ return normal_quad_v3(r_no, co1, co2, co3, co4);
+ }
+ case 3: {
+ const float *co1 = vertexCos[BM_elem_index_get((l = BM_FACE_FIRST_LOOP(f))->v)];
+ const float *co2 = vertexCos[BM_elem_index_get((l = l->next)->v)];
+ const float *co3 = vertexCos[BM_elem_index_get((l->next)->v)];
+
+ return normal_tri_v3(r_no, co1, co2, co3);
+ }
+ default: {
+ return bm_face_calc_poly_normal_vertex_cos(f, r_no, vertexCos);
+ }
+ }
}
/**
@@ -875,34 +868,35 @@ float BM_face_calc_normal_vcos(
*/
float BM_face_calc_normal_subset(const BMLoop *l_first, const BMLoop *l_last, float r_no[3])
{
- const float *v_prev, *v_curr;
+ const float *v_prev, *v_curr;
- /* Newell's Method */
- const BMLoop *l_iter = l_first;
- const BMLoop *l_term = l_last->next;
+ /* Newell's Method */
+ const BMLoop *l_iter = l_first;
+ const BMLoop *l_term = l_last->next;
- zero_v3(r_no);
+ zero_v3(r_no);
- v_prev = l_last->v->co;
- do {
- v_curr = l_iter->v->co;
- add_newell_cross_v3_v3v3(r_no, v_prev, v_curr);
- v_prev = v_curr;
- } while ((l_iter = l_iter->next) != l_term);
+ v_prev = l_last->v->co;
+ do {
+ v_curr = l_iter->v->co;
+ add_newell_cross_v3_v3v3(r_no, v_prev, v_curr);
+ v_prev = v_curr;
+ } while ((l_iter = l_iter->next) != l_term);
- return normalize_v3(r_no);
+ return normalize_v3(r_no);
}
/* exact same as 'BM_face_calc_normal' but accepts vertex coords */
-void BM_face_calc_center_median_vcos(
- const BMesh *bm, const BMFace *f, float r_cent[3],
- float const (*vertexCos)[3])
+void BM_face_calc_center_median_vcos(const BMesh *bm,
+ const BMFace *f,
+ float r_cent[3],
+ float const (*vertexCos)[3])
{
- /* must have valid index data */
- BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
- (void)bm;
+ /* must have valid index data */
+ BLI_assert((bm->elem_index_dirty & BM_VERT) == 0);
+ (void)bm;
- bm_face_calc_poly_center_median_vertex_cos(f, r_cent, vertexCos);
+ bm_face_calc_poly_center_median_vertex_cos(f, r_cent, vertexCos);
}
/**
@@ -911,18 +905,19 @@ void BM_face_calc_center_median_vcos(
* Reverses the winding of a face.
* \note This updates the calculated normal.
*/
-void BM_face_normal_flip_ex(
- BMesh *bm, BMFace *f,
- const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
+void BM_face_normal_flip_ex(BMesh *bm,
+ BMFace *f,
+ const int cd_loop_mdisp_offset,
+ const bool use_loop_mdisp_flip)
{
- bmesh_kernel_loop_reverse(bm, f, cd_loop_mdisp_offset, use_loop_mdisp_flip);
- negate_v3(f->no);
+ bmesh_kernel_loop_reverse(bm, f, cd_loop_mdisp_offset, use_loop_mdisp_flip);
+ negate_v3(f->no);
}
void BM_face_normal_flip(BMesh *bm, BMFace *f)
{
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
- BM_face_normal_flip_ex(bm, f, cd_loop_mdisp_offset, true);
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+ BM_face_normal_flip_ex(bm, f, cd_loop_mdisp_offset, true);
}
/**
@@ -937,24 +932,24 @@ void BM_face_normal_flip(BMesh *bm, BMFace *f)
*/
bool BM_face_point_inside_test(const BMFace *f, const float co[3])
{
- float axis_mat[3][3];
- float (*projverts)[2] = BLI_array_alloca(projverts, f->len);
+ float axis_mat[3][3];
+ float(*projverts)[2] = BLI_array_alloca(projverts, f->len);
- float co_2d[2];
- BMLoop *l_iter;
- int i;
+ float co_2d[2];
+ BMLoop *l_iter;
+ int i;
- BLI_assert(BM_face_is_normal_valid(f));
+ BLI_assert(BM_face_is_normal_valid(f));
- axis_dominant_v3_to_m3(axis_mat, f->no);
+ axis_dominant_v3_to_m3(axis_mat, f->no);
- mul_v2_m3v3(co_2d, axis_mat, co);
+ mul_v2_m3v3(co_2d, axis_mat, co);
- for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) {
- mul_v2_m3v3(projverts[i], axis_mat, l_iter->v->co);
- }
+ for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) {
+ mul_v2_m3v3(projverts[i], axis_mat, l_iter->v->co);
+ }
- return isect_point_poly_v2(co_2d, projverts, f->len, false);
+ return isect_point_poly_v2(co_2d, projverts, f->len, false);
}
/**
@@ -980,236 +975,226 @@ bool BM_face_point_inside_test(const BMFace *f, const float co[3])
*
* \note use_tag tags new flags and edges.
*/
-void BM_face_triangulate(
- BMesh *bm, BMFace *f,
- BMFace **r_faces_new,
- int *r_faces_new_tot,
- BMEdge **r_edges_new,
- int *r_edges_new_tot,
- LinkNode **r_faces_double,
- const int quad_method,
- const int ngon_method,
- const bool use_tag,
- /* use for ngons only! */
- MemArena *pf_arena,
-
- /* use for MOD_TRIANGULATE_NGON_BEAUTY only! */
- struct Heap *pf_heap)
+void BM_face_triangulate(BMesh *bm,
+ BMFace *f,
+ BMFace **r_faces_new,
+ int *r_faces_new_tot,
+ BMEdge **r_edges_new,
+ int *r_edges_new_tot,
+ LinkNode **r_faces_double,
+ const int quad_method,
+ const int ngon_method,
+ const bool use_tag,
+ /* use for ngons only! */
+ MemArena *pf_arena,
+
+ /* use for MOD_TRIANGULATE_NGON_BEAUTY only! */
+ struct Heap *pf_heap)
{
- const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
- const bool use_beauty = (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY);
- BMLoop *l_first, *l_new;
- BMFace *f_new;
- int nf_i = 0;
- int ne_i = 0;
-
- BLI_assert(BM_face_is_normal_valid(f));
-
- /* ensure both are valid or NULL */
- BLI_assert((r_faces_new == NULL) == (r_faces_new_tot == NULL));
-
- BLI_assert(f->len > 3);
-
- {
- BMLoop **loops = BLI_array_alloca(loops, f->len);
- uint (*tris)[3] = BLI_array_alloca(tris, f->len);
- const int totfilltri = f->len - 2;
- const int last_tri = f->len - 3;
- int i;
- /* for mdisps */
- float f_center[3];
-
- if (f->len == 4) {
- /* even though we're not using BLI_polyfill, fill in 'tris' and 'loops'
- * so we can share code to handle face creation afterwards. */
- BMLoop *l_v1, *l_v2;
-
- l_first = BM_FACE_FIRST_LOOP(f);
-
- switch (quad_method) {
- case MOD_TRIANGULATE_QUAD_FIXED:
- {
- l_v1 = l_first;
- l_v2 = l_first->next->next;
- break;
- }
- case MOD_TRIANGULATE_QUAD_ALTERNATE:
- {
- l_v1 = l_first->next;
- l_v2 = l_first->prev;
- break;
- }
- case MOD_TRIANGULATE_QUAD_SHORTEDGE:
- case MOD_TRIANGULATE_QUAD_BEAUTY:
- default:
- {
- BMLoop *l_v3, *l_v4;
- bool split_24;
-
- l_v1 = l_first->next;
- l_v2 = l_first->next->next;
- l_v3 = l_first->prev;
- l_v4 = l_first;
-
- if (quad_method == MOD_TRIANGULATE_QUAD_SHORTEDGE) {
- float d1, d2;
- d1 = len_squared_v3v3(l_v4->v->co, l_v2->v->co);
- d2 = len_squared_v3v3(l_v1->v->co, l_v3->v->co);
- split_24 = ((d2 - d1) > 0.0f);
- }
- else {
- /* first check if the quad is concave on either diagonal */
- const int flip_flag = is_quad_flip_v3(l_v1->v->co, l_v2->v->co, l_v3->v->co, l_v4->v->co);
- if (UNLIKELY(flip_flag & (1 << 0))) {
- split_24 = true;
- }
- else if (UNLIKELY(flip_flag & (1 << 1))) {
- split_24 = false;
- }
- else {
- split_24 = (BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) > 0.0f);
- }
- }
-
- /* named confusingly, l_v1 is in fact the second vertex */
- if (split_24) {
- l_v1 = l_v4;
- //l_v2 = l_v2;
- }
- else {
- //l_v1 = l_v1;
- l_v2 = l_v3;
- }
- break;
- }
- }
-
- loops[0] = l_v1;
- loops[1] = l_v1->next;
- loops[2] = l_v2;
- loops[3] = l_v2->next;
-
- ARRAY_SET_ITEMS(tris[0], 0, 1, 2);
- ARRAY_SET_ITEMS(tris[1], 0, 2, 3);
- }
- else {
- BMLoop *l_iter;
- float axis_mat[3][3];
- float (*projverts)[2] = BLI_array_alloca(projverts, f->len);
-
- axis_dominant_v3_to_m3_negate(axis_mat, f->no);
-
- for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) {
- loops[i] = l_iter;
- mul_v2_m3v3(projverts[i], axis_mat, l_iter->v->co);
- }
-
- BLI_polyfill_calc_arena(projverts, f->len, 1, tris,
- pf_arena);
-
- if (use_beauty) {
- BLI_polyfill_beautify(
- projverts, f->len, tris,
- pf_arena, pf_heap);
- }
-
- BLI_memarena_clear(pf_arena);
- }
-
- if (cd_loop_mdisp_offset != -1) {
- BM_face_calc_center_median(f, f_center);
- }
-
- /* loop over calculated triangles and create new geometry */
- for (i = 0; i < totfilltri; i++) {
- BMLoop *l_tri[3] = {
- loops[tris[i][0]],
- loops[tris[i][1]],
- loops[tris[i][2]]};
-
- BMVert *v_tri[3] = {
- l_tri[0]->v,
- l_tri[1]->v,
- l_tri[2]->v};
-
- f_new = BM_face_create_verts(bm, v_tri, 3, f, BM_CREATE_NOP, true);
- l_new = BM_FACE_FIRST_LOOP(f_new);
-
- BLI_assert(v_tri[0] == l_new->v);
-
- /* check for duplicate */
- if (l_new->radial_next != l_new) {
- BMLoop *l_iter = l_new->radial_next;
- do {
- if (UNLIKELY((l_iter->f->len == 3) && (l_new->prev->v == l_iter->prev->v))) {
- /* Check the last tri because we swap last f_new with f at the end... */
- BLI_linklist_prepend(r_faces_double, (i != last_tri) ? f_new : f);
- break;
- }
- } while ((l_iter = l_iter->radial_next) != l_new);
- }
-
- /* copy CD data */
- BM_elem_attrs_copy(bm, bm, l_tri[0], l_new);
- BM_elem_attrs_copy(bm, bm, l_tri[1], l_new->next);
- BM_elem_attrs_copy(bm, bm, l_tri[2], l_new->prev);
-
- /* add all but the last face which is swapped and removed (below) */
- if (i != last_tri) {
- if (use_tag) {
- BM_elem_flag_enable(f_new, BM_ELEM_TAG);
- }
- if (r_faces_new) {
- r_faces_new[nf_i++] = f_new;
- }
- }
-
- if (use_tag || r_edges_new) {
- /* new faces loops */
- BMLoop *l_iter;
-
- l_iter = l_first = l_new;
- do {
- BMEdge *e = l_iter->e;
- /* confusing! if its not a boundary now, we know it will be later
- * since this will be an edge of one of the new faces which we're in the middle of creating */
- bool is_new_edge = (l_iter == l_iter->radial_next);
-
- if (is_new_edge) {
- if (use_tag) {
- BM_elem_flag_enable(e, BM_ELEM_TAG);
- }
- if (r_edges_new) {
- r_edges_new[ne_i++] = e;
- }
- }
- /* note, never disable tag's */
- } while ((l_iter = l_iter->next) != l_first);
- }
-
- if (cd_loop_mdisp_offset != -1) {
- float f_new_center[3];
- BM_face_calc_center_median(f_new, f_new_center);
- BM_face_interp_multires_ex(bm, f_new, f, f_new_center, f_center, cd_loop_mdisp_offset);
- }
- }
-
- {
- /* we can't delete the real face, because some of the callers expect it to remain valid.
- * so swap data and delete the last created tri */
- bmesh_face_swap_data(f, f_new);
- BM_face_kill(bm, f_new);
- }
- }
- bm->elem_index_dirty |= BM_FACE;
-
- if (r_faces_new_tot) {
- *r_faces_new_tot = nf_i;
- }
-
- if (r_edges_new_tot) {
- *r_edges_new_tot = ne_i;
- }
+ const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
+ const bool use_beauty = (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY);
+ BMLoop *l_first, *l_new;
+ BMFace *f_new;
+ int nf_i = 0;
+ int ne_i = 0;
+
+ BLI_assert(BM_face_is_normal_valid(f));
+
+ /* ensure both are valid or NULL */
+ BLI_assert((r_faces_new == NULL) == (r_faces_new_tot == NULL));
+
+ BLI_assert(f->len > 3);
+
+ {
+ BMLoop **loops = BLI_array_alloca(loops, f->len);
+ uint(*tris)[3] = BLI_array_alloca(tris, f->len);
+ const int totfilltri = f->len - 2;
+ const int last_tri = f->len - 3;
+ int i;
+ /* for mdisps */
+ float f_center[3];
+
+ if (f->len == 4) {
+ /* even though we're not using BLI_polyfill, fill in 'tris' and 'loops'
+ * so we can share code to handle face creation afterwards. */
+ BMLoop *l_v1, *l_v2;
+
+ l_first = BM_FACE_FIRST_LOOP(f);
+
+ switch (quad_method) {
+ case MOD_TRIANGULATE_QUAD_FIXED: {
+ l_v1 = l_first;
+ l_v2 = l_first->next->next;
+ break;
+ }
+ case MOD_TRIANGULATE_QUAD_ALTERNATE: {
+ l_v1 = l_first->next;
+ l_v2 = l_first->prev;
+ break;
+ }
+ case MOD_TRIANGULATE_QUAD_SHORTEDGE:
+ case MOD_TRIANGULATE_QUAD_BEAUTY:
+ default: {
+ BMLoop *l_v3, *l_v4;
+ bool split_24;
+
+ l_v1 = l_first->next;
+ l_v2 = l_first->next->next;
+ l_v3 = l_first->prev;
+ l_v4 = l_first;
+
+ if (quad_method == MOD_TRIANGULATE_QUAD_SHORTEDGE) {
+ float d1, d2;
+ d1 = len_squared_v3v3(l_v4->v->co, l_v2->v->co);
+ d2 = len_squared_v3v3(l_v1->v->co, l_v3->v->co);
+ split_24 = ((d2 - d1) > 0.0f);
+ }
+ else {
+ /* first check if the quad is concave on either diagonal */
+ const int flip_flag = is_quad_flip_v3(
+ l_v1->v->co, l_v2->v->co, l_v3->v->co, l_v4->v->co);
+ if (UNLIKELY(flip_flag & (1 << 0))) {
+ split_24 = true;
+ }
+ else if (UNLIKELY(flip_flag & (1 << 1))) {
+ split_24 = false;
+ }
+ else {
+ split_24 = (BM_verts_calc_rotate_beauty(l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) >
+ 0.0f);
+ }
+ }
+
+ /* named confusingly, l_v1 is in fact the second vertex */
+ if (split_24) {
+ l_v1 = l_v4;
+ //l_v2 = l_v2;
+ }
+ else {
+ //l_v1 = l_v1;
+ l_v2 = l_v3;
+ }
+ break;
+ }
+ }
+
+ loops[0] = l_v1;
+ loops[1] = l_v1->next;
+ loops[2] = l_v2;
+ loops[3] = l_v2->next;
+
+ ARRAY_SET_ITEMS(tris[0], 0, 1, 2);
+ ARRAY_SET_ITEMS(tris[1], 0, 2, 3);
+ }
+ else {
+ BMLoop *l_iter;
+ float axis_mat[3][3];
+ float(*projverts)[2] = BLI_array_alloca(projverts, f->len);
+
+ axis_dominant_v3_to_m3_negate(axis_mat, f->no);
+
+ for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) {
+ loops[i] = l_iter;
+ mul_v2_m3v3(projverts[i], axis_mat, l_iter->v->co);
+ }
+
+ BLI_polyfill_calc_arena(projverts, f->len, 1, tris, pf_arena);
+
+ if (use_beauty) {
+ BLI_polyfill_beautify(projverts, f->len, tris, pf_arena, pf_heap);
+ }
+
+ BLI_memarena_clear(pf_arena);
+ }
+
+ if (cd_loop_mdisp_offset != -1) {
+ BM_face_calc_center_median(f, f_center);
+ }
+
+ /* loop over calculated triangles and create new geometry */
+ for (i = 0; i < totfilltri; i++) {
+ BMLoop *l_tri[3] = {loops[tris[i][0]], loops[tris[i][1]], loops[tris[i][2]]};
+
+ BMVert *v_tri[3] = {l_tri[0]->v, l_tri[1]->v, l_tri[2]->v};
+
+ f_new = BM_face_create_verts(bm, v_tri, 3, f, BM_CREATE_NOP, true);
+ l_new = BM_FACE_FIRST_LOOP(f_new);
+
+ BLI_assert(v_tri[0] == l_new->v);
+
+ /* check for duplicate */
+ if (l_new->radial_next != l_new) {
+ BMLoop *l_iter = l_new->radial_next;
+ do {
+ if (UNLIKELY((l_iter->f->len == 3) && (l_new->prev->v == l_iter->prev->v))) {
+ /* Check the last tri because we swap last f_new with f at the end... */
+ BLI_linklist_prepend(r_faces_double, (i != last_tri) ? f_new : f);
+ break;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_new);
+ }
+
+ /* copy CD data */
+ BM_elem_attrs_copy(bm, bm, l_tri[0], l_new);
+ BM_elem_attrs_copy(bm, bm, l_tri[1], l_new->next);
+ BM_elem_attrs_copy(bm, bm, l_tri[2], l_new->prev);
+
+ /* add all but the last face which is swapped and removed (below) */
+ if (i != last_tri) {
+ if (use_tag) {
+ BM_elem_flag_enable(f_new, BM_ELEM_TAG);
+ }
+ if (r_faces_new) {
+ r_faces_new[nf_i++] = f_new;
+ }
+ }
+
+ if (use_tag || r_edges_new) {
+ /* new faces loops */
+ BMLoop *l_iter;
+
+ l_iter = l_first = l_new;
+ do {
+ BMEdge *e = l_iter->e;
+ /* confusing! if its not a boundary now, we know it will be later
+ * since this will be an edge of one of the new faces which we're in the middle of creating */
+ bool is_new_edge = (l_iter == l_iter->radial_next);
+
+ if (is_new_edge) {
+ if (use_tag) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
+ if (r_edges_new) {
+ r_edges_new[ne_i++] = e;
+ }
+ }
+ /* note, never disable tag's */
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ if (cd_loop_mdisp_offset != -1) {
+ float f_new_center[3];
+ BM_face_calc_center_median(f_new, f_new_center);
+ BM_face_interp_multires_ex(bm, f_new, f, f_new_center, f_center, cd_loop_mdisp_offset);
+ }
+ }
+
+ {
+ /* we can't delete the real face, because some of the callers expect it to remain valid.
+ * so swap data and delete the last created tri */
+ bmesh_face_swap_data(f, f_new);
+ BM_face_kill(bm, f_new);
+ }
+ }
+ bm->elem_index_dirty |= BM_FACE;
+
+ if (r_faces_new_tot) {
+ *r_faces_new_tot = nf_i;
+ }
+
+ if (r_edges_new_tot) {
+ *r_edges_new_tot = ne_i;
+ }
}
/**
@@ -1222,101 +1207,97 @@ void BM_face_triangulate(
*/
void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len)
{
- float out[2] = {-FLT_MAX, -FLT_MAX};
- float center[2] = {0.0f, 0.0f};
- float axis_mat[3][3];
- float (*projverts)[2] = BLI_array_alloca(projverts, f->len);
- const float *(*edgeverts)[2] = BLI_array_alloca(edgeverts, len);
- BMLoop *l;
- int i, i_prev, j;
-
- BLI_assert(BM_face_is_normal_valid(f));
-
- axis_dominant_v3_to_m3(axis_mat, f->no);
-
- for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) {
- mul_v2_m3v3(projverts[i], axis_mat, l->v->co);
- add_v2_v2(center, projverts[i]);
- }
-
- /* first test for completely convex face */
- if (is_poly_convex_v2(projverts, f->len)) {
- return;
- }
-
- mul_v2_fl(center, 1.0f / f->len);
-
- for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) {
- BM_elem_index_set(l, i); /* set_dirty */
-
- /* center the projection for maximum accuracy */
- sub_v2_v2(projverts[i], center);
-
- out[0] = max_ff(out[0], projverts[i][0]);
- out[1] = max_ff(out[1], projverts[i][1]);
- }
- bm->elem_index_dirty |= BM_LOOP;
-
- /* 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][0] = projverts[BM_elem_index_get(loops[i][0])];
- edgeverts[i][1] = projverts[BM_elem_index_get(loops[i][1])];
- }
-
- /* do convexity test */
- for (i = 0; i < len; i++) {
- float mid[2];
- mid_v2_v2v2(mid, edgeverts[i][0], edgeverts[i][1]);
-
- int isect = 0;
- int j_prev;
- for (j = 0, j_prev = f->len - 1; j < f->len; j_prev = j++) {
- const float *f_edge[2] = {projverts[j_prev], projverts[j]};
- if (isect_seg_seg_v2(UNPACK2(f_edge), mid, out) == ISECT_LINE_LINE_CROSS) {
- isect++;
- }
- }
-
- if (isect % 2 == 0) {
- loops[i][0] = NULL;
- }
- }
+ float out[2] = {-FLT_MAX, -FLT_MAX};
+ float center[2] = {0.0f, 0.0f};
+ float axis_mat[3][3];
+ float(*projverts)[2] = BLI_array_alloca(projverts, f->len);
+ const float *(*edgeverts)[2] = BLI_array_alloca(edgeverts, len);
+ BMLoop *l;
+ int i, i_prev, j;
+
+ BLI_assert(BM_face_is_normal_valid(f));
+
+ axis_dominant_v3_to_m3(axis_mat, f->no);
+
+ for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) {
+ mul_v2_m3v3(projverts[i], axis_mat, l->v->co);
+ add_v2_v2(center, projverts[i]);
+ }
+
+ /* first test for completely convex face */
+ if (is_poly_convex_v2(projverts, f->len)) {
+ return;
+ }
+
+ mul_v2_fl(center, 1.0f / f->len);
+
+ for (i = 0, l = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l = l->next) {
+ BM_elem_index_set(l, i); /* set_dirty */
+
+ /* center the projection for maximum accuracy */
+ sub_v2_v2(projverts[i], center);
+
+ out[0] = max_ff(out[0], projverts[i][0]);
+ out[1] = max_ff(out[1], projverts[i][1]);
+ }
+ bm->elem_index_dirty |= BM_LOOP;
+
+ /* 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][0] = projverts[BM_elem_index_get(loops[i][0])];
+ edgeverts[i][1] = projverts[BM_elem_index_get(loops[i][1])];
+ }
+
+ /* do convexity test */
+ for (i = 0; i < len; i++) {
+ float mid[2];
+ mid_v2_v2v2(mid, edgeverts[i][0], edgeverts[i][1]);
+
+ int isect = 0;
+ int j_prev;
+ for (j = 0, j_prev = f->len - 1; j < f->len; j_prev = j++) {
+ const float *f_edge[2] = {projverts[j_prev], projverts[j]};
+ if (isect_seg_seg_v2(UNPACK2(f_edge), mid, out) == ISECT_LINE_LINE_CROSS) {
+ isect++;
+ }
+ }
+
+ if (isect % 2 == 0) {
+ loops[i][0] = NULL;
+ }
+ }
#define EDGE_SHARE_VERT(e1, e2) \
- ((ELEM((e1)[0], (e2)[0], (e2)[1])) || \
- (ELEM((e1)[1], (e2)[0], (e2)[1])))
-
- /* do line crossing tests */
- for (i = 0, i_prev = f->len - 1; i < f->len; i_prev = i++) {
- const float *f_edge[2] = {projverts[i_prev], projverts[i]};
- for (j = 0; j < len; j++) {
- if ((loops[j][0] != NULL) &&
- !EDGE_SHARE_VERT(f_edge, edgeverts[j]))
- {
- if (isect_seg_seg_v2(UNPACK2(f_edge), UNPACK2(edgeverts[j])) == ISECT_LINE_LINE_CROSS) {
- loops[j][0] = NULL;
- }
- }
- }
- }
-
- /* self intersect tests */
- for (i = 0; i < len; i++) {
- if (loops[i][0]) {
- for (j = i + 1; j < len; j++) {
- if ((loops[j][0] != NULL) &&
- !EDGE_SHARE_VERT(edgeverts[i], edgeverts[j]))
- {
- if (isect_seg_seg_v2(UNPACK2(edgeverts[i]), UNPACK2(edgeverts[j])) == ISECT_LINE_LINE_CROSS) {
- loops[i][0] = NULL;
- break;
- }
- }
- }
- }
- }
+ ((ELEM((e1)[0], (e2)[0], (e2)[1])) || (ELEM((e1)[1], (e2)[0], (e2)[1])))
+
+ /* do line crossing tests */
+ for (i = 0, i_prev = f->len - 1; i < f->len; i_prev = i++) {
+ const float *f_edge[2] = {projverts[i_prev], projverts[i]};
+ for (j = 0; j < len; j++) {
+ if ((loops[j][0] != NULL) && !EDGE_SHARE_VERT(f_edge, edgeverts[j])) {
+ if (isect_seg_seg_v2(UNPACK2(f_edge), UNPACK2(edgeverts[j])) == ISECT_LINE_LINE_CROSS) {
+ loops[j][0] = NULL;
+ }
+ }
+ }
+ }
+
+ /* self intersect tests */
+ for (i = 0; i < len; i++) {
+ if (loops[i][0]) {
+ for (j = i + 1; j < len; j++) {
+ if ((loops[j][0] != NULL) && !EDGE_SHARE_VERT(edgeverts[i], edgeverts[j])) {
+ if (isect_seg_seg_v2(UNPACK2(edgeverts[i]), UNPACK2(edgeverts[j])) ==
+ ISECT_LINE_LINE_CROSS) {
+ loops[i][0] = NULL;
+ break;
+ }
+ }
+ }
+ }
+ }
#undef EDGE_SHARE_VERT
}
@@ -1327,14 +1308,15 @@ void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int l
*/
void BM_face_splits_check_optimal(BMFace *f, BMLoop *(*loops)[2], int len)
{
- int i;
-
- for (i = 0; i < len; i++) {
- BMLoop *l_a_dummy, *l_b_dummy;
- if (f != BM_vert_pair_share_face_by_angle(loops[i][0]->v, loops[i][1]->v, &l_a_dummy, &l_b_dummy, false)) {
- loops[i][0] = NULL;
- }
- }
+ int i;
+
+ for (i = 0; i < len; i++) {
+ BMLoop *l_a_dummy, *l_b_dummy;
+ if (f != BM_vert_pair_share_face_by_angle(
+ loops[i][0]->v, loops[i][1]->v, &l_a_dummy, &l_b_dummy, false)) {
+ loops[i][0] = NULL;
+ }
+ }
}
/**
@@ -1345,13 +1327,15 @@ void BM_face_splits_check_optimal(BMFace *f, BMLoop *(*loops)[2], int len)
*/
void BM_face_as_array_vert_tri(BMFace *f, BMVert *r_verts[3])
{
- BMLoop *l = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l = BM_FACE_FIRST_LOOP(f);
- BLI_assert(f->len == 3);
+ BLI_assert(f->len == 3);
- r_verts[0] = l->v; l = l->next;
- r_verts[1] = l->v; l = l->next;
- r_verts[2] = l->v;
+ r_verts[0] = l->v;
+ l = l->next;
+ r_verts[1] = l->v;
+ l = l->next;
+ r_verts[2] = l->v;
}
/**
@@ -1360,17 +1344,19 @@ void BM_face_as_array_vert_tri(BMFace *f, BMVert *r_verts[3])
*/
void BM_face_as_array_vert_quad(BMFace *f, BMVert *r_verts[4])
{
- BMLoop *l = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l = BM_FACE_FIRST_LOOP(f);
- BLI_assert(f->len == 4);
+ BLI_assert(f->len == 4);
- r_verts[0] = l->v; l = l->next;
- r_verts[1] = l->v; l = l->next;
- r_verts[2] = l->v; l = l->next;
- r_verts[3] = l->v;
+ r_verts[0] = l->v;
+ l = l->next;
+ r_verts[1] = l->v;
+ l = l->next;
+ r_verts[2] = l->v;
+ l = l->next;
+ r_verts[3] = l->v;
}
-
/**
* Small utility functions for fast access
*
@@ -1379,13 +1365,15 @@ void BM_face_as_array_vert_quad(BMFace *f, BMVert *r_verts[4])
*/
void BM_face_as_array_loop_tri(BMFace *f, BMLoop *r_loops[3])
{
- BMLoop *l = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l = BM_FACE_FIRST_LOOP(f);
- BLI_assert(f->len == 3);
+ BLI_assert(f->len == 3);
- r_loops[0] = l; l = l->next;
- r_loops[1] = l; l = l->next;
- r_loops[2] = l;
+ r_loops[0] = l;
+ l = l->next;
+ r_loops[1] = l;
+ l = l->next;
+ r_loops[2] = l;
}
/**
@@ -1394,17 +1382,19 @@ void BM_face_as_array_loop_tri(BMFace *f, BMLoop *r_loops[3])
*/
void BM_face_as_array_loop_quad(BMFace *f, BMLoop *r_loops[4])
{
- BMLoop *l = BM_FACE_FIRST_LOOP(f);
+ BMLoop *l = BM_FACE_FIRST_LOOP(f);
- BLI_assert(f->len == 4);
+ BLI_assert(f->len == 4);
- r_loops[0] = l; l = l->next;
- r_loops[1] = l; l = l->next;
- r_loops[2] = l; l = l->next;
- r_loops[3] = l;
+ r_loops[0] = l;
+ l = l->next;
+ r_loops[1] = l;
+ l = l->next;
+ r_loops[2] = l;
+ l = l->next;
+ r_loops[3] = l;
}
-
/**
* \brief BM_mesh_calc_tessellation get the looptris and its number from a certain bmesh
* \param looptris:
@@ -1413,287 +1403,280 @@ void BM_face_as_array_loop_quad(BMFace *f, BMLoop *r_loops[4])
*/
void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot)
{
- /* use this to avoid locking pthread for _every_ polygon
- * and calling the fill function */
+ /* use this to avoid locking pthread for _every_ polygon
+ * and calling the fill function */
#define USE_TESSFACE_SPEEDUP
- /* this assumes all faces can be scan-filled, which isn't always true,
- * worst case we over alloc a little which is acceptable */
+ /* this assumes all faces can be scan-filled, which isn't always true,
+ * worst case we over alloc a little which is acceptable */
#ifndef NDEBUG
- const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
+ const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
#endif
- BMIter iter;
- BMFace *efa;
- int i = 0;
+ BMIter iter;
+ BMFace *efa;
+ int i = 0;
- MemArena *arena = NULL;
+ MemArena *arena = NULL;
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- /* don't consider two-edged faces */
- if (UNLIKELY(efa->len < 3)) {
- /* do nothing */
- }
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ /* don't consider two-edged faces */
+ if (UNLIKELY(efa->len < 3)) {
+ /* do nothing */
+ }
#ifdef USE_TESSFACE_SPEEDUP
- /* no need to ensure the loop order, we know its ok */
-
- else if (efa->len == 3) {
-#if 0
- int j;
- BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
- looptris[i][j] = l;
- }
- i += 1;
-#else
- /* more cryptic but faster */
- BMLoop *l;
- BMLoop **l_ptr = looptris[i++];
- l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa);
- l_ptr[1] = l = l->next;
- l_ptr[2] = l->next;
-#endif
- }
- else if (efa->len == 4) {
-#if 0
- BMLoop *ltmp[4];
- int j;
- BLI_array_grow_items(looptris, 2);
- BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
- ltmp[j] = l;
- }
-
- looptris[i][0] = ltmp[0];
- looptris[i][1] = ltmp[1];
- looptris[i][2] = ltmp[2];
- i += 1;
-
- looptris[i][0] = ltmp[0];
- looptris[i][1] = ltmp[2];
- looptris[i][2] = ltmp[3];
- i += 1;
-#else
- /* more cryptic but faster */
- BMLoop *l;
- BMLoop **l_ptr_a = looptris[i++];
- BMLoop **l_ptr_b = looptris[i++];
- (l_ptr_a[0] = l_ptr_b[0] = l = BM_FACE_FIRST_LOOP(efa));
- (l_ptr_a[1] = l = l->next);
- (l_ptr_a[2] = l_ptr_b[1] = l = l->next);
- ( l_ptr_b[2] = l->next);
-#endif
-
- if (UNLIKELY(is_quad_flip_v3_first_third_fast(
- l_ptr_a[0]->v->co,
- l_ptr_a[1]->v->co,
- l_ptr_a[2]->v->co,
- l_ptr_b[2]->v->co)))
- {
- /* flip out of degenerate 0-2 state. */
- l_ptr_a[2] = l_ptr_b[2];
- l_ptr_b[0] = l_ptr_a[1];
- }
- }
+ /* no need to ensure the loop order, we know its ok */
+
+ else if (efa->len == 3) {
+# if 0
+ int j;
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
+ looptris[i][j] = l;
+ }
+ i += 1;
+# else
+ /* more cryptic but faster */
+ BMLoop *l;
+ BMLoop **l_ptr = looptris[i++];
+ l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa);
+ l_ptr[1] = l = l->next;
+ l_ptr[2] = l->next;
+# endif
+ }
+ else if (efa->len == 4) {
+# if 0
+ BMLoop *ltmp[4];
+ int j;
+ BLI_array_grow_items(looptris, 2);
+ BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, j) {
+ ltmp[j] = l;
+ }
+
+ looptris[i][0] = ltmp[0];
+ looptris[i][1] = ltmp[1];
+ looptris[i][2] = ltmp[2];
+ i += 1;
+
+ looptris[i][0] = ltmp[0];
+ looptris[i][1] = ltmp[2];
+ looptris[i][2] = ltmp[3];
+ i += 1;
+# else
+ /* more cryptic but faster */
+ BMLoop *l;
+ BMLoop **l_ptr_a = looptris[i++];
+ BMLoop **l_ptr_b = looptris[i++];
+ (l_ptr_a[0] = l_ptr_b[0] = l = BM_FACE_FIRST_LOOP(efa));
+ (l_ptr_a[1] = l = l->next);
+ (l_ptr_a[2] = l_ptr_b[1] = l = l->next);
+ (l_ptr_b[2] = l->next);
+# endif
+
+ if (UNLIKELY(is_quad_flip_v3_first_third_fast(
+ l_ptr_a[0]->v->co, l_ptr_a[1]->v->co, l_ptr_a[2]->v->co, l_ptr_b[2]->v->co))) {
+ /* flip out of degenerate 0-2 state. */
+ l_ptr_a[2] = l_ptr_b[2];
+ l_ptr_b[0] = l_ptr_a[1];
+ }
+ }
#endif /* USE_TESSFACE_SPEEDUP */
- else {
- int j;
+ else {
+ int j;
- BMLoop *l_iter;
- BMLoop *l_first;
- BMLoop **l_arr;
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ BMLoop **l_arr;
- float axis_mat[3][3];
- float (*projverts)[2];
- uint (*tris)[3];
+ float axis_mat[3][3];
+ float(*projverts)[2];
+ uint(*tris)[3];
- const int totfilltri = efa->len - 2;
+ const int totfilltri = efa->len - 2;
- if (UNLIKELY(arena == NULL)) {
- arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
- }
+ if (UNLIKELY(arena == NULL)) {
+ arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ }
- tris = BLI_memarena_alloc(arena, sizeof(*tris) * totfilltri);
- l_arr = BLI_memarena_alloc(arena, sizeof(*l_arr) * efa->len);
- projverts = BLI_memarena_alloc(arena, sizeof(*projverts) * efa->len);
+ tris = BLI_memarena_alloc(arena, sizeof(*tris) * totfilltri);
+ l_arr = BLI_memarena_alloc(arena, sizeof(*l_arr) * efa->len);
+ projverts = BLI_memarena_alloc(arena, sizeof(*projverts) * efa->len);
- axis_dominant_v3_to_m3_negate(axis_mat, efa->no);
+ axis_dominant_v3_to_m3_negate(axis_mat, efa->no);
- j = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
- do {
- l_arr[j] = l_iter;
- mul_v2_m3v3(projverts[j], axis_mat, l_iter->v->co);
- j++;
- } while ((l_iter = l_iter->next) != l_first);
+ j = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ l_arr[j] = l_iter;
+ mul_v2_m3v3(projverts[j], axis_mat, l_iter->v->co);
+ j++;
+ } while ((l_iter = l_iter->next) != l_first);
- BLI_polyfill_calc_arena(projverts, efa->len, 1, tris, arena);
+ BLI_polyfill_calc_arena(projverts, efa->len, 1, tris, arena);
- for (j = 0; j < totfilltri; j++) {
- BMLoop **l_ptr = looptris[i++];
- uint *tri = tris[j];
+ for (j = 0; j < totfilltri; j++) {
+ BMLoop **l_ptr = looptris[i++];
+ uint *tri = tris[j];
- l_ptr[0] = l_arr[tri[0]];
- l_ptr[1] = l_arr[tri[1]];
- l_ptr[2] = l_arr[tri[2]];
- }
+ l_ptr[0] = l_arr[tri[0]];
+ l_ptr[1] = l_arr[tri[1]];
+ l_ptr[2] = l_arr[tri[2]];
+ }
- BLI_memarena_clear(arena);
- }
- }
+ BLI_memarena_clear(arena);
+ }
+ }
- if (arena) {
- BLI_memarena_free(arena);
- arena = NULL;
- }
+ if (arena) {
+ BLI_memarena_free(arena);
+ arena = NULL;
+ }
- *r_looptris_tot = i;
+ *r_looptris_tot = i;
- BLI_assert(i <= looptris_tot);
+ BLI_assert(i <= looptris_tot);
#undef USE_TESSFACE_SPEEDUP
-
}
-
/**
* A version of #BM_mesh_calc_tessellation that avoids degenerate triangles.
*/
void BM_mesh_calc_tessellation_beauty(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot)
{
- /* this assumes all faces can be scan-filled, which isn't always true,
- * worst case we over alloc a little which is acceptable */
+ /* this assumes all faces can be scan-filled, which isn't always true,
+ * worst case we over alloc a little which is acceptable */
#ifndef NDEBUG
- const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
+ const int looptris_tot = poly_to_tri_count(bm->totface, bm->totloop);
#endif
- BMIter iter;
- BMFace *efa;
- int i = 0;
-
- MemArena *pf_arena = NULL;
-
- /* use_beauty */
- Heap *pf_heap = NULL;
-
- BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
- /* don't consider two-edged faces */
- if (UNLIKELY(efa->len < 3)) {
- /* do nothing */
- }
- else if (efa->len == 3) {
- BMLoop *l;
- BMLoop **l_ptr = looptris[i++];
- l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa);
- l_ptr[1] = l = l->next;
- l_ptr[2] = l->next;
- }
- else if (efa->len == 4) {
- BMLoop *l_v1 = BM_FACE_FIRST_LOOP(efa);
- BMLoop *l_v2 = l_v1->next;
- BMLoop *l_v3 = l_v2->next;
- BMLoop *l_v4 = l_v1->prev;
-
- /* #BM_verts_calc_rotate_beauty performs excessive checks we don't need!
- * It's meant for rotating edges, it also calculates a new normal.
- *
- * Use #BLI_polyfill_beautify_quad_rotate_calc since we have the normal.
- */
+ BMIter iter;
+ BMFace *efa;
+ int i = 0;
+
+ MemArena *pf_arena = NULL;
+
+ /* use_beauty */
+ Heap *pf_heap = NULL;
+
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ /* don't consider two-edged faces */
+ if (UNLIKELY(efa->len < 3)) {
+ /* do nothing */
+ }
+ else if (efa->len == 3) {
+ BMLoop *l;
+ BMLoop **l_ptr = looptris[i++];
+ l_ptr[0] = l = BM_FACE_FIRST_LOOP(efa);
+ l_ptr[1] = l = l->next;
+ l_ptr[2] = l->next;
+ }
+ else if (efa->len == 4) {
+ BMLoop *l_v1 = BM_FACE_FIRST_LOOP(efa);
+ BMLoop *l_v2 = l_v1->next;
+ BMLoop *l_v3 = l_v2->next;
+ BMLoop *l_v4 = l_v1->prev;
+
+ /* #BM_verts_calc_rotate_beauty performs excessive checks we don't need!
+ * It's meant for rotating edges, it also calculates a new normal.
+ *
+ * Use #BLI_polyfill_beautify_quad_rotate_calc since we have the normal.
+ */
#if 0
- const bool split_13 = (BM_verts_calc_rotate_beauty(
- l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) < 0.0f);
+ const bool split_13 = (BM_verts_calc_rotate_beauty(
+ l_v1->v, l_v2->v, l_v3->v, l_v4->v, 0, 0) < 0.0f);
#else
- float axis_mat[3][3], v_quad[4][2];
- axis_dominant_v3_to_m3(axis_mat, efa->no);
- mul_v2_m3v3(v_quad[0], axis_mat, l_v1->v->co);
- mul_v2_m3v3(v_quad[1], axis_mat, l_v2->v->co);
- mul_v2_m3v3(v_quad[2], axis_mat, l_v3->v->co);
- mul_v2_m3v3(v_quad[3], axis_mat, l_v4->v->co);
-
- const bool split_13 = BLI_polyfill_beautify_quad_rotate_calc(
- v_quad[0], v_quad[1], v_quad[2], v_quad[3]) < 0.0f;
+ float axis_mat[3][3], v_quad[4][2];
+ axis_dominant_v3_to_m3(axis_mat, efa->no);
+ mul_v2_m3v3(v_quad[0], axis_mat, l_v1->v->co);
+ mul_v2_m3v3(v_quad[1], axis_mat, l_v2->v->co);
+ mul_v2_m3v3(v_quad[2], axis_mat, l_v3->v->co);
+ mul_v2_m3v3(v_quad[3], axis_mat, l_v4->v->co);
+
+ const bool split_13 = BLI_polyfill_beautify_quad_rotate_calc(
+ v_quad[0], v_quad[1], v_quad[2], v_quad[3]) < 0.0f;
#endif
- BMLoop **l_ptr_a = looptris[i++];
- BMLoop **l_ptr_b = looptris[i++];
- if (split_13) {
- l_ptr_a[0] = l_v1;
- l_ptr_a[1] = l_v2;
- l_ptr_a[2] = l_v3;
-
- l_ptr_b[0] = l_v1;
- l_ptr_b[1] = l_v3;
- l_ptr_b[2] = l_v4;
- }
- else {
- l_ptr_a[0] = l_v1;
- l_ptr_a[1] = l_v2;
- l_ptr_a[2] = l_v4;
-
- l_ptr_b[0] = l_v2;
- l_ptr_b[1] = l_v3;
- l_ptr_b[2] = l_v4;
- }
- }
- else {
- int j;
-
- BMLoop *l_iter;
- BMLoop *l_first;
- BMLoop **l_arr;
-
- float axis_mat[3][3];
- float (*projverts)[2];
- unsigned int (*tris)[3];
-
- const int totfilltri = efa->len - 2;
-
- if (UNLIKELY(pf_arena == NULL)) {
- pf_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
- pf_heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE);
- }
-
- tris = BLI_memarena_alloc(pf_arena, sizeof(*tris) * totfilltri);
- l_arr = BLI_memarena_alloc(pf_arena, sizeof(*l_arr) * efa->len);
- projverts = BLI_memarena_alloc(pf_arena, sizeof(*projverts) * efa->len);
-
- axis_dominant_v3_to_m3_negate(axis_mat, efa->no);
-
- j = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
- do {
- l_arr[j] = l_iter;
- mul_v2_m3v3(projverts[j], axis_mat, l_iter->v->co);
- j++;
- } while ((l_iter = l_iter->next) != l_first);
-
- BLI_polyfill_calc_arena(projverts, efa->len, 1, tris, pf_arena);
-
- BLI_polyfill_beautify(projverts, efa->len, tris, pf_arena, pf_heap);
-
- for (j = 0; j < totfilltri; j++) {
- BMLoop **l_ptr = looptris[i++];
- unsigned int *tri = tris[j];
-
- l_ptr[0] = l_arr[tri[0]];
- l_ptr[1] = l_arr[tri[1]];
- l_ptr[2] = l_arr[tri[2]];
- }
-
- BLI_memarena_clear(pf_arena);
- }
- }
-
- if (pf_arena) {
- BLI_memarena_free(pf_arena);
-
- BLI_heap_free(pf_heap, NULL);
- }
-
- *r_looptris_tot = i;
-
- BLI_assert(i <= looptris_tot);
-
+ BMLoop **l_ptr_a = looptris[i++];
+ BMLoop **l_ptr_b = looptris[i++];
+ if (split_13) {
+ l_ptr_a[0] = l_v1;
+ l_ptr_a[1] = l_v2;
+ l_ptr_a[2] = l_v3;
+
+ l_ptr_b[0] = l_v1;
+ l_ptr_b[1] = l_v3;
+ l_ptr_b[2] = l_v4;
+ }
+ else {
+ l_ptr_a[0] = l_v1;
+ l_ptr_a[1] = l_v2;
+ l_ptr_a[2] = l_v4;
+
+ l_ptr_b[0] = l_v2;
+ l_ptr_b[1] = l_v3;
+ l_ptr_b[2] = l_v4;
+ }
+ }
+ else {
+ int j;
+
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ BMLoop **l_arr;
+
+ float axis_mat[3][3];
+ float(*projverts)[2];
+ unsigned int(*tris)[3];
+
+ const int totfilltri = efa->len - 2;
+
+ if (UNLIKELY(pf_arena == NULL)) {
+ pf_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ pf_heap = BLI_heap_new_ex(BLI_POLYFILL_ALLOC_NGON_RESERVE);
+ }
+
+ tris = BLI_memarena_alloc(pf_arena, sizeof(*tris) * totfilltri);
+ l_arr = BLI_memarena_alloc(pf_arena, sizeof(*l_arr) * efa->len);
+ projverts = BLI_memarena_alloc(pf_arena, sizeof(*projverts) * efa->len);
+
+ axis_dominant_v3_to_m3_negate(axis_mat, efa->no);
+
+ j = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
+ do {
+ l_arr[j] = l_iter;
+ mul_v2_m3v3(projverts[j], axis_mat, l_iter->v->co);
+ j++;
+ } while ((l_iter = l_iter->next) != l_first);
+
+ BLI_polyfill_calc_arena(projverts, efa->len, 1, tris, pf_arena);
+
+ BLI_polyfill_beautify(projverts, efa->len, tris, pf_arena, pf_heap);
+
+ for (j = 0; j < totfilltri; j++) {
+ BMLoop **l_ptr = looptris[i++];
+ unsigned int *tri = tris[j];
+
+ l_ptr[0] = l_arr[tri[0]];
+ l_ptr[1] = l_arr[tri[1]];
+ l_ptr[2] = l_arr[tri[2]];
+ }
+
+ BLI_memarena_clear(pf_arena);
+ }
+ }
+
+ if (pf_arena) {
+ BLI_memarena_free(pf_arena);
+
+ BLI_heap_free(pf_heap, NULL);
+ }
+
+ *r_looptris_tot = i;
+
+ BLI_assert(i <= looptris_tot);
}
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index ff93ce94c77..191ebd86f4a 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -25,67 +25,77 @@ struct Heap;
#include "BLI_compiler_attrs.h"
-void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot);
-void BM_mesh_calc_tessellation_beauty(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot);
-
-void BM_face_calc_tessellation(
- const BMFace *f, const bool use_fixed_quad,
- BMLoop **r_loops, uint (*r_index)[3]);
-void BM_face_calc_point_in_face(const BMFace *f, float r_co[3]);
+void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot);
+void BM_mesh_calc_tessellation_beauty(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptris_tot);
+
+void BM_face_calc_tessellation(const BMFace *f,
+ const bool use_fixed_quad,
+ BMLoop **r_loops,
+ uint (*r_index)[3]);
+void BM_face_calc_point_in_face(const BMFace *f, float r_co[3]);
float BM_face_calc_normal(const BMFace *f, float r_no[3]) ATTR_NONNULL();
-float BM_face_calc_normal_vcos(
- const BMesh *bm, const BMFace *f, float r_no[3],
- float const (*vertexCos)[3]) ATTR_NONNULL();
-float BM_face_calc_normal_subset(const BMLoop *l_first, const BMLoop *l_last, float r_no[3]) ATTR_NONNULL();
+float BM_face_calc_normal_vcos(const BMesh *bm,
+ const BMFace *f,
+ float r_no[3],
+ float const (*vertexCos)[3]) ATTR_NONNULL();
+float BM_face_calc_normal_subset(const BMLoop *l_first, const BMLoop *l_last, float r_no[3])
+ ATTR_NONNULL();
float BM_face_calc_area(const BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_face_calc_area_with_mat3(const BMFace *f, const float mat3[3][3]) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+float BM_face_calc_area_uv(const BMFace *f, int cd_loop_uv_offset) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
float BM_face_calc_perimeter(const BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_face_calc_perimeter_with_mat3(const BMFace *f, const float mat3[3][3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void BM_face_calc_tangent_edge(const BMFace *f, float r_plane[3]) ATTR_NONNULL();
-void BM_face_calc_tangent_edge_pair(const BMFace *f, float r_plane[3]) ATTR_NONNULL();
-void BM_face_calc_tangent_edge_diagonal(const BMFace *f, float r_plane[3]) ATTR_NONNULL();
-void BM_face_calc_tangent_vert_diagonal(const BMFace *f, float r_plane[3]) ATTR_NONNULL();
-void BM_face_calc_tangent_auto(const BMFace *f, float r_plane[3]) ATTR_NONNULL();
-void BM_face_calc_center_bounds(const BMFace *f, float center[3]) ATTR_NONNULL();
-void BM_face_calc_center_median(const BMFace *f, float center[3]) ATTR_NONNULL();
-void BM_face_calc_center_median_vcos(
- const BMesh *bm, const BMFace *f, float r_cent[3],
- float const (*vertexCos)[3]) ATTR_NONNULL();
-void BM_face_calc_center_median_weighted(const BMFace *f, float center[3]) ATTR_NONNULL();
+float BM_face_calc_perimeter_with_mat3(const BMFace *f,
+ const float mat3[3][3]) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+void BM_face_calc_tangent_edge(const BMFace *f, float r_plane[3]) ATTR_NONNULL();
+void BM_face_calc_tangent_edge_pair(const BMFace *f, float r_plane[3]) ATTR_NONNULL();
+void BM_face_calc_tangent_edge_diagonal(const BMFace *f, float r_plane[3]) ATTR_NONNULL();
+void BM_face_calc_tangent_vert_diagonal(const BMFace *f, float r_plane[3]) ATTR_NONNULL();
+void BM_face_calc_tangent_auto(const BMFace *f, float r_plane[3]) ATTR_NONNULL();
+void BM_face_calc_center_bounds(const BMFace *f, float center[3]) ATTR_NONNULL();
+void BM_face_calc_center_median(const BMFace *f, float center[3]) ATTR_NONNULL();
+void BM_face_calc_center_median_vcos(const BMesh *bm,
+ const BMFace *f,
+ float r_cent[3],
+ float const (*vertexCos)[3]) ATTR_NONNULL();
+void BM_face_calc_center_median_weighted(const BMFace *f, float center[3]) ATTR_NONNULL();
void BM_face_calc_bounds_expand(const BMFace *f, float min[3], float max[3]);
-void BM_face_normal_update(BMFace *f) ATTR_NONNULL();
-
-void BM_edge_normals_update(BMEdge *e) ATTR_NONNULL();
-
-bool BM_vert_calc_normal_ex(const BMVert *v, const char hflag, float r_no[3]);
-bool BM_vert_calc_normal(const BMVert *v, float r_no[3]);
-void BM_vert_normal_update(BMVert *v) ATTR_NONNULL();
-void BM_vert_normal_update_all(BMVert *v) ATTR_NONNULL();
-
-void BM_face_normal_flip_ex(
- BMesh *bm, BMFace *f,
- const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip) ATTR_NONNULL();
-void BM_face_normal_flip(BMesh *bm, BMFace *f) ATTR_NONNULL();
-bool BM_face_point_inside_test(const BMFace *f, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-
-void BM_face_triangulate(
- BMesh *bm, BMFace *f,
- BMFace **r_faces_new,
- int *r_faces_new_tot,
- BMEdge **r_edges_new,
- int *r_edges_new_tot,
- struct LinkNode **r_faces_double,
- const int quad_method, const int ngon_method,
- const bool use_tag,
- struct MemArena *pf_arena,
- struct Heap *pf_heap
- ) ATTR_NONNULL(1, 2);
-
-void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL();
-void BM_face_splits_check_optimal(BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL();
+void BM_face_normal_update(BMFace *f) ATTR_NONNULL();
+
+void BM_edge_normals_update(BMEdge *e) ATTR_NONNULL();
+
+bool BM_vert_calc_normal_ex(const BMVert *v, const char hflag, float r_no[3]);
+bool BM_vert_calc_normal(const BMVert *v, float r_no[3]);
+void BM_vert_normal_update(BMVert *v) ATTR_NONNULL();
+void BM_vert_normal_update_all(BMVert *v) ATTR_NONNULL();
+
+void BM_face_normal_flip_ex(BMesh *bm,
+ BMFace *f,
+ const int cd_loop_mdisp_offset,
+ const bool use_loop_mdisp_flip) ATTR_NONNULL();
+void BM_face_normal_flip(BMesh *bm, BMFace *f) ATTR_NONNULL();
+bool BM_face_point_inside_test(const BMFace *f, const float co[3]) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+
+void BM_face_triangulate(BMesh *bm,
+ BMFace *f,
+ BMFace **r_faces_new,
+ int *r_faces_new_tot,
+ BMEdge **r_edges_new,
+ int *r_edges_new_tot,
+ struct LinkNode **r_faces_double,
+ const int quad_method,
+ const int ngon_method,
+ const bool use_tag,
+ struct MemArena *pf_arena,
+ struct Heap *pf_heap) ATTR_NONNULL(1, 2);
+
+void BM_face_splits_check_legal(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL();
+void BM_face_splits_check_optimal(BMFace *f, BMLoop *(*loops)[2], int len) ATTR_NONNULL();
void BM_face_as_array_vert_tri(BMFace *f, BMVert *r_verts[3]) ATTR_NONNULL();
void BM_face_as_array_vert_quad(BMFace *f, BMVert *r_verts[4]) ATTR_NONNULL();
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index 76c0dcc1dfa..e2b117536f3 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -52,167 +52,169 @@
/* Note: All these flags _must_ be cleared on exit */
/* face is apart of the edge-net (including the original face we're splitting) */
-#define FACE_NET _FLAG_WALK
+#define FACE_NET _FLAG_WALK
/* edge is apart of the edge-net we're filling */
-#define EDGE_NET _FLAG_WALK
+#define EDGE_NET _FLAG_WALK
/* tag verts we've visit */
#define VERT_VISIT _FLAG_WALK
#define VERT_IN_QUEUE _FLAG_WALK_ALT
struct VertOrder {
- float angle;
- BMVert *v;
+ float angle;
+ BMVert *v;
};
static uint bm_edge_flagged_radial_count(BMEdge *e)
{
- uint count = 0;
- BMLoop *l;
-
- if ((l = e->l)) {
- do {
- if (BM_ELEM_API_FLAG_TEST(l->f, FACE_NET)) {
- count++;
- }
- } while ((l = l->radial_next) != e->l);
- }
- return count;
+ uint count = 0;
+ BMLoop *l;
+
+ if ((l = e->l)) {
+ do {
+ if (BM_ELEM_API_FLAG_TEST(l->f, FACE_NET)) {
+ count++;
+ }
+ } while ((l = l->radial_next) != e->l);
+ }
+ return count;
}
static BMLoop *bm_edge_flagged_radial_first(BMEdge *e)
{
- BMLoop *l;
-
- if ((l = e->l)) {
- do {
- if (BM_ELEM_API_FLAG_TEST(l->f, FACE_NET)) {
- return l;
- }
- } while ((l = l->radial_next) != e->l);
- }
- return NULL;
+ BMLoop *l;
+
+ if ((l = e->l)) {
+ do {
+ if (BM_ELEM_API_FLAG_TEST(l->f, FACE_NET)) {
+ return l;
+ }
+ } while ((l = l->radial_next) != e->l);
+ }
+ return NULL;
}
-static void normalize_v2_m3_v3v3(float out[2], float axis_mat[3][3], const float v1[3], const float v2[3])
+static void normalize_v2_m3_v3v3(float out[2],
+ float axis_mat[3][3],
+ const float v1[3],
+ const float v2[3])
{
- float dir[3];
- sub_v3_v3v3(dir, v1, v2);
- mul_v2_m3v3(out, axis_mat, dir);
- normalize_v2(out);
+ float dir[3];
+ sub_v3_v3v3(dir, v1, v2);
+ mul_v2_m3v3(out, axis_mat, dir);
+ normalize_v2(out);
}
-
/**
* \note Be sure to update #bm_face_split_edgenet_find_loop_pair_exists
* when making changed to edge picking logic.
*/
-static bool bm_face_split_edgenet_find_loop_pair(
- BMVert *v_init,
- const float face_normal[3], float face_normal_matrix[3][3],
- BMEdge *e_pair[2])
+static bool bm_face_split_edgenet_find_loop_pair(BMVert *v_init,
+ const float face_normal[3],
+ float face_normal_matrix[3][3],
+ BMEdge *e_pair[2])
{
- /* Always find one boundary edge (to determine winding)
- * and one wire (if available), otherwise another boundary.
- */
-
- /* detect winding */
- BMLoop *l_walk;
- bool swap;
-
- BLI_SMALLSTACK_DECLARE(edges_boundary, BMEdge *);
- BLI_SMALLSTACK_DECLARE(edges_wire, BMEdge *);
- int edges_boundary_len = 0;
- int edges_wire_len = 0;
-
- {
- BMEdge *e, *e_first;
- e = e_first = v_init->e;
- do {
- if (BM_ELEM_API_FLAG_TEST(e, EDGE_NET)) {
- const uint count = bm_edge_flagged_radial_count(e);
- if (count == 1) {
- BLI_SMALLSTACK_PUSH(edges_boundary, e);
- edges_boundary_len++;
- }
- else if (count == 0) {
- BLI_SMALLSTACK_PUSH(edges_wire, e);
- edges_wire_len++;
- }
- }
- } while ((e = BM_DISK_EDGE_NEXT(e, v_init)) != e_first);
- }
-
- /* first edge should always be boundary */
- if (edges_boundary_len == 0) {
- return false;
- }
- e_pair[0] = BLI_SMALLSTACK_POP(edges_boundary);
-
- /* use to hold boundary OR wire edges */
- BLI_SMALLSTACK_DECLARE(edges_search, BMEdge *);
-
- /* attempt one boundary and one wire, or 2 boundary */
- if (edges_wire_len == 0) {
- if (edges_boundary_len > 1) {
- e_pair[1] = BLI_SMALLSTACK_POP(edges_boundary);
-
- if (edges_boundary_len > 2) {
- BLI_SMALLSTACK_SWAP(edges_search, edges_boundary);
- }
- }
- else {
- /* one boundary and no wire */
- return false;
- }
- }
- else {
- e_pair[1] = BLI_SMALLSTACK_POP(edges_wire);
- if (edges_wire_len > 1) {
- BLI_SMALLSTACK_SWAP(edges_search, edges_wire);
- }
- }
-
- /* if we swapped above, search this list for the best edge */
- if (!BLI_SMALLSTACK_IS_EMPTY(edges_search)) {
- /* find the best edge in 'edge_list' to use for 'e_pair[1]' */
- const BMVert *v_prev = BM_edge_other_vert(e_pair[0], v_init);
- const BMVert *v_next = BM_edge_other_vert(e_pair[1], v_init);
-
- float dir_prev[2], dir_next[2];
-
- normalize_v2_m3_v3v3(dir_prev, face_normal_matrix, v_prev->co, v_init->co);
- normalize_v2_m3_v3v3(dir_next, face_normal_matrix, v_next->co, v_init->co);
- float angle_best_cos = dot_v2v2(dir_next, dir_prev);
-
- BMEdge *e;
- while ((e = BLI_SMALLSTACK_POP(edges_search))) {
- v_next = BM_edge_other_vert(e, v_init);
- float dir_test[2];
-
- normalize_v2_m3_v3v3(dir_test, face_normal_matrix, v_next->co, v_init->co);
- const float angle_test_cos = dot_v2v2(dir_prev, dir_test);
-
- if (angle_test_cos > angle_best_cos) {
- angle_best_cos = angle_test_cos;
- e_pair[1] = e;
- }
- }
- }
-
- /* flip based on winding */
- l_walk = bm_edge_flagged_radial_first(e_pair[0]);
- swap = false;
- if (face_normal == l_walk->f->no) {
- swap = !swap;
- }
- if (l_walk->v != v_init) {
- swap = !swap;
- }
- if (swap) {
- SWAP(BMEdge *, e_pair[0], e_pair[1]);
- }
-
- return true;
+ /* Always find one boundary edge (to determine winding)
+ * and one wire (if available), otherwise another boundary.
+ */
+
+ /* detect winding */
+ BMLoop *l_walk;
+ bool swap;
+
+ BLI_SMALLSTACK_DECLARE(edges_boundary, BMEdge *);
+ BLI_SMALLSTACK_DECLARE(edges_wire, BMEdge *);
+ int edges_boundary_len = 0;
+ int edges_wire_len = 0;
+
+ {
+ BMEdge *e, *e_first;
+ e = e_first = v_init->e;
+ do {
+ if (BM_ELEM_API_FLAG_TEST(e, EDGE_NET)) {
+ const uint count = bm_edge_flagged_radial_count(e);
+ if (count == 1) {
+ BLI_SMALLSTACK_PUSH(edges_boundary, e);
+ edges_boundary_len++;
+ }
+ else if (count == 0) {
+ BLI_SMALLSTACK_PUSH(edges_wire, e);
+ edges_wire_len++;
+ }
+ }
+ } while ((e = BM_DISK_EDGE_NEXT(e, v_init)) != e_first);
+ }
+
+ /* first edge should always be boundary */
+ if (edges_boundary_len == 0) {
+ return false;
+ }
+ e_pair[0] = BLI_SMALLSTACK_POP(edges_boundary);
+
+ /* use to hold boundary OR wire edges */
+ BLI_SMALLSTACK_DECLARE(edges_search, BMEdge *);
+
+ /* attempt one boundary and one wire, or 2 boundary */
+ if (edges_wire_len == 0) {
+ if (edges_boundary_len > 1) {
+ e_pair[1] = BLI_SMALLSTACK_POP(edges_boundary);
+
+ if (edges_boundary_len > 2) {
+ BLI_SMALLSTACK_SWAP(edges_search, edges_boundary);
+ }
+ }
+ else {
+ /* one boundary and no wire */
+ return false;
+ }
+ }
+ else {
+ e_pair[1] = BLI_SMALLSTACK_POP(edges_wire);
+ if (edges_wire_len > 1) {
+ BLI_SMALLSTACK_SWAP(edges_search, edges_wire);
+ }
+ }
+
+ /* if we swapped above, search this list for the best edge */
+ if (!BLI_SMALLSTACK_IS_EMPTY(edges_search)) {
+ /* find the best edge in 'edge_list' to use for 'e_pair[1]' */
+ const BMVert *v_prev = BM_edge_other_vert(e_pair[0], v_init);
+ const BMVert *v_next = BM_edge_other_vert(e_pair[1], v_init);
+
+ float dir_prev[2], dir_next[2];
+
+ normalize_v2_m3_v3v3(dir_prev, face_normal_matrix, v_prev->co, v_init->co);
+ normalize_v2_m3_v3v3(dir_next, face_normal_matrix, v_next->co, v_init->co);
+ float angle_best_cos = dot_v2v2(dir_next, dir_prev);
+
+ BMEdge *e;
+ while ((e = BLI_SMALLSTACK_POP(edges_search))) {
+ v_next = BM_edge_other_vert(e, v_init);
+ float dir_test[2];
+
+ normalize_v2_m3_v3v3(dir_test, face_normal_matrix, v_next->co, v_init->co);
+ const float angle_test_cos = dot_v2v2(dir_prev, dir_test);
+
+ if (angle_test_cos > angle_best_cos) {
+ angle_best_cos = angle_test_cos;
+ e_pair[1] = e;
+ }
+ }
+ }
+
+ /* flip based on winding */
+ l_walk = bm_edge_flagged_radial_first(e_pair[0]);
+ swap = false;
+ if (face_normal == l_walk->f->no) {
+ swap = !swap;
+ }
+ if (l_walk->v != v_init) {
+ swap = !swap;
+ }
+ if (swap) {
+ SWAP(BMEdge *, e_pair[0], e_pair[1]);
+ }
+
+ return true;
}
/**
@@ -223,226 +225,233 @@ static bool bm_face_split_edgenet_find_loop_pair(
* since between this check and running #bm_face_split_edgenet_find_loop,
* the selected edges may have had faces attached.
*/
-static bool bm_face_split_edgenet_find_loop_pair_exists(
- BMVert *v_init)
+static bool bm_face_split_edgenet_find_loop_pair_exists(BMVert *v_init)
{
- int edges_boundary_len = 0;
- int edges_wire_len = 0;
-
- {
- BMEdge *e, *e_first;
- e = e_first = v_init->e;
- do {
- if (BM_ELEM_API_FLAG_TEST(e, EDGE_NET)) {
- const uint count = bm_edge_flagged_radial_count(e);
- if (count == 1) {
- edges_boundary_len++;
- }
- else if (count == 0) {
- edges_wire_len++;
- }
- }
- } while ((e = BM_DISK_EDGE_NEXT(e, v_init)) != e_first);
- }
-
- /* first edge should always be boundary */
- if (edges_boundary_len == 0) {
- return false;
- }
-
- /* attempt one boundary and one wire, or 2 boundary */
- if (edges_wire_len == 0) {
- if (edges_boundary_len >= 2) {
- /* pass */
- }
- else {
- /* one boundary and no wire */
- return false;
- }
- }
- else {
- /* pass */
- }
-
- return true;
+ int edges_boundary_len = 0;
+ int edges_wire_len = 0;
+
+ {
+ BMEdge *e, *e_first;
+ e = e_first = v_init->e;
+ do {
+ if (BM_ELEM_API_FLAG_TEST(e, EDGE_NET)) {
+ const uint count = bm_edge_flagged_radial_count(e);
+ if (count == 1) {
+ edges_boundary_len++;
+ }
+ else if (count == 0) {
+ edges_wire_len++;
+ }
+ }
+ } while ((e = BM_DISK_EDGE_NEXT(e, v_init)) != e_first);
+ }
+
+ /* first edge should always be boundary */
+ if (edges_boundary_len == 0) {
+ return false;
+ }
+
+ /* attempt one boundary and one wire, or 2 boundary */
+ if (edges_wire_len == 0) {
+ if (edges_boundary_len >= 2) {
+ /* pass */
+ }
+ else {
+ /* one boundary and no wire */
+ return false;
+ }
+ }
+ else {
+ /* pass */
+ }
+
+ return true;
}
-static bool bm_face_split_edgenet_find_loop_walk(
- BMVert *v_init, const float face_normal[3],
- /* cache to avoid realloc every time */
- struct VertOrder *edge_order, const uint edge_order_len,
- BMEdge *e_pair[2])
+static bool bm_face_split_edgenet_find_loop_walk(BMVert *v_init,
+ const float face_normal[3],
+ /* cache to avoid realloc every time */
+ struct VertOrder *edge_order,
+ const uint edge_order_len,
+ BMEdge *e_pair[2])
{
- /* fast-path for the common case (avoid push-pop).
- * Also avoids tagging as visited since we know we
- * can't reach these verts some other way */
+ /* fast-path for the common case (avoid push-pop).
+ * Also avoids tagging as visited since we know we
+ * can't reach these verts some other way */
#define USE_FASTPATH_NOFORK
- BMVert *v;
- BMVert *v_dst;
- bool found = false;
+ BMVert *v;
+ BMVert *v_dst;
+ bool found = false;
- struct VertOrder *eo;
- STACK_DECLARE(edge_order);
+ struct VertOrder *eo;
+ STACK_DECLARE(edge_order);
- /* store visited verts so we can clear the visit flag after execution */
- BLI_SMALLSTACK_DECLARE(vert_visit, BMVert *);
+ /* store visited verts so we can clear the visit flag after execution */
+ BLI_SMALLSTACK_DECLARE(vert_visit, BMVert *);
- /* likely this will stay very small
- * all verts pushed into this stack _must_ have their previous edges set! */
- BLI_SMALLSTACK_DECLARE(vert_stack, BMVert *);
- BLI_SMALLSTACK_DECLARE(vert_stack_next, BMVert *);
+ /* likely this will stay very small
+ * all verts pushed into this stack _must_ have their previous edges set! */
+ BLI_SMALLSTACK_DECLARE(vert_stack, BMVert *);
+ BLI_SMALLSTACK_DECLARE(vert_stack_next, BMVert *);
- STACK_INIT(edge_order, edge_order_len);
+ STACK_INIT(edge_order, edge_order_len);
- /* start stepping */
- v = BM_edge_other_vert(e_pair[0], v_init);
- v->e = e_pair[0];
- BLI_SMALLSTACK_PUSH(vert_stack, v);
+ /* start stepping */
+ v = BM_edge_other_vert(e_pair[0], v_init);
+ v->e = e_pair[0];
+ BLI_SMALLSTACK_PUSH(vert_stack, v);
- v_dst = BM_edge_other_vert(e_pair[1], v_init);
+ v_dst = BM_edge_other_vert(e_pair[1], v_init);
#ifdef DEBUG_PRINT
- printf("%s: vert (search) %d\n", __func__, BM_elem_index_get(v_init));
+ printf("%s: vert (search) %d\n", __func__, BM_elem_index_get(v_init));
#endif
- /* This loop will keep stepping over the best possible edge,
- * in most cases it finds the direct route to close the face.
- *
- * In cases where paths can't be closed,
- * alternatives are stored in the 'vert_stack'.
- */
- while ((v = BLI_SMALLSTACK_POP_EX(vert_stack, vert_stack_next))) {
+ /* This loop will keep stepping over the best possible edge,
+ * in most cases it finds the direct route to close the face.
+ *
+ * In cases where paths can't be closed,
+ * alternatives are stored in the 'vert_stack'.
+ */
+ while ((v = BLI_SMALLSTACK_POP_EX(vert_stack, vert_stack_next))) {
#ifdef USE_FASTPATH_NOFORK
-walk_nofork:
+ walk_nofork:
#else
- BLI_SMALLSTACK_PUSH(vert_visit, v);
- BM_ELEM_API_FLAG_ENABLE(v, VERT_VISIT);
+ BLI_SMALLSTACK_PUSH(vert_visit, v);
+ BM_ELEM_API_FLAG_ENABLE(v, VERT_VISIT);
#endif
- BLI_assert(STACK_SIZE(edge_order) == 0);
+ BLI_assert(STACK_SIZE(edge_order) == 0);
- /* check if we're done! */
- if (v == v_dst) {
- found = true;
- goto finally;
- }
+ /* check if we're done! */
+ if (v == v_dst) {
+ found = true;
+ goto finally;
+ }
- BMEdge *e_next, *e_first;
- e_first = v->e;
- e_next = BM_DISK_EDGE_NEXT(e_first, v); /* always skip this verts edge */
+ BMEdge *e_next, *e_first;
+ e_first = v->e;
+ e_next = BM_DISK_EDGE_NEXT(e_first, v); /* always skip this verts edge */
- /* in rare cases there may be edges with a single connecting vertex */
- if (e_next != e_first) {
- do {
- if ((BM_ELEM_API_FLAG_TEST(e_next, EDGE_NET)) &&
- (bm_edge_flagged_radial_count(e_next) < 2))
- {
- BMVert *v_next;
+ /* in rare cases there may be edges with a single connecting vertex */
+ if (e_next != e_first) {
+ do {
+ if ((BM_ELEM_API_FLAG_TEST(e_next, EDGE_NET)) &&
+ (bm_edge_flagged_radial_count(e_next) < 2)) {
+ BMVert *v_next;
- v_next = BM_edge_other_vert(e_next, v);
- BLI_assert(v->e != e_next);
+ v_next = BM_edge_other_vert(e_next, v);
+ BLI_assert(v->e != e_next);
#ifdef DEBUG_PRINT
- /* indent and print */
- {
- BMVert *_v = v;
- do {
- printf(" ");
- } while ((_v = BM_edge_other_vert(_v->e, _v)) != v_init);
- printf("vert %d -> %d (add=%d)\n",
- BM_elem_index_get(v), BM_elem_index_get(v_next),
- BM_ELEM_API_FLAG_TEST(v_next, VERT_VISIT) == 0);
- }
+ /* indent and print */
+ {
+ BMVert *_v = v;
+ do {
+ printf(" ");
+ } while ((_v = BM_edge_other_vert(_v->e, _v)) != v_init);
+ printf("vert %d -> %d (add=%d)\n",
+ BM_elem_index_get(v),
+ BM_elem_index_get(v_next),
+ BM_ELEM_API_FLAG_TEST(v_next, VERT_VISIT) == 0);
+ }
#endif
- if (!BM_ELEM_API_FLAG_TEST(v_next, VERT_VISIT)) {
- eo = STACK_PUSH_RET_PTR(edge_order);
- eo->v = v_next;
+ if (!BM_ELEM_API_FLAG_TEST(v_next, VERT_VISIT)) {
+ eo = STACK_PUSH_RET_PTR(edge_order);
+ eo->v = v_next;
- v_next->e = e_next;
- }
- }
- } while ((e_next = BM_DISK_EDGE_NEXT(e_next, v)) != e_first);
- }
+ v_next->e = e_next;
+ }
+ }
+ } while ((e_next = BM_DISK_EDGE_NEXT(e_next, v)) != e_first);
+ }
#ifdef USE_FASTPATH_NOFORK
- if (STACK_SIZE(edge_order) == 1) {
- eo = STACK_POP_PTR(edge_order);
- v = eo->v;
+ if (STACK_SIZE(edge_order) == 1) {
+ eo = STACK_POP_PTR(edge_order);
+ v = eo->v;
- goto walk_nofork;
- }
+ goto walk_nofork;
+ }
#endif
- /* sort by angle if needed */
- if (STACK_SIZE(edge_order) > 1) {
- uint j;
- BMVert *v_prev = BM_edge_other_vert(v->e, v);
+ /* sort by angle if needed */
+ if (STACK_SIZE(edge_order) > 1) {
+ uint j;
+ BMVert *v_prev = BM_edge_other_vert(v->e, v);
- for (j = 0; j < STACK_SIZE(edge_order); j++) {
- edge_order[j].angle = angle_signed_on_axis_v3v3v3_v3(v_prev->co, v->co, edge_order[j].v->co, face_normal);
- }
- qsort(edge_order, STACK_SIZE(edge_order), sizeof(struct VertOrder), BLI_sortutil_cmp_float_reverse);
+ for (j = 0; j < STACK_SIZE(edge_order); j++) {
+ edge_order[j].angle = angle_signed_on_axis_v3v3v3_v3(
+ v_prev->co, v->co, edge_order[j].v->co, face_normal);
+ }
+ qsort(edge_order,
+ STACK_SIZE(edge_order),
+ sizeof(struct VertOrder),
+ BLI_sortutil_cmp_float_reverse);
#ifdef USE_FASTPATH_NOFORK
- /* only tag forks */
- BLI_SMALLSTACK_PUSH(vert_visit, v);
- BM_ELEM_API_FLAG_ENABLE(v, VERT_VISIT);
+ /* only tag forks */
+ BLI_SMALLSTACK_PUSH(vert_visit, v);
+ BM_ELEM_API_FLAG_ENABLE(v, VERT_VISIT);
#endif
- }
-
- while ((eo = STACK_POP_PTR(edge_order))) {
- BLI_SMALLSTACK_PUSH(vert_stack_next, eo->v);
- }
+ }
- if (!BLI_SMALLSTACK_IS_EMPTY(vert_stack_next)) {
- BLI_SMALLSTACK_SWAP(vert_stack, vert_stack_next);
- }
- }
+ while ((eo = STACK_POP_PTR(edge_order))) {
+ BLI_SMALLSTACK_PUSH(vert_stack_next, eo->v);
+ }
+ if (!BLI_SMALLSTACK_IS_EMPTY(vert_stack_next)) {
+ BLI_SMALLSTACK_SWAP(vert_stack, vert_stack_next);
+ }
+ }
finally:
- /* clear flag for next execution */
- while ((v = BLI_SMALLSTACK_POP(vert_visit))) {
- BM_ELEM_API_FLAG_DISABLE(v, VERT_VISIT);
- }
+ /* clear flag for next execution */
+ while ((v = BLI_SMALLSTACK_POP(vert_visit))) {
+ BM_ELEM_API_FLAG_DISABLE(v, VERT_VISIT);
+ }
- return found;
+ return found;
#undef USE_FASTPATH_NOFORK
}
-static bool bm_face_split_edgenet_find_loop(
- BMVert *v_init, const float face_normal[3], float face_normal_matrix[3][3],
- /* cache to avoid realloc every time */
- struct VertOrder *edge_order, const uint edge_order_len,
- BMVert **r_face_verts, int *r_face_verts_len)
+static bool bm_face_split_edgenet_find_loop(BMVert *v_init,
+ const float face_normal[3],
+ float face_normal_matrix[3][3],
+ /* cache to avoid realloc every time */
+ struct VertOrder *edge_order,
+ const uint edge_order_len,
+ BMVert **r_face_verts,
+ int *r_face_verts_len)
{
- BMEdge *e_pair[2];
- BMVert *v;
-
- if (!bm_face_split_edgenet_find_loop_pair(v_init, face_normal, face_normal_matrix, e_pair)) {
- return false;
- }
-
- BLI_assert((bm_edge_flagged_radial_count(e_pair[0]) == 1) ||
- (bm_edge_flagged_radial_count(e_pair[1]) == 1));
-
- if (bm_face_split_edgenet_find_loop_walk(v_init, face_normal, edge_order, edge_order_len, e_pair)) {
- uint i = 0;
-
- r_face_verts[i++] = v_init;
- v = BM_edge_other_vert(e_pair[1], v_init);
- do {
- r_face_verts[i++] = v;
- } while ((v = BM_edge_other_vert(v->e, v)) != v_init);
- *r_face_verts_len = i;
- return (i > 2) ? true : false;
- }
- else {
- return false;
- }
+ BMEdge *e_pair[2];
+ BMVert *v;
+
+ if (!bm_face_split_edgenet_find_loop_pair(v_init, face_normal, face_normal_matrix, e_pair)) {
+ return false;
+ }
+
+ BLI_assert((bm_edge_flagged_radial_count(e_pair[0]) == 1) ||
+ (bm_edge_flagged_radial_count(e_pair[1]) == 1));
+
+ if (bm_face_split_edgenet_find_loop_walk(
+ v_init, face_normal, edge_order, edge_order_len, e_pair)) {
+ uint i = 0;
+
+ r_face_verts[i++] = v_init;
+ v = BM_edge_other_vert(e_pair[1], v_init);
+ do {
+ r_face_verts[i++] = v;
+ } while ((v = BM_edge_other_vert(v->e, v)) != v_init);
+ *r_face_verts_len = i;
+ return (i > 2) ? true : false;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -453,237 +462,232 @@ static bool bm_face_split_edgenet_find_loop(
* - customdata calculations aren't efficient
* (need to calculate weights for each vert).
*/
-bool BM_face_split_edgenet(
- BMesh *bm,
- BMFace *f, BMEdge **edge_net, const int edge_net_len,
- BMFace ***r_face_arr, int *r_face_arr_len)
+bool BM_face_split_edgenet(BMesh *bm,
+ BMFace *f,
+ BMEdge **edge_net,
+ const int edge_net_len,
+ BMFace ***r_face_arr,
+ int *r_face_arr_len)
{
- /* re-use for new face verts */
- BMVert **face_verts;
- int face_verts_len;
-
- BMFace **face_arr = NULL;
- BLI_array_declare(face_arr);
+ /* re-use for new face verts */
+ BMVert **face_verts;
+ int face_verts_len;
- BMVert **vert_queue;
- STACK_DECLARE(vert_queue);
- int i;
+ BMFace **face_arr = NULL;
+ BLI_array_declare(face_arr);
- struct VertOrder *edge_order;
- const uint edge_order_len = edge_net_len + 2;
+ BMVert **vert_queue;
+ STACK_DECLARE(vert_queue);
+ int i;
- BMVert *v;
+ struct VertOrder *edge_order;
+ const uint edge_order_len = edge_net_len + 2;
- BMLoop *l_iter, *l_first;
+ BMVert *v;
+ BMLoop *l_iter, *l_first;
- if (!edge_net_len) {
- if (r_face_arr) {
- *r_face_arr = NULL;
- *r_face_arr_len = 0;
- }
- return false;
- }
+ if (!edge_net_len) {
+ if (r_face_arr) {
+ *r_face_arr = NULL;
+ *r_face_arr_len = 0;
+ }
+ return false;
+ }
- /* over-alloc (probably 2-4 is only used in most cases), for the biggest-fan */
- edge_order = BLI_array_alloca(edge_order, edge_order_len);
+ /* over-alloc (probably 2-4 is only used in most cases), for the biggest-fan */
+ edge_order = BLI_array_alloca(edge_order, edge_order_len);
- /* use later */
- face_verts = BLI_array_alloca(face_verts, edge_net_len + f->len);
+ /* use later */
+ face_verts = BLI_array_alloca(face_verts, edge_net_len + f->len);
- vert_queue = BLI_array_alloca(vert_queue, edge_net_len + f->len);
- STACK_INIT(vert_queue, f->len + edge_net_len);
+ vert_queue = BLI_array_alloca(vert_queue, edge_net_len + f->len);
+ STACK_INIT(vert_queue, f->len + edge_net_len);
- BLI_assert(BM_ELEM_API_FLAG_TEST(f, FACE_NET) == 0);
- BM_ELEM_API_FLAG_ENABLE(f, FACE_NET);
+ BLI_assert(BM_ELEM_API_FLAG_TEST(f, FACE_NET) == 0);
+ BM_ELEM_API_FLAG_ENABLE(f, FACE_NET);
#ifdef DEBUG
- for (i = 0; i < edge_net_len; i++) {
- BLI_assert(BM_ELEM_API_FLAG_TEST(edge_net[i], EDGE_NET) == 0);
- BLI_assert(BM_edge_in_face(edge_net[i], f) == false);
- }
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BLI_assert(BM_ELEM_API_FLAG_TEST(l_iter->e, EDGE_NET) == 0);
- } while ((l_iter = l_iter->next) != l_first);
+ for (i = 0; i < edge_net_len; i++) {
+ BLI_assert(BM_ELEM_API_FLAG_TEST(edge_net[i], EDGE_NET) == 0);
+ BLI_assert(BM_edge_in_face(edge_net[i], f) == false);
+ }
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BLI_assert(BM_ELEM_API_FLAG_TEST(l_iter->e, EDGE_NET) == 0);
+ } while ((l_iter = l_iter->next) != l_first);
#endif
- /* Note: 'VERT_IN_QUEUE' is often not needed at all,
- * however in rare cases verts are added multiple times to the queue,
- * that on it's own is harmless but in _very_ rare cases,
- * the queue will overflow its maximum size,
- * so we better be strict about this! see: T51539 */
-
- for (i = 0; i < edge_net_len; i++) {
- BM_ELEM_API_FLAG_ENABLE(edge_net[i], EDGE_NET);
- BM_ELEM_API_FLAG_DISABLE(edge_net[i]->v1, VERT_IN_QUEUE);
- BM_ELEM_API_FLAG_DISABLE(edge_net[i]->v2, VERT_IN_QUEUE);
- }
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BM_ELEM_API_FLAG_ENABLE(l_iter->e, EDGE_NET);
- BM_ELEM_API_FLAG_DISABLE(l_iter->v, VERT_IN_QUEUE);
- } while ((l_iter = l_iter->next) != l_first);
-
- float face_normal_matrix[3][3];
- axis_dominant_v3_to_m3(face_normal_matrix, f->no);
-
-
- /* any vert can be used to begin with */
- STACK_PUSH(vert_queue, l_first->v);
- BM_ELEM_API_FLAG_ENABLE(l_first->v, VERT_IN_QUEUE);
-
- while ((v = STACK_POP(vert_queue))) {
- BM_ELEM_API_FLAG_DISABLE(v, VERT_IN_QUEUE);
- if (bm_face_split_edgenet_find_loop(
- v, f->no, face_normal_matrix,
- edge_order, edge_order_len, face_verts, &face_verts_len))
- {
- BMFace *f_new;
-
- f_new = BM_face_create_verts(bm, face_verts, face_verts_len, f, BM_CREATE_NOP, false);
-
- for (i = 0; i < edge_net_len; i++) {
- BLI_assert(BM_ELEM_API_FLAG_TEST(edge_net[i], EDGE_NET));
- }
-
- if (f_new) {
- BLI_array_append(face_arr, f_new);
- copy_v3_v3(f_new->no, f->no);
-
- /* warning, normally don't do this,
- * its needed for mesh intersection - which tracks face-sides based on selection */
- f_new->head.hflag = f->head.hflag;
- if (f->head.hflag & BM_ELEM_SELECT) {
- bm->totfacesel++;
- }
-
- BM_ELEM_API_FLAG_ENABLE(f_new, FACE_NET);
-
- /* add new verts to keep finding loops for
- * (verts between boundary and manifold edges) */
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
- do {
- /* Avoid adding to queue multiple times (not common but happens). */
- if (!BM_ELEM_API_FLAG_TEST(l_iter->v, VERT_IN_QUEUE) &&
- bm_face_split_edgenet_find_loop_pair_exists(l_iter->v))
- {
- STACK_PUSH(vert_queue, l_iter->v);
- BM_ELEM_API_FLAG_ENABLE(l_iter->v, VERT_IN_QUEUE);
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
- }
- }
-
-
- if (CustomData_has_math(&bm->ldata)) {
- /* reuse VERT_VISIT here to tag vert's already interpolated */
- BMIter iter;
- BMLoop *l_other;
-
- /* see: #BM_loop_interp_from_face for similar logic */
- void **blocks = BLI_array_alloca(blocks, f->len);
- float (*cos_2d)[2] = BLI_array_alloca(cos_2d, f->len);
- float *w = BLI_array_alloca(w, f->len);
- float axis_mat[3][3];
- float co[2];
-
- /* interior loops */
- axis_dominant_v3_to_m3(axis_mat, f->no);
-
-
- /* first simply copy from existing face */
- i = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BM_ITER_ELEM (l_other, &iter, l_iter->v, BM_LOOPS_OF_VERT) {
- if ((l_other->f != f) && BM_ELEM_API_FLAG_TEST(l_other->f, FACE_NET)) {
- CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata,
- l_iter->head.data, &l_other->head.data);
- }
- }
- /* tag not to interpolate */
- BM_ELEM_API_FLAG_ENABLE(l_iter->v, VERT_VISIT);
-
-
- mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
- blocks[i] = l_iter->head.data;
-
- } while ((void)i++, (l_iter = l_iter->next) != l_first);
-
-
- for (i = 0; i < edge_net_len; i++) {
- BM_ITER_ELEM (v, &iter, edge_net[i], BM_VERTS_OF_EDGE) {
- if (!BM_ELEM_API_FLAG_TEST(v, VERT_VISIT)) {
- BMIter liter;
-
- BM_ELEM_API_FLAG_ENABLE(v, VERT_VISIT);
-
- /* interpolate this loop, then copy to the rest */
- l_first = NULL;
-
- BM_ITER_ELEM (l_iter, &liter, v, BM_LOOPS_OF_VERT) {
- if (BM_ELEM_API_FLAG_TEST(l_iter->f, FACE_NET)) {
- if (l_first == NULL) {
- mul_v2_m3v3(co, axis_mat, v->co);
- interp_weights_poly_v2(w, cos_2d, f->len, co);
- CustomData_bmesh_interp(
- &bm->ldata, (const void **)blocks,
- w, NULL, f->len, l_iter->head.data);
- l_first = l_iter;
- }
- else {
- CustomData_bmesh_copy_data(&bm->ldata, &bm->ldata,
- l_first->head.data, &l_iter->head.data);
- }
- }
- }
- }
- }
- }
- }
-
-
-
- /* cleanup */
- for (i = 0; i < edge_net_len; i++) {
- BM_ELEM_API_FLAG_DISABLE(edge_net[i], EDGE_NET);
- /* from interp only */
- BM_ELEM_API_FLAG_DISABLE(edge_net[i]->v1, VERT_VISIT);
- BM_ELEM_API_FLAG_DISABLE(edge_net[i]->v2, VERT_VISIT);
- }
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BM_ELEM_API_FLAG_DISABLE(l_iter->e, EDGE_NET);
- /* from interp only */
- BM_ELEM_API_FLAG_DISABLE(l_iter->v, VERT_VISIT);
- } while ((l_iter = l_iter->next) != l_first);
-
- if (BLI_array_len(face_arr)) {
- bmesh_face_swap_data(f, face_arr[0]);
- BM_face_kill(bm, face_arr[0]);
- face_arr[0] = f;
- }
- else {
- BM_ELEM_API_FLAG_DISABLE(f, FACE_NET);
- }
-
- for (i = 0; i < BLI_array_len(face_arr); i++) {
- BM_ELEM_API_FLAG_DISABLE(face_arr[i], FACE_NET);
- }
-
- if (r_face_arr) {
- *r_face_arr = face_arr;
- *r_face_arr_len = BLI_array_len(face_arr);
- }
- else {
- if (face_arr) {
- MEM_freeN(face_arr);
- }
- }
-
- return true;
+ /* Note: 'VERT_IN_QUEUE' is often not needed at all,
+ * however in rare cases verts are added multiple times to the queue,
+ * that on it's own is harmless but in _very_ rare cases,
+ * the queue will overflow its maximum size,
+ * so we better be strict about this! see: T51539 */
+
+ for (i = 0; i < edge_net_len; i++) {
+ BM_ELEM_API_FLAG_ENABLE(edge_net[i], EDGE_NET);
+ BM_ELEM_API_FLAG_DISABLE(edge_net[i]->v1, VERT_IN_QUEUE);
+ BM_ELEM_API_FLAG_DISABLE(edge_net[i]->v2, VERT_IN_QUEUE);
+ }
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_ELEM_API_FLAG_ENABLE(l_iter->e, EDGE_NET);
+ BM_ELEM_API_FLAG_DISABLE(l_iter->v, VERT_IN_QUEUE);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ float face_normal_matrix[3][3];
+ axis_dominant_v3_to_m3(face_normal_matrix, f->no);
+
+ /* any vert can be used to begin with */
+ STACK_PUSH(vert_queue, l_first->v);
+ BM_ELEM_API_FLAG_ENABLE(l_first->v, VERT_IN_QUEUE);
+
+ while ((v = STACK_POP(vert_queue))) {
+ BM_ELEM_API_FLAG_DISABLE(v, VERT_IN_QUEUE);
+ if (bm_face_split_edgenet_find_loop(v,
+ f->no,
+ face_normal_matrix,
+ edge_order,
+ edge_order_len,
+ face_verts,
+ &face_verts_len)) {
+ BMFace *f_new;
+
+ f_new = BM_face_create_verts(bm, face_verts, face_verts_len, f, BM_CREATE_NOP, false);
+
+ for (i = 0; i < edge_net_len; i++) {
+ BLI_assert(BM_ELEM_API_FLAG_TEST(edge_net[i], EDGE_NET));
+ }
+
+ if (f_new) {
+ BLI_array_append(face_arr, f_new);
+ copy_v3_v3(f_new->no, f->no);
+
+ /* warning, normally don't do this,
+ * its needed for mesh intersection - which tracks face-sides based on selection */
+ f_new->head.hflag = f->head.hflag;
+ if (f->head.hflag & BM_ELEM_SELECT) {
+ bm->totfacesel++;
+ }
+
+ BM_ELEM_API_FLAG_ENABLE(f_new, FACE_NET);
+
+ /* add new verts to keep finding loops for
+ * (verts between boundary and manifold edges) */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
+ do {
+ /* Avoid adding to queue multiple times (not common but happens). */
+ if (!BM_ELEM_API_FLAG_TEST(l_iter->v, VERT_IN_QUEUE) &&
+ bm_face_split_edgenet_find_loop_pair_exists(l_iter->v)) {
+ STACK_PUSH(vert_queue, l_iter->v);
+ BM_ELEM_API_FLAG_ENABLE(l_iter->v, VERT_IN_QUEUE);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+ }
+
+ if (CustomData_has_math(&bm->ldata)) {
+ /* reuse VERT_VISIT here to tag vert's already interpolated */
+ BMIter iter;
+ BMLoop *l_other;
+
+ /* see: #BM_loop_interp_from_face for similar logic */
+ void **blocks = BLI_array_alloca(blocks, f->len);
+ float(*cos_2d)[2] = BLI_array_alloca(cos_2d, f->len);
+ float *w = BLI_array_alloca(w, f->len);
+ float axis_mat[3][3];
+ float co[2];
+
+ /* interior loops */
+ axis_dominant_v3_to_m3(axis_mat, f->no);
+
+ /* first simply copy from existing face */
+ i = 0;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_ITER_ELEM (l_other, &iter, l_iter->v, BM_LOOPS_OF_VERT) {
+ if ((l_other->f != f) && BM_ELEM_API_FLAG_TEST(l_other->f, FACE_NET)) {
+ CustomData_bmesh_copy_data(
+ &bm->ldata, &bm->ldata, l_iter->head.data, &l_other->head.data);
+ }
+ }
+ /* tag not to interpolate */
+ BM_ELEM_API_FLAG_ENABLE(l_iter->v, VERT_VISIT);
+
+ mul_v2_m3v3(cos_2d[i], axis_mat, l_iter->v->co);
+ blocks[i] = l_iter->head.data;
+
+ } while ((void)i++, (l_iter = l_iter->next) != l_first);
+
+ for (i = 0; i < edge_net_len; i++) {
+ BM_ITER_ELEM (v, &iter, edge_net[i], BM_VERTS_OF_EDGE) {
+ if (!BM_ELEM_API_FLAG_TEST(v, VERT_VISIT)) {
+ BMIter liter;
+
+ BM_ELEM_API_FLAG_ENABLE(v, VERT_VISIT);
+
+ /* interpolate this loop, then copy to the rest */
+ l_first = NULL;
+
+ BM_ITER_ELEM (l_iter, &liter, v, BM_LOOPS_OF_VERT) {
+ if (BM_ELEM_API_FLAG_TEST(l_iter->f, FACE_NET)) {
+ if (l_first == NULL) {
+ mul_v2_m3v3(co, axis_mat, v->co);
+ interp_weights_poly_v2(w, cos_2d, f->len, co);
+ CustomData_bmesh_interp(
+ &bm->ldata, (const void **)blocks, w, NULL, f->len, l_iter->head.data);
+ l_first = l_iter;
+ }
+ else {
+ CustomData_bmesh_copy_data(
+ &bm->ldata, &bm->ldata, l_first->head.data, &l_iter->head.data);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* cleanup */
+ for (i = 0; i < edge_net_len; i++) {
+ BM_ELEM_API_FLAG_DISABLE(edge_net[i], EDGE_NET);
+ /* from interp only */
+ BM_ELEM_API_FLAG_DISABLE(edge_net[i]->v1, VERT_VISIT);
+ BM_ELEM_API_FLAG_DISABLE(edge_net[i]->v2, VERT_VISIT);
+ }
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BM_ELEM_API_FLAG_DISABLE(l_iter->e, EDGE_NET);
+ /* from interp only */
+ BM_ELEM_API_FLAG_DISABLE(l_iter->v, VERT_VISIT);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (BLI_array_len(face_arr)) {
+ bmesh_face_swap_data(f, face_arr[0]);
+ BM_face_kill(bm, face_arr[0]);
+ face_arr[0] = f;
+ }
+ else {
+ BM_ELEM_API_FLAG_DISABLE(f, FACE_NET);
+ }
+
+ for (i = 0; i < BLI_array_len(face_arr); i++) {
+ BM_ELEM_API_FLAG_DISABLE(face_arr[i], FACE_NET);
+ }
+
+ if (r_face_arr) {
+ *r_face_arr = face_arr;
+ *r_face_arr_len = BLI_array_len(face_arr);
+ }
+ else {
+ if (face_arr) {
+ MEM_freeN(face_arr);
+ }
+ }
+
+ return true;
}
#undef FACE_NET
@@ -692,7 +696,6 @@ bool BM_face_split_edgenet(
/** \} */
-
/* -------------------------------------------------------------------- */
/* Face Split Edge-Net Connect Islands */
@@ -707,41 +710,41 @@ bool BM_face_split_edgenet(
*
* \{ */
-
#define USE_PARTIAL_CONNECT
-
#define VERT_IS_VALID BM_ELEM_INTERNAL_TAG
/* can be X or Y */
#define SORT_AXIS 0
-BLI_INLINE bool edge_isect_verts_point_2d(
- const BMEdge *e, const BMVert *v_a, const BMVert *v_b,
- float r_isect[2])
+BLI_INLINE bool edge_isect_verts_point_2d(const BMEdge *e,
+ const BMVert *v_a,
+ const BMVert *v_b,
+ float r_isect[2])
{
- /* This bias seems like it could be too large,
- * mostly its not needed, see T52329 for example where it is. */
- const float endpoint_bias = 1e-4f;
- return ((isect_seg_seg_v2_point_ex(v_a->co, v_b->co, e->v1->co, e->v2->co, endpoint_bias, r_isect) == 1) &&
- ((e->v1 != v_a) && (e->v2 != v_a) && (e->v1 != v_b) && (e->v2 != v_b)));
+ /* This bias seems like it could be too large,
+ * mostly its not needed, see T52329 for example where it is. */
+ const float endpoint_bias = 1e-4f;
+ return ((isect_seg_seg_v2_point_ex(
+ v_a->co, v_b->co, e->v1->co, e->v2->co, endpoint_bias, r_isect) == 1) &&
+ ((e->v1 != v_a) && (e->v2 != v_a) && (e->v1 != v_b) && (e->v2 != v_b)));
}
BLI_INLINE int axis_pt_cmp(const float pt_a[2], const float pt_b[2])
{
- if (pt_a[0] < pt_b[0]) {
- return -1;
- }
- if (pt_a[0] > pt_b[0]) {
- return 1;
- }
- if (pt_a[1] < pt_b[1]) {
- return -1;
- }
- if (pt_a[1] > pt_b[1]) {
- return 1;
- }
- return 0;
+ if (pt_a[0] < pt_b[0]) {
+ return -1;
+ }
+ if (pt_a[0] > pt_b[0]) {
+ return 1;
+ }
+ if (pt_a[1] < pt_b[1]) {
+ return -1;
+ }
+ if (pt_a[1] > pt_b[1]) {
+ return 1;
+ }
+ return 0;
}
/**
@@ -750,106 +753,107 @@ BLI_INLINE int axis_pt_cmp(const float pt_a[2], const float pt_b[2])
* (edges remain in `edge_links`).
*/
struct EdgeGroupIsland {
- LinkNode edge_links; /* keep first */
- uint vert_len, edge_len;
-
- /* Set the following vars once we have >1 groups */
-
- /* when when an edge in a previous group connects to this one,
- * so theres no need to create one pointing back. */
- uint has_prev_edge : 1;
-
- /* verts in the group which has the lowest & highest values,
- * the lower vertex is connected to the first edge */
- struct {
- BMVert *min, *max;
- /* used for sorting only */
- float min_axis[2];
- float max_axis[2];
- } vert_span;
+ LinkNode edge_links; /* keep first */
+ uint vert_len, edge_len;
+
+ /* Set the following vars once we have >1 groups */
+
+ /* when when an edge in a previous group connects to this one,
+ * so theres no need to create one pointing back. */
+ uint has_prev_edge : 1;
+
+ /* verts in the group which has the lowest & highest values,
+ * the lower vertex is connected to the first edge */
+ struct {
+ BMVert *min, *max;
+ /* used for sorting only */
+ float min_axis[2];
+ float max_axis[2];
+ } vert_span;
};
static int group_min_cmp_fn(const void *p1, const void *p2)
{
- const struct EdgeGroupIsland *g1 = *(struct EdgeGroupIsland **)p1;
- const struct EdgeGroupIsland *g2 = *(struct EdgeGroupIsland **)p2;
- /* min->co[SORT_AXIS] hasn't been applied yet */
- int test = axis_pt_cmp(g1->vert_span.min_axis, g2->vert_span.min_axis);
- if (UNLIKELY(test == 0)) {
- test = axis_pt_cmp(g1->vert_span.max_axis, g2->vert_span.max_axis);
- }
- return test;
+ const struct EdgeGroupIsland *g1 = *(struct EdgeGroupIsland **)p1;
+ const struct EdgeGroupIsland *g2 = *(struct EdgeGroupIsland **)p2;
+ /* min->co[SORT_AXIS] hasn't been applied yet */
+ int test = axis_pt_cmp(g1->vert_span.min_axis, g2->vert_span.min_axis);
+ if (UNLIKELY(test == 0)) {
+ test = axis_pt_cmp(g1->vert_span.max_axis, g2->vert_span.max_axis);
+ }
+ return test;
}
struct Edges_VertVert_BVHTreeTest {
- float dist_orig;
- BMEdge **edge_arr;
+ float dist_orig;
+ BMEdge **edge_arr;
- BMVert *v_origin;
- BMVert *v_other;
+ BMVert *v_origin;
+ BMVert *v_other;
- const uint *vert_range;
+ const uint *vert_range;
};
struct Edges_VertRay_BVHTreeTest {
- BMEdge **edge_arr;
+ BMEdge **edge_arr;
- BMVert *v_origin;
+ BMVert *v_origin;
- const uint *vert_range;
+ const uint *vert_range;
};
-static void bvhtree_test_edges_isect_2d_vert_cb(
- void *user_data, int index, const BVHTreeRay *UNUSED(ray), BVHTreeRayHit *hit)
+static void bvhtree_test_edges_isect_2d_vert_cb(void *user_data,
+ int index,
+ const BVHTreeRay *UNUSED(ray),
+ BVHTreeRayHit *hit)
{
- struct Edges_VertVert_BVHTreeTest *data = user_data;
- const BMEdge *e = data->edge_arr[index];
- const int v1_index = BM_elem_index_get(e->v1);
- float co_isect[2];
-
- if (edge_isect_verts_point_2d(e, data->v_origin, data->v_other, co_isect)) {
- const float t = line_point_factor_v2(co_isect, data->v_origin->co, data->v_other->co);
- const float dist_new = data->dist_orig * t;
- /* avoid float precision issues, possible this is greater,
- * check above zero to allow some overlap
- * (and needed for partial-connect which will overlap vertices) */
- if (LIKELY((dist_new < hit->dist) && (dist_new > 0.0f))) {
- /* v1/v2 will both be in the same group */
- if (v1_index < (int)data->vert_range[0] ||
- v1_index >= (int)data->vert_range[1])
- {
- hit->dist = dist_new;
- hit->index = index;
- }
- }
- }
+ struct Edges_VertVert_BVHTreeTest *data = user_data;
+ const BMEdge *e = data->edge_arr[index];
+ const int v1_index = BM_elem_index_get(e->v1);
+ float co_isect[2];
+
+ if (edge_isect_verts_point_2d(e, data->v_origin, data->v_other, co_isect)) {
+ const float t = line_point_factor_v2(co_isect, data->v_origin->co, data->v_other->co);
+ const float dist_new = data->dist_orig * t;
+ /* avoid float precision issues, possible this is greater,
+ * check above zero to allow some overlap
+ * (and needed for partial-connect which will overlap vertices) */
+ if (LIKELY((dist_new < hit->dist) && (dist_new > 0.0f))) {
+ /* v1/v2 will both be in the same group */
+ if (v1_index < (int)data->vert_range[0] || v1_index >= (int)data->vert_range[1]) {
+ hit->dist = dist_new;
+ hit->index = index;
+ }
+ }
+ }
}
-static void bvhtree_test_edges_isect_2d_ray_cb(
- void *user_data, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
+static void bvhtree_test_edges_isect_2d_ray_cb(void *user_data,
+ int index,
+ const BVHTreeRay *ray,
+ BVHTreeRayHit *hit)
{
- struct Edges_VertRay_BVHTreeTest *data = user_data;
- const BMEdge *e = data->edge_arr[index];
-
- /* direction is normalized, so this will be the distance */
- float dist_new;
- if (isect_ray_seg_v2(data->v_origin->co, ray->direction, e->v1->co, e->v2->co, &dist_new, NULL)) {
- /* avoid float precision issues, possible this is greater,
- * check above zero to allow some overlap
- * (and needed for partial-connect which will overlap vertices) */
- if (LIKELY(dist_new < hit->dist && (dist_new > 0.0f))) {
- if (e->v1 != data->v_origin && e->v2 != data->v_origin) {
- const int v1_index = BM_elem_index_get(e->v1);
- /* v1/v2 will both be in the same group */
- if (v1_index < (int)data->vert_range[0] ||
- v1_index >= (int)data->vert_range[1])
- {
- hit->dist = dist_new;
- hit->index = index;
- }
- }
- }
- }
+ struct Edges_VertRay_BVHTreeTest *data = user_data;
+ const BMEdge *e = data->edge_arr[index];
+
+ /* direction is normalized, so this will be the distance */
+ float dist_new;
+ if (isect_ray_seg_v2(
+ data->v_origin->co, ray->direction, e->v1->co, e->v2->co, &dist_new, NULL)) {
+ /* avoid float precision issues, possible this is greater,
+ * check above zero to allow some overlap
+ * (and needed for partial-connect which will overlap vertices) */
+ if (LIKELY(dist_new < hit->dist && (dist_new > 0.0f))) {
+ if (e->v1 != data->v_origin && e->v2 != data->v_origin) {
+ const int v1_index = BM_elem_index_get(e->v1);
+ /* v1/v2 will both be in the same group */
+ if (v1_index < (int)data->vert_range[0] || v1_index >= (int)data->vert_range[1]) {
+ hit->dist = dist_new;
+ hit->index = index;
+ }
+ }
+ }
+ }
}
/**
@@ -859,186 +863,193 @@ static void bvhtree_test_edges_isect_2d_ray_cb(
* ... which don't change each call.
*/
struct EdgeGroup_FindConnection_Args {
- BVHTree *bvhtree;
- BMEdge **edge_arr;
- uint edge_arr_len;
+ BVHTree *bvhtree;
+ BMEdge **edge_arr;
+ uint edge_arr_len;
- BMEdge **edge_arr_new;
- uint edge_arr_new_len;
+ BMEdge **edge_arr_new;
+ uint edge_arr_new_len;
- const uint *vert_range;
+ const uint *vert_range;
};
-static BMEdge *test_edges_isect_2d_vert(
- const struct EdgeGroup_FindConnection_Args *args,
- BMVert *v_origin, BMVert *v_other)
+static BMEdge *test_edges_isect_2d_vert(const struct EdgeGroup_FindConnection_Args *args,
+ BMVert *v_origin,
+ BMVert *v_other)
{
- int index;
-
- BVHTreeRayHit hit = {0};
- float dir[3];
-
- sub_v2_v2v2(dir, v_other->co, v_origin->co);
- dir[2] = 0.0f;
- hit.index = -1;
- hit.dist = normalize_v2(dir);
-
- struct Edges_VertVert_BVHTreeTest user_data = {0};
- user_data.dist_orig = hit.dist;
- user_data.edge_arr = args->edge_arr;
- user_data.v_origin = v_origin;
- user_data.v_other = v_other;
- user_data.vert_range = args->vert_range;
-
- index = BLI_bvhtree_ray_cast_ex(
- args->bvhtree, v_origin->co, dir, 0.0f, &hit,
- bvhtree_test_edges_isect_2d_vert_cb, &user_data, 0);
-
- BMEdge *e_hit = (index != -1) ? args->edge_arr[index] : NULL;
-
- /* check existing connections (no spatial optimization here since we're continually adding). */
- if (LIKELY(index == -1)) {
- float t_best = 1.0f;
- for (uint i = 0; i < args->edge_arr_new_len; i++) {
- float co_isect[2];
- if (UNLIKELY(edge_isect_verts_point_2d(args->edge_arr_new[i], v_origin, v_other, co_isect))) {
- const float t_test = line_point_factor_v2(co_isect, v_origin->co, v_other->co);
- if (t_test < t_best) {
- t_best = t_test;
-
- e_hit = args->edge_arr_new[i];
- }
- }
- }
- }
-
- return e_hit;
+ int index;
+
+ BVHTreeRayHit hit = {0};
+ float dir[3];
+
+ sub_v2_v2v2(dir, v_other->co, v_origin->co);
+ dir[2] = 0.0f;
+ hit.index = -1;
+ hit.dist = normalize_v2(dir);
+
+ struct Edges_VertVert_BVHTreeTest user_data = {0};
+ user_data.dist_orig = hit.dist;
+ user_data.edge_arr = args->edge_arr;
+ user_data.v_origin = v_origin;
+ user_data.v_other = v_other;
+ user_data.vert_range = args->vert_range;
+
+ index = BLI_bvhtree_ray_cast_ex(args->bvhtree,
+ v_origin->co,
+ dir,
+ 0.0f,
+ &hit,
+ bvhtree_test_edges_isect_2d_vert_cb,
+ &user_data,
+ 0);
+
+ BMEdge *e_hit = (index != -1) ? args->edge_arr[index] : NULL;
+
+ /* check existing connections (no spatial optimization here since we're continually adding). */
+ if (LIKELY(index == -1)) {
+ float t_best = 1.0f;
+ for (uint i = 0; i < args->edge_arr_new_len; i++) {
+ float co_isect[2];
+ if (UNLIKELY(
+ edge_isect_verts_point_2d(args->edge_arr_new[i], v_origin, v_other, co_isect))) {
+ const float t_test = line_point_factor_v2(co_isect, v_origin->co, v_other->co);
+ if (t_test < t_best) {
+ t_best = t_test;
+
+ e_hit = args->edge_arr_new[i];
+ }
+ }
+ }
+ }
+
+ return e_hit;
}
/**
* Similar to #test_edges_isect_2d_vert but we're casting into a direction,
* (not to a vertex)
*/
-static BMEdge *test_edges_isect_2d_ray(
- const struct EdgeGroup_FindConnection_Args *args,
- BMVert *v_origin, const float dir[3])
+static BMEdge *test_edges_isect_2d_ray(const struct EdgeGroup_FindConnection_Args *args,
+ BMVert *v_origin,
+ const float dir[3])
{
- int index;
- BVHTreeRayHit hit = {0};
-
- BLI_ASSERT_UNIT_V2(dir);
-
- hit.index = -1;
- hit.dist = BVH_RAYCAST_DIST_MAX;
-
- struct Edges_VertRay_BVHTreeTest user_data = {0};
- user_data.edge_arr = args->edge_arr;
- user_data.v_origin = v_origin;
- user_data.vert_range = args->vert_range;
-
- index = BLI_bvhtree_ray_cast_ex(
- args->bvhtree, v_origin->co, dir, 0.0f, &hit,
- bvhtree_test_edges_isect_2d_ray_cb, &user_data, 0);
-
- BMEdge *e_hit = (index != -1) ? args->edge_arr[index] : NULL;
-
- /* check existing connections (no spatial optimization here since we're continually adding). */
- if (LIKELY(index != -1)) {
- for (uint i = 0; i < args->edge_arr_new_len; i++) {
- BMEdge *e = args->edge_arr_new[i];
- float dist_new;
- if (isect_ray_seg_v2(v_origin->co, dir, e->v1->co, e->v2->co, &dist_new, NULL)) {
- if (e->v1 != v_origin && e->v2 != v_origin) {
- /* avoid float precision issues, possible this is greater */
- if (LIKELY(dist_new < hit.dist)) {
- hit.dist = dist_new;
-
- e_hit = args->edge_arr_new[i];
- }
- }
- }
- }
- }
-
- return e_hit;
+ int index;
+ BVHTreeRayHit hit = {0};
+
+ BLI_ASSERT_UNIT_V2(dir);
+
+ hit.index = -1;
+ hit.dist = BVH_RAYCAST_DIST_MAX;
+
+ struct Edges_VertRay_BVHTreeTest user_data = {0};
+ user_data.edge_arr = args->edge_arr;
+ user_data.v_origin = v_origin;
+ user_data.vert_range = args->vert_range;
+
+ index = BLI_bvhtree_ray_cast_ex(args->bvhtree,
+ v_origin->co,
+ dir,
+ 0.0f,
+ &hit,
+ bvhtree_test_edges_isect_2d_ray_cb,
+ &user_data,
+ 0);
+
+ BMEdge *e_hit = (index != -1) ? args->edge_arr[index] : NULL;
+
+ /* check existing connections (no spatial optimization here since we're continually adding). */
+ if (LIKELY(index != -1)) {
+ for (uint i = 0; i < args->edge_arr_new_len; i++) {
+ BMEdge *e = args->edge_arr_new[i];
+ float dist_new;
+ if (isect_ray_seg_v2(v_origin->co, dir, e->v1->co, e->v2->co, &dist_new, NULL)) {
+ if (e->v1 != v_origin && e->v2 != v_origin) {
+ /* avoid float precision issues, possible this is greater */
+ if (LIKELY(dist_new < hit.dist)) {
+ hit.dist = dist_new;
+
+ e_hit = args->edge_arr_new[i];
+ }
+ }
+ }
+ }
+ }
+
+ return e_hit;
}
-static int bm_face_split_edgenet_find_connection(
- const struct EdgeGroup_FindConnection_Args *args,
- BMVert *v_origin,
- /* false = negative, true = positive */
- bool direction_sign)
+static int bm_face_split_edgenet_find_connection(const struct EdgeGroup_FindConnection_Args *args,
+ BMVert *v_origin,
+ /* false = negative, true = positive */
+ bool direction_sign)
{
- /**
- * Method for finding connection is as follows:
- *
- * - Cast a ray along either the positive or negative directions.
- * - Take the hit-edge, and cast rays to their vertices checking those rays don't intersect a closer edge.
- * - Keep taking the hit-edge and testing its verts until a vertex is found which isn't blocked by an edge.
- *
- * \note It's possible none of the verts can be accessed (with self-intersecting lines).
- * In that case theres no right answer (without subdividing edges),
- * so return a fall-back vertex in that case.
- */
-
- const float dir[3] = {[SORT_AXIS] = direction_sign ? 1.0f : -1.0f};
- BMEdge *e_hit = test_edges_isect_2d_ray(args, v_origin, dir);
- BMVert *v_other = NULL;
-
- if (e_hit) {
- BMVert *v_other_fallback = NULL;
-
- BLI_SMALLSTACK_DECLARE(vert_search, BMVert *);
-
- /* ensure we never add verts multiple times (not all that likely - but possible) */
- BLI_SMALLSTACK_DECLARE(vert_blacklist, BMVert *);
-
- do {
- BMVert *v_pair[2];
- /* ensure the closest vertex is popped back off the stack first */
- if (len_squared_v2v2(v_origin->co, e_hit->v1->co) >
- len_squared_v2v2(v_origin->co, e_hit->v2->co))
- {
- ARRAY_SET_ITEMS(v_pair, e_hit->v1, e_hit->v2);
- }
- else {
- ARRAY_SET_ITEMS(v_pair, e_hit->v2, e_hit->v1);
- }
-
- for (int j = 0; j < 2; j++) {
- BMVert *v_iter = v_pair[j];
- if (BM_elem_flag_test(v_iter, VERT_IS_VALID)) {
- if (direction_sign ? (v_iter->co[SORT_AXIS] > v_origin->co[SORT_AXIS]) :
- (v_iter->co[SORT_AXIS] < v_origin->co[SORT_AXIS]))
- {
- BLI_SMALLSTACK_PUSH(vert_search, v_iter);
- BLI_SMALLSTACK_PUSH(vert_blacklist, v_iter);
- BM_elem_flag_disable(v_iter, VERT_IS_VALID);
- }
- }
- }
- v_other_fallback = v_other;
-
- } while ((v_other = BLI_SMALLSTACK_POP(vert_search)) &&
- (e_hit = test_edges_isect_2d_vert(args, v_origin, v_other)));
-
- if (v_other == NULL) {
- printf("Using fallback\n");
- v_other = v_other_fallback;
- }
-
- /* reset the blacklist flag, for future use */
- BMVert *v;
- while ((v = BLI_SMALLSTACK_POP(vert_blacklist))) {
- BM_elem_flag_enable(v, VERT_IS_VALID);
- }
- }
-
- /* if we reach this line, v_other is either the best vertex or its NULL */
- return v_other ? BM_elem_index_get(v_other) : -1;
+ /**
+ * Method for finding connection is as follows:
+ *
+ * - Cast a ray along either the positive or negative directions.
+ * - Take the hit-edge, and cast rays to their vertices checking those rays don't intersect a closer edge.
+ * - Keep taking the hit-edge and testing its verts until a vertex is found which isn't blocked by an edge.
+ *
+ * \note It's possible none of the verts can be accessed (with self-intersecting lines).
+ * In that case theres no right answer (without subdividing edges),
+ * so return a fall-back vertex in that case.
+ */
+
+ const float dir[3] = {[SORT_AXIS] = direction_sign ? 1.0f : -1.0f};
+ BMEdge *e_hit = test_edges_isect_2d_ray(args, v_origin, dir);
+ BMVert *v_other = NULL;
+
+ if (e_hit) {
+ BMVert *v_other_fallback = NULL;
+
+ BLI_SMALLSTACK_DECLARE(vert_search, BMVert *);
+
+ /* ensure we never add verts multiple times (not all that likely - but possible) */
+ BLI_SMALLSTACK_DECLARE(vert_blacklist, BMVert *);
+
+ do {
+ BMVert *v_pair[2];
+ /* ensure the closest vertex is popped back off the stack first */
+ if (len_squared_v2v2(v_origin->co, e_hit->v1->co) >
+ len_squared_v2v2(v_origin->co, e_hit->v2->co)) {
+ ARRAY_SET_ITEMS(v_pair, e_hit->v1, e_hit->v2);
+ }
+ else {
+ ARRAY_SET_ITEMS(v_pair, e_hit->v2, e_hit->v1);
+ }
+
+ for (int j = 0; j < 2; j++) {
+ BMVert *v_iter = v_pair[j];
+ if (BM_elem_flag_test(v_iter, VERT_IS_VALID)) {
+ if (direction_sign ? (v_iter->co[SORT_AXIS] > v_origin->co[SORT_AXIS]) :
+ (v_iter->co[SORT_AXIS] < v_origin->co[SORT_AXIS])) {
+ BLI_SMALLSTACK_PUSH(vert_search, v_iter);
+ BLI_SMALLSTACK_PUSH(vert_blacklist, v_iter);
+ BM_elem_flag_disable(v_iter, VERT_IS_VALID);
+ }
+ }
+ }
+ v_other_fallback = v_other;
+
+ } while ((v_other = BLI_SMALLSTACK_POP(vert_search)) &&
+ (e_hit = test_edges_isect_2d_vert(args, v_origin, v_other)));
+
+ if (v_other == NULL) {
+ printf("Using fallback\n");
+ v_other = v_other_fallback;
+ }
+
+ /* reset the blacklist flag, for future use */
+ BMVert *v;
+ while ((v = BLI_SMALLSTACK_POP(vert_blacklist))) {
+ BM_elem_flag_enable(v, VERT_IS_VALID);
+ }
+ }
+
+ /* if we reach this line, v_other is either the best vertex or its NULL */
+ return v_other ? BM_elem_index_get(v_other) : -1;
}
-
/**
* Support for connecting islands that have single-edge connections.
* This options is not very optimal (however its not needed for booleans either).
@@ -1051,8 +1062,8 @@ static int bm_face_split_edgenet_find_connection(
*/
static bool test_tagged_and_notface(BMEdge *e, void *fptr)
{
- BMFace *f = (BMFace *)fptr;
- return BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG) && !BM_edge_in_face(e, f);
+ BMFace *f = (BMFace *)fptr;
+ return BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG) && !BM_edge_in_face(e, f);
}
/**
@@ -1064,148 +1075,144 @@ static bool test_tagged_and_notface(BMEdge *e, void *fptr)
*/
static BMVert *bm_face_split_edgenet_partial_connect(BMesh *bm, BMVert *v_delimit, BMFace *f)
{
- /* -------------------------------------------------------------------- */
- /* Initial check that we may be a delimiting vert (keep this fast) */
-
- /* initial check - see if we have 3+ flagged edges attached to 'v_delimit'
- * if not, we can early exit */
- LinkNode *e_delimit_list = NULL;
- uint e_delimit_list_len = 0;
-
-#define EDGE_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
-#define VERT_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
-
-#define FOREACH_VERT_EDGE(v_, e_, body_) { \
- BMEdge *e_ = v_->e; \
- do { body_ } while ((e_ = BM_DISK_EDGE_NEXT(e_, v_)) != v_->e); \
-} ((void)0)
-
- /* start with face edges, since we need to split away wire-only edges */
- BMEdge *e_face_init = NULL;
-
- FOREACH_VERT_EDGE(v_delimit, e_iter, {
- if (BM_elem_flag_test(e_iter, EDGE_NOT_IN_STACK)) {
- BLI_assert(BM_elem_flag_test(BM_edge_other_vert(e_iter, v_delimit), VERT_NOT_IN_STACK));
- BLI_linklist_prepend_alloca(&e_delimit_list, e_iter);
- e_delimit_list_len++;
- if (e_iter->l != NULL && BM_edge_in_face(e_iter, f)) {
- e_face_init = e_iter;
- }
- }
- });
-
- /* skip typical edge-chain verts */
- if (LIKELY(e_delimit_list_len <= 2)) {
- return NULL;
- }
-
-
- /* -------------------------------------------------------------------- */
- /* Complicated stuff starts now! */
-
-
- /* Store connected vertices for restoring the flag */
- LinkNode *vert_stack = NULL;
- BLI_linklist_prepend_alloca(&vert_stack, v_delimit);
- BM_elem_flag_disable(v_delimit, VERT_NOT_IN_STACK);
-
- /* Walk the net... */
- {
- BLI_SMALLSTACK_DECLARE(search, BMVert *);
- BMVert *v_other = BM_edge_other_vert(e_face_init ? e_face_init : v_delimit->e, v_delimit);
-
- BLI_SMALLSTACK_PUSH(search, v_other);
- BM_elem_flag_disable(v_other, VERT_NOT_IN_STACK);
-
- while ((v_other = BLI_SMALLSTACK_POP(search))) {
- BLI_assert(BM_elem_flag_test(v_other, VERT_NOT_IN_STACK) == false);
- BLI_linklist_prepend_alloca(&vert_stack, v_other);
- BMEdge *e_iter = v_other->e;
- do {
- BMVert *v_step = BM_edge_other_vert(e_iter, v_other);
- if (BM_elem_flag_test(e_iter, EDGE_NOT_IN_STACK)) {
- if (BM_elem_flag_test(v_step, VERT_NOT_IN_STACK)) {
- BM_elem_flag_disable(v_step, VERT_NOT_IN_STACK);
- BLI_SMALLSTACK_PUSH(search, v_step);
- }
- }
- } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_other)) != v_other->e);
- }
- }
-
- /* Detect if this is a delimiter by checking if we didn't walk any of edges connected to 'v_delimit' */
- bool is_delimit = false;
- FOREACH_VERT_EDGE(v_delimit, e_iter, {
- BMVert *v_step = BM_edge_other_vert(e_iter, v_delimit);
- if (BM_elem_flag_test(v_step, VERT_NOT_IN_STACK) && !BM_edge_in_face(e_iter, f)) {
- is_delimit = true; /* if one vertex is valid - we have a mix */
- }
- else {
- /* match the vertex flag (only for edges around 'v_delimit') */
- BM_elem_flag_disable(e_iter, EDGE_NOT_IN_STACK);
- }
- });
-
-#undef FOREACH_VERT_EDGE
-
- /* Execute the split */
- BMVert *v_split = NULL;
- if (is_delimit) {
- v_split = BM_vert_create(bm, v_delimit->co, NULL, 0);
- BM_vert_separate_tested_edges(bm, v_split, v_delimit, test_tagged_and_notface, f);
- BM_elem_flag_enable(v_split, VERT_NOT_IN_STACK);
-
- BLI_assert(v_delimit->e != NULL);
-
- /* Degenerate, avoid eternal loop, see: T59074. */
-#if 0
- BLI_assert(v_split->e != NULL);
-#else
- if (UNLIKELY(v_split->e == NULL)) {
- BM_vert_kill(bm, v_split);
- v_split = NULL;
- }
-#endif
- }
-
- /* Restore flags */
- do {
- BM_elem_flag_enable((BMVert *)vert_stack->link, VERT_NOT_IN_STACK);
- } while ((vert_stack = vert_stack->next));
-
- do {
- BM_elem_flag_enable((BMEdge *)e_delimit_list->link, EDGE_NOT_IN_STACK);
- } while ((e_delimit_list = e_delimit_list->next));
-
-#undef EDGE_NOT_IN_STACK
-#undef VERT_NOT_IN_STACK
-
- return v_split;
+ /* -------------------------------------------------------------------- */
+ /* Initial check that we may be a delimiting vert (keep this fast) */
+
+ /* initial check - see if we have 3+ flagged edges attached to 'v_delimit'
+ * if not, we can early exit */
+ LinkNode *e_delimit_list = NULL;
+ uint e_delimit_list_len = 0;
+
+# define EDGE_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
+# define VERT_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
+
+# define FOREACH_VERT_EDGE(v_, e_, body_) \
+ { \
+ BMEdge *e_ = v_->e; \
+ do { \
+ body_ \
+ } while ((e_ = BM_DISK_EDGE_NEXT(e_, v_)) != v_->e); \
+ } \
+ ((void)0)
+
+ /* start with face edges, since we need to split away wire-only edges */
+ BMEdge *e_face_init = NULL;
+
+ FOREACH_VERT_EDGE(v_delimit, e_iter, {
+ if (BM_elem_flag_test(e_iter, EDGE_NOT_IN_STACK)) {
+ BLI_assert(BM_elem_flag_test(BM_edge_other_vert(e_iter, v_delimit), VERT_NOT_IN_STACK));
+ BLI_linklist_prepend_alloca(&e_delimit_list, e_iter);
+ e_delimit_list_len++;
+ if (e_iter->l != NULL && BM_edge_in_face(e_iter, f)) {
+ e_face_init = e_iter;
+ }
+ }
+ });
+
+ /* skip typical edge-chain verts */
+ if (LIKELY(e_delimit_list_len <= 2)) {
+ return NULL;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Complicated stuff starts now! */
+
+ /* Store connected vertices for restoring the flag */
+ LinkNode *vert_stack = NULL;
+ BLI_linklist_prepend_alloca(&vert_stack, v_delimit);
+ BM_elem_flag_disable(v_delimit, VERT_NOT_IN_STACK);
+
+ /* Walk the net... */
+ {
+ BLI_SMALLSTACK_DECLARE(search, BMVert *);
+ BMVert *v_other = BM_edge_other_vert(e_face_init ? e_face_init : v_delimit->e, v_delimit);
+
+ BLI_SMALLSTACK_PUSH(search, v_other);
+ BM_elem_flag_disable(v_other, VERT_NOT_IN_STACK);
+
+ while ((v_other = BLI_SMALLSTACK_POP(search))) {
+ BLI_assert(BM_elem_flag_test(v_other, VERT_NOT_IN_STACK) == false);
+ BLI_linklist_prepend_alloca(&vert_stack, v_other);
+ BMEdge *e_iter = v_other->e;
+ do {
+ BMVert *v_step = BM_edge_other_vert(e_iter, v_other);
+ if (BM_elem_flag_test(e_iter, EDGE_NOT_IN_STACK)) {
+ if (BM_elem_flag_test(v_step, VERT_NOT_IN_STACK)) {
+ BM_elem_flag_disable(v_step, VERT_NOT_IN_STACK);
+ BLI_SMALLSTACK_PUSH(search, v_step);
+ }
+ }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_other)) != v_other->e);
+ }
+ }
+
+ /* Detect if this is a delimiter by checking if we didn't walk any of edges connected to 'v_delimit' */
+ bool is_delimit = false;
+ FOREACH_VERT_EDGE(v_delimit, e_iter, {
+ BMVert *v_step = BM_edge_other_vert(e_iter, v_delimit);
+ if (BM_elem_flag_test(v_step, VERT_NOT_IN_STACK) && !BM_edge_in_face(e_iter, f)) {
+ is_delimit = true; /* if one vertex is valid - we have a mix */
+ }
+ else {
+ /* match the vertex flag (only for edges around 'v_delimit') */
+ BM_elem_flag_disable(e_iter, EDGE_NOT_IN_STACK);
+ }
+ });
+
+# undef FOREACH_VERT_EDGE
+
+ /* Execute the split */
+ BMVert *v_split = NULL;
+ if (is_delimit) {
+ v_split = BM_vert_create(bm, v_delimit->co, NULL, 0);
+ BM_vert_separate_tested_edges(bm, v_split, v_delimit, test_tagged_and_notface, f);
+ BM_elem_flag_enable(v_split, VERT_NOT_IN_STACK);
+
+ BLI_assert(v_delimit->e != NULL);
+
+ /* Degenerate, avoid eternal loop, see: T59074. */
+# if 0
+ BLI_assert(v_split->e != NULL);
+# else
+ if (UNLIKELY(v_split->e == NULL)) {
+ BM_vert_kill(bm, v_split);
+ v_split = NULL;
+ }
+# endif
+ }
+
+ /* Restore flags */
+ do {
+ BM_elem_flag_enable((BMVert *)vert_stack->link, VERT_NOT_IN_STACK);
+ } while ((vert_stack = vert_stack->next));
+
+ do {
+ BM_elem_flag_enable((BMEdge *)e_delimit_list->link, EDGE_NOT_IN_STACK);
+ } while ((e_delimit_list = e_delimit_list->next));
+
+# undef EDGE_NOT_IN_STACK
+# undef VERT_NOT_IN_STACK
+
+ return v_split;
}
-
/**
* Check if connecting vertices would cause an edge with duplicate verts.
*/
-static bool bm_vert_partial_connect_check_overlap(
- const int *remap,
- const int v_a_index, const int v_b_index)
+static bool bm_vert_partial_connect_check_overlap(const int *remap,
+ const int v_a_index,
+ const int v_b_index)
{
- /* connected to eachother */
- if (UNLIKELY((remap[v_a_index] == v_b_index) ||
- (remap[v_b_index] == v_a_index)))
- {
- return true;
- }
- else {
- return false;
- }
+ /* connected to eachother */
+ if (UNLIKELY((remap[v_a_index] == v_b_index) || (remap[v_b_index] == v_a_index))) {
+ return true;
+ }
+ else {
+ return false;
+ }
}
-
-#endif /* USE_PARTIAL_CONNECT */
-
-
+#endif /* USE_PARTIAL_CONNECT */
/**
* For when the edge-net has holes in it-this connects them.
@@ -1215,476 +1222,470 @@ static bool bm_vert_partial_connect_check_overlap(
* \param mem_arena: Avoids many small allocs & should be cleared after each use.
* take care since \a r_edge_net_new is stored in \a r_edge_net_new.
*/
-bool BM_face_split_edgenet_connect_islands(
- BMesh *bm,
- BMFace *f, BMEdge **edge_net_init, const uint edge_net_init_len,
- bool use_partial_connect,
- MemArena *mem_arena,
- BMEdge ***r_edge_net_new, uint *r_edge_net_new_len)
+bool BM_face_split_edgenet_connect_islands(BMesh *bm,
+ BMFace *f,
+ BMEdge **edge_net_init,
+ const uint edge_net_init_len,
+ bool use_partial_connect,
+ MemArena *mem_arena,
+ BMEdge ***r_edge_net_new,
+ uint *r_edge_net_new_len)
{
- /* -------------------------------------------------------------------- */
- /* This function has 2 main parts.
- *
- * - Check if there are any holes.
- * - Connect the holes with edges (if any are found).
- *
- * Keep the first part fast since it will run very often for edge-nets that have no holes.
- *
- * \note Don't use the mem_arena unless he have holes to fill.
- * (avoid thrashing the area when the initial check isn't so intensive on the stack).
- */
-
- const uint edge_arr_len = (uint)edge_net_init_len + (uint)f->len;
- BMEdge **edge_arr = BLI_array_alloca(edge_arr, edge_arr_len);
- bool ok = false;
- uint edge_net_new_len = (uint)edge_net_init_len;
-
- memcpy(edge_arr, edge_net_init, sizeof(*edge_arr) * (size_t)edge_net_init_len);
-
- /* _must_ clear on exit */
-#define EDGE_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
-#define VERT_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
-
- {
- uint i = edge_net_init_len;
- BMLoop *l_iter, *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BLI_assert(!BM_elem_flag_test(l_iter->v, VERT_NOT_IN_STACK));
- BLI_assert(!BM_elem_flag_test(l_iter->e, EDGE_NOT_IN_STACK));
- edge_arr[i++] = l_iter->e;
- } while ((l_iter = l_iter->next) != l_first);
- BLI_assert(i == edge_arr_len);
- }
-
- for (uint i = 0; i < edge_arr_len; i++) {
- BM_elem_flag_enable(edge_arr[i], EDGE_NOT_IN_STACK);
- BM_elem_flag_enable(edge_arr[i]->v1, VERT_NOT_IN_STACK);
- BM_elem_flag_enable(edge_arr[i]->v2, VERT_NOT_IN_STACK);
- }
-
-
+ /* -------------------------------------------------------------------- */
+ /* This function has 2 main parts.
+ *
+ * - Check if there are any holes.
+ * - Connect the holes with edges (if any are found).
+ *
+ * Keep the first part fast since it will run very often for edge-nets that have no holes.
+ *
+ * \note Don't use the mem_arena unless he have holes to fill.
+ * (avoid thrashing the area when the initial check isn't so intensive on the stack).
+ */
+
+ const uint edge_arr_len = (uint)edge_net_init_len + (uint)f->len;
+ BMEdge **edge_arr = BLI_array_alloca(edge_arr, edge_arr_len);
+ bool ok = false;
+ uint edge_net_new_len = (uint)edge_net_init_len;
+
+ memcpy(edge_arr, edge_net_init, sizeof(*edge_arr) * (size_t)edge_net_init_len);
+
+ /* _must_ clear on exit */
+#define EDGE_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
+#define VERT_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
+
+ {
+ uint i = edge_net_init_len;
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BLI_assert(!BM_elem_flag_test(l_iter->v, VERT_NOT_IN_STACK));
+ BLI_assert(!BM_elem_flag_test(l_iter->e, EDGE_NOT_IN_STACK));
+ edge_arr[i++] = l_iter->e;
+ } while ((l_iter = l_iter->next) != l_first);
+ BLI_assert(i == edge_arr_len);
+ }
+
+ for (uint i = 0; i < edge_arr_len; i++) {
+ BM_elem_flag_enable(edge_arr[i], EDGE_NOT_IN_STACK);
+ BM_elem_flag_enable(edge_arr[i]->v1, VERT_NOT_IN_STACK);
+ BM_elem_flag_enable(edge_arr[i]->v2, VERT_NOT_IN_STACK);
+ }
#ifdef USE_PARTIAL_CONNECT
- /* Split-out delimiting vertices */
- struct TempVertPair {
- struct TempVertPair *next;
- BMVert *v_temp;
- BMVert *v_orig;
- };
-
- struct {
- struct TempVertPair *list;
- uint len;
- int *remap; /* temp -> orig mapping */
- } temp_vert_pairs = {NULL};
-
- if (use_partial_connect) {
- for (uint i = 0; i < edge_net_init_len; i++) {
- for (unsigned j = 0; j < 2; j++) {
- BMVert *v_delimit = (&edge_arr[i]->v1)[j];
- BMVert *v_other;
-
- /* note, remapping will _never_ map a vertex to an already mapped vertex */
- while (UNLIKELY((v_other = bm_face_split_edgenet_partial_connect(bm, v_delimit, f)))) {
- struct TempVertPair *tvp = BLI_memarena_alloc(mem_arena, sizeof(*tvp));
- tvp->next = temp_vert_pairs.list;
- tvp->v_orig = v_delimit;
- tvp->v_temp = v_other;
- temp_vert_pairs.list = tvp;
- temp_vert_pairs.len++;
- }
- }
- }
-
- if (temp_vert_pairs.len == 0) {
- use_partial_connect = false;
- }
- }
-#endif /* USE_PARTIAL_CONNECT */
-
-
-
- uint group_arr_len = 0;
- LinkNode *group_head = NULL;
- {
- /* scan 'edge_arr' backwards so the outer face boundary is handled first
- * (since its likely to be the largest) */
- uint edge_index = (edge_arr_len - 1);
- uint edge_in_group_tot = 0;
-
- BLI_SMALLSTACK_DECLARE(vstack, BMVert *);
-
- while (true) {
- LinkNode *edge_links = NULL;
- uint unique_verts_in_group = 0, unique_edges_in_group = 0;
-
- /* list of groups */
- BLI_assert(BM_elem_flag_test(edge_arr[edge_index]->v1, VERT_NOT_IN_STACK));
- BLI_SMALLSTACK_PUSH(vstack, edge_arr[edge_index]->v1);
- BM_elem_flag_disable(edge_arr[edge_index]->v1, VERT_NOT_IN_STACK);
-
- BMVert *v_iter;
- while ((v_iter = BLI_SMALLSTACK_POP(vstack))) {
- unique_verts_in_group++;
-
- BMEdge *e_iter = v_iter->e;
- do {
- if (BM_elem_flag_test(e_iter, EDGE_NOT_IN_STACK)) {
- BM_elem_flag_disable(e_iter, EDGE_NOT_IN_STACK);
- unique_edges_in_group++;
-
- BLI_linklist_prepend_alloca(&edge_links, e_iter);
-
- BMVert *v_other = BM_edge_other_vert(e_iter, v_iter);
- if (BM_elem_flag_test(v_other, VERT_NOT_IN_STACK)) {
- BLI_SMALLSTACK_PUSH(vstack, v_other);
- BM_elem_flag_disable(v_other, VERT_NOT_IN_STACK);
- }
- }
- } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_iter)) != v_iter->e);
- }
-
- struct EdgeGroupIsland *g = alloca(sizeof(*g));
- g->vert_len = unique_verts_in_group;
- g->edge_len = unique_edges_in_group;
- edge_in_group_tot += unique_edges_in_group;
-
- BLI_linklist_prepend_nlink(&group_head, edge_links, (LinkNode *)g);
-
- group_arr_len++;
-
- if (edge_in_group_tot == edge_arr_len) {
- break;
- }
-
- /* skip edges in the stack */
- while (BM_elem_flag_test(edge_arr[edge_index], EDGE_NOT_IN_STACK) == false) {
- BLI_assert(edge_index != 0);
- edge_index--;
- }
- }
- }
-
- /* single group - no holes */
- if (group_arr_len == 1) {
- goto finally;
- }
-
-
- /* -------------------------------------------------------------------- */
- /* Previous checks need to be kept fast, since they will run very often,
- * now we know there are holes, so calculate a spatial lookup info and
- * other per-group data.
- */
-
- float axis_mat[3][3];
- axis_dominant_v3_to_m3(axis_mat, f->no);
+ /* Split-out delimiting vertices */
+ struct TempVertPair {
+ struct TempVertPair *next;
+ BMVert *v_temp;
+ BMVert *v_orig;
+ };
+
+ struct {
+ struct TempVertPair *list;
+ uint len;
+ int *remap; /* temp -> orig mapping */
+ } temp_vert_pairs = {NULL};
+
+ if (use_partial_connect) {
+ for (uint i = 0; i < edge_net_init_len; i++) {
+ for (unsigned j = 0; j < 2; j++) {
+ BMVert *v_delimit = (&edge_arr[i]->v1)[j];
+ BMVert *v_other;
+
+ /* note, remapping will _never_ map a vertex to an already mapped vertex */
+ while (UNLIKELY((v_other = bm_face_split_edgenet_partial_connect(bm, v_delimit, f)))) {
+ struct TempVertPair *tvp = BLI_memarena_alloc(mem_arena, sizeof(*tvp));
+ tvp->next = temp_vert_pairs.list;
+ tvp->v_orig = v_delimit;
+ tvp->v_temp = v_other;
+ temp_vert_pairs.list = tvp;
+ temp_vert_pairs.len++;
+ }
+ }
+ }
+
+ if (temp_vert_pairs.len == 0) {
+ use_partial_connect = false;
+ }
+ }
+#endif /* USE_PARTIAL_CONNECT */
+
+ uint group_arr_len = 0;
+ LinkNode *group_head = NULL;
+ {
+ /* scan 'edge_arr' backwards so the outer face boundary is handled first
+ * (since its likely to be the largest) */
+ uint edge_index = (edge_arr_len - 1);
+ uint edge_in_group_tot = 0;
+
+ BLI_SMALLSTACK_DECLARE(vstack, BMVert *);
+
+ while (true) {
+ LinkNode *edge_links = NULL;
+ uint unique_verts_in_group = 0, unique_edges_in_group = 0;
+
+ /* list of groups */
+ BLI_assert(BM_elem_flag_test(edge_arr[edge_index]->v1, VERT_NOT_IN_STACK));
+ BLI_SMALLSTACK_PUSH(vstack, edge_arr[edge_index]->v1);
+ BM_elem_flag_disable(edge_arr[edge_index]->v1, VERT_NOT_IN_STACK);
+
+ BMVert *v_iter;
+ while ((v_iter = BLI_SMALLSTACK_POP(vstack))) {
+ unique_verts_in_group++;
+
+ BMEdge *e_iter = v_iter->e;
+ do {
+ if (BM_elem_flag_test(e_iter, EDGE_NOT_IN_STACK)) {
+ BM_elem_flag_disable(e_iter, EDGE_NOT_IN_STACK);
+ unique_edges_in_group++;
+
+ BLI_linklist_prepend_alloca(&edge_links, e_iter);
+
+ BMVert *v_other = BM_edge_other_vert(e_iter, v_iter);
+ if (BM_elem_flag_test(v_other, VERT_NOT_IN_STACK)) {
+ BLI_SMALLSTACK_PUSH(vstack, v_other);
+ BM_elem_flag_disable(v_other, VERT_NOT_IN_STACK);
+ }
+ }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v_iter)) != v_iter->e);
+ }
+
+ struct EdgeGroupIsland *g = alloca(sizeof(*g));
+ g->vert_len = unique_verts_in_group;
+ g->edge_len = unique_edges_in_group;
+ edge_in_group_tot += unique_edges_in_group;
+
+ BLI_linklist_prepend_nlink(&group_head, edge_links, (LinkNode *)g);
+
+ group_arr_len++;
+
+ if (edge_in_group_tot == edge_arr_len) {
+ break;
+ }
+
+ /* skip edges in the stack */
+ while (BM_elem_flag_test(edge_arr[edge_index], EDGE_NOT_IN_STACK) == false) {
+ BLI_assert(edge_index != 0);
+ edge_index--;
+ }
+ }
+ }
+
+ /* single group - no holes */
+ if (group_arr_len == 1) {
+ goto finally;
+ }
+
+ /* -------------------------------------------------------------------- */
+ /* Previous checks need to be kept fast, since they will run very often,
+ * now we know there are holes, so calculate a spatial lookup info and
+ * other per-group data.
+ */
+
+ float axis_mat[3][3];
+ axis_dominant_v3_to_m3(axis_mat, f->no);
#define VERT_IN_ARRAY BM_ELEM_INTERNAL_TAG
- struct EdgeGroupIsland **group_arr = BLI_memarena_alloc(mem_arena, sizeof(*group_arr) * group_arr_len);
- uint vert_arr_len = 0;
- /* sort groups by lowest value vertex */
- {
- /* fill 'groups_arr' in reverse order so the boundary face is first */
- struct EdgeGroupIsland **group_arr_p = &group_arr[group_arr_len];
-
- for (struct EdgeGroupIsland *g = (void *)group_head; g; g = (struct EdgeGroupIsland *)g->edge_links.next) {
- LinkNode *edge_links = g->edge_links.link;
-
- /* init with *any* different verts */
- g->vert_span.min = ((BMEdge *)edge_links->link)->v1;
- g->vert_span.max = ((BMEdge *)edge_links->link)->v2;
- float min_axis[2] = {FLT_MAX, FLT_MAX};
- float max_axis[2] = {-FLT_MAX, -FLT_MAX};
-
- do {
- BMEdge *e = edge_links->link;
- BLI_assert(e->head.htype == BM_EDGE);
-
- for (int j = 0; j < 2; j++) {
- BMVert *v_iter = (&e->v1)[j];
- BLI_assert(v_iter->head.htype == BM_VERT);
- /* ideally we could use 'v_iter->co[SORT_AXIS]' here,
- * but we need to sort the groups before setting the vertex array order */
- const float axis_value[2] = {
+ struct EdgeGroupIsland **group_arr = BLI_memarena_alloc(mem_arena,
+ sizeof(*group_arr) * group_arr_len);
+ uint vert_arr_len = 0;
+ /* sort groups by lowest value vertex */
+ {
+ /* fill 'groups_arr' in reverse order so the boundary face is first */
+ struct EdgeGroupIsland **group_arr_p = &group_arr[group_arr_len];
+
+ for (struct EdgeGroupIsland *g = (void *)group_head; g;
+ g = (struct EdgeGroupIsland *)g->edge_links.next) {
+ LinkNode *edge_links = g->edge_links.link;
+
+ /* init with *any* different verts */
+ g->vert_span.min = ((BMEdge *)edge_links->link)->v1;
+ g->vert_span.max = ((BMEdge *)edge_links->link)->v2;
+ float min_axis[2] = {FLT_MAX, FLT_MAX};
+ float max_axis[2] = {-FLT_MAX, -FLT_MAX};
+
+ do {
+ BMEdge *e = edge_links->link;
+ BLI_assert(e->head.htype == BM_EDGE);
+
+ for (int j = 0; j < 2; j++) {
+ BMVert *v_iter = (&e->v1)[j];
+ BLI_assert(v_iter->head.htype == BM_VERT);
+ /* ideally we could use 'v_iter->co[SORT_AXIS]' here,
+ * but we need to sort the groups before setting the vertex array order */
+ const float axis_value[2] = {
#if SORT_AXIS == 0
- dot_m3_v3_row_x(axis_mat, v_iter->co),
- dot_m3_v3_row_y(axis_mat, v_iter->co),
+ dot_m3_v3_row_x(axis_mat, v_iter->co),
+ dot_m3_v3_row_y(axis_mat, v_iter->co),
#else
- dot_m3_v3_row_y(axis_mat, v_iter->co),
- dot_m3_v3_row_x(axis_mat, v_iter->co),
+ dot_m3_v3_row_y(axis_mat, v_iter->co),
+ dot_m3_v3_row_x(axis_mat, v_iter->co),
#endif
- };
-
- if (axis_pt_cmp(axis_value, min_axis) == -1) {
- g->vert_span.min = v_iter;
- copy_v2_v2(min_axis, axis_value);
- }
- if (axis_pt_cmp(axis_value, max_axis) == 1) {
- g->vert_span.max = v_iter;
- copy_v2_v2(max_axis, axis_value);
- }
- }
- } while ((edge_links = edge_links->next));
-
- copy_v2_v2(g->vert_span.min_axis, min_axis);
- copy_v2_v2(g->vert_span.max_axis, max_axis);
-
- g->has_prev_edge = false;
-
- vert_arr_len += g->vert_len;
-
- *(--group_arr_p) = g;
- }
- }
-
- qsort(group_arr, group_arr_len, sizeof(*group_arr), group_min_cmp_fn);
-
- /* we don't know how many unique verts there are connecting the edges, so over-alloc */
- BMVert **vert_arr = BLI_memarena_alloc(mem_arena, sizeof(*vert_arr) * vert_arr_len);
- /* map vertex -> group index */
- uint *verts_group_table = BLI_memarena_alloc(mem_arena, sizeof(*verts_group_table) * vert_arr_len);
-
- float (*vert_coords_backup)[3] = BLI_memarena_alloc(mem_arena, sizeof(*vert_coords_backup) * vert_arr_len);
-
- {
- /* relative location, for higher precision calculations */
- const float f_co_ref[3] = {UNPACK3(BM_FACE_FIRST_LOOP(f)->v->co)};
-
- int v_index = 0; /* global vert index */
- for (uint g_index = 0; g_index < group_arr_len; g_index++) {
- LinkNode *edge_links = group_arr[g_index]->edge_links.link;
- do {
- BMEdge *e = edge_links->link;
- for (int j = 0; j < 2; j++) {
- BMVert *v_iter = (&e->v1)[j];
- if (!BM_elem_flag_test(v_iter, VERT_IN_ARRAY)) {
- BM_elem_flag_enable(v_iter, VERT_IN_ARRAY);
-
- /* not nice, but alternatives arent much better :S */
- {
- copy_v3_v3(vert_coords_backup[v_index], v_iter->co);
-
- /* for higher precision */
- sub_v3_v3(v_iter->co, f_co_ref);
-
- float co_2d[2];
- mul_v2_m3v3(co_2d, axis_mat, v_iter->co);
- v_iter->co[0] = co_2d[0];
- v_iter->co[1] = co_2d[1];
- v_iter->co[2] = 0.0f;
- }
-
- BM_elem_index_set(v_iter, v_index); /* set_dirty */
-
- vert_arr[v_index] = v_iter;
- verts_group_table[v_index] = g_index;
- v_index++;
- }
- }
- } while ((edge_links = edge_links->next));
- }
- }
-
- bm->elem_index_dirty |= BM_VERT;
-
- /* Now create bvh tree
- *
- * Note that a large epsilon is used because meshes with dimensions of around 100+ need it. see T52329. */
- BVHTree *bvhtree = BLI_bvhtree_new(edge_arr_len, 1e-4f, 8, 8);
- for (uint i = 0; i < edge_arr_len; i++) {
- const float e_cos[2][3] = {
- {UNPACK2(edge_arr[i]->v1->co), 0.0f},
- {UNPACK2(edge_arr[i]->v2->co), 0.0f},
- };
- BLI_bvhtree_insert(bvhtree, i, (const float *)e_cos, 2);
- }
- BLI_bvhtree_balance(bvhtree);
-
-
+ };
+
+ if (axis_pt_cmp(axis_value, min_axis) == -1) {
+ g->vert_span.min = v_iter;
+ copy_v2_v2(min_axis, axis_value);
+ }
+ if (axis_pt_cmp(axis_value, max_axis) == 1) {
+ g->vert_span.max = v_iter;
+ copy_v2_v2(max_axis, axis_value);
+ }
+ }
+ } while ((edge_links = edge_links->next));
+
+ copy_v2_v2(g->vert_span.min_axis, min_axis);
+ copy_v2_v2(g->vert_span.max_axis, max_axis);
+
+ g->has_prev_edge = false;
+
+ vert_arr_len += g->vert_len;
+
+ *(--group_arr_p) = g;
+ }
+ }
+
+ qsort(group_arr, group_arr_len, sizeof(*group_arr), group_min_cmp_fn);
+
+ /* we don't know how many unique verts there are connecting the edges, so over-alloc */
+ BMVert **vert_arr = BLI_memarena_alloc(mem_arena, sizeof(*vert_arr) * vert_arr_len);
+ /* map vertex -> group index */
+ uint *verts_group_table = BLI_memarena_alloc(mem_arena,
+ sizeof(*verts_group_table) * vert_arr_len);
+
+ float(*vert_coords_backup)[3] = BLI_memarena_alloc(mem_arena,
+ sizeof(*vert_coords_backup) * vert_arr_len);
+
+ {
+ /* relative location, for higher precision calculations */
+ const float f_co_ref[3] = {UNPACK3(BM_FACE_FIRST_LOOP(f)->v->co)};
+
+ int v_index = 0; /* global vert index */
+ for (uint g_index = 0; g_index < group_arr_len; g_index++) {
+ LinkNode *edge_links = group_arr[g_index]->edge_links.link;
+ do {
+ BMEdge *e = edge_links->link;
+ for (int j = 0; j < 2; j++) {
+ BMVert *v_iter = (&e->v1)[j];
+ if (!BM_elem_flag_test(v_iter, VERT_IN_ARRAY)) {
+ BM_elem_flag_enable(v_iter, VERT_IN_ARRAY);
+
+ /* not nice, but alternatives arent much better :S */
+ {
+ copy_v3_v3(vert_coords_backup[v_index], v_iter->co);
+
+ /* for higher precision */
+ sub_v3_v3(v_iter->co, f_co_ref);
+
+ float co_2d[2];
+ mul_v2_m3v3(co_2d, axis_mat, v_iter->co);
+ v_iter->co[0] = co_2d[0];
+ v_iter->co[1] = co_2d[1];
+ v_iter->co[2] = 0.0f;
+ }
+
+ BM_elem_index_set(v_iter, v_index); /* set_dirty */
+
+ vert_arr[v_index] = v_iter;
+ verts_group_table[v_index] = g_index;
+ v_index++;
+ }
+ }
+ } while ((edge_links = edge_links->next));
+ }
+ }
+
+ bm->elem_index_dirty |= BM_VERT;
+
+ /* Now create bvh tree
+ *
+ * Note that a large epsilon is used because meshes with dimensions of around 100+ need it. see T52329. */
+ BVHTree *bvhtree = BLI_bvhtree_new(edge_arr_len, 1e-4f, 8, 8);
+ for (uint i = 0; i < edge_arr_len; i++) {
+ const float e_cos[2][3] = {
+ {UNPACK2(edge_arr[i]->v1->co), 0.0f},
+ {UNPACK2(edge_arr[i]->v2->co), 0.0f},
+ };
+ BLI_bvhtree_insert(bvhtree, i, (const float *)e_cos, 2);
+ }
+ BLI_bvhtree_balance(bvhtree);
#ifdef USE_PARTIAL_CONNECT
- if (use_partial_connect) {
- /* needs to be done once the vertex indices have been written into */
- temp_vert_pairs.remap = BLI_memarena_alloc(mem_arena, sizeof(*temp_vert_pairs.remap) * vert_arr_len);
- copy_vn_i(temp_vert_pairs.remap, vert_arr_len, -1);
+ if (use_partial_connect) {
+ /* needs to be done once the vertex indices have been written into */
+ temp_vert_pairs.remap = BLI_memarena_alloc(mem_arena,
+ sizeof(*temp_vert_pairs.remap) * vert_arr_len);
+ copy_vn_i(temp_vert_pairs.remap, vert_arr_len, -1);
- struct TempVertPair *tvp = temp_vert_pairs.list;
- do {
- temp_vert_pairs.remap[BM_elem_index_get(tvp->v_temp)] = BM_elem_index_get(tvp->v_orig);
- } while ((tvp = tvp->next));
- }
-#endif /* USE_PARTIAL_CONNECT */
+ struct TempVertPair *tvp = temp_vert_pairs.list;
+ do {
+ temp_vert_pairs.remap[BM_elem_index_get(tvp->v_temp)] = BM_elem_index_get(tvp->v_orig);
+ } while ((tvp = tvp->next));
+ }
+#endif /* USE_PARTIAL_CONNECT */
+ /* Create connections between groups */
+ /* may be an over-alloc, but not by much */
+ edge_net_new_len = (uint)edge_net_init_len + ((group_arr_len - 1) * 2);
+ BMEdge **edge_net_new = BLI_memarena_alloc(mem_arena, sizeof(*edge_net_new) * edge_net_new_len);
+ memcpy(edge_net_new, edge_net_init, sizeof(*edge_net_new) * (size_t)edge_net_init_len);
- /* Create connections between groups */
+ {
+ uint edge_net_new_index = edge_net_init_len;
+ /* start-end of the verts in the current group */
- /* may be an over-alloc, but not by much */
- edge_net_new_len = (uint)edge_net_init_len + ((group_arr_len - 1) * 2);
- BMEdge **edge_net_new = BLI_memarena_alloc(mem_arena, sizeof(*edge_net_new) * edge_net_new_len);
- memcpy(edge_net_new, edge_net_init, sizeof(*edge_net_new) * (size_t)edge_net_init_len);
+ uint vert_range[2];
- {
- uint edge_net_new_index = edge_net_init_len;
- /* start-end of the verts in the current group */
+ vert_range[0] = 0;
+ vert_range[1] = group_arr[0]->vert_len;
- uint vert_range[2];
+ struct EdgeGroup_FindConnection_Args args = {
+ .bvhtree = bvhtree,
- vert_range[0] = 0;
- vert_range[1] = group_arr[0]->vert_len;
+ /* use the new edge array so we can scan edges which have been added */
+ .edge_arr = edge_arr,
+ .edge_arr_len = edge_arr_len,
- struct EdgeGroup_FindConnection_Args args = {
- .bvhtree = bvhtree,
+ /* we only want to check newly created edges */
+ .edge_arr_new = edge_net_new + edge_net_init_len,
+ .edge_arr_new_len = 0,
- /* use the new edge array so we can scan edges which have been added */
- .edge_arr = edge_arr,
- .edge_arr_len = edge_arr_len,
+ .vert_range = vert_range,
+ };
- /* we only want to check newly created edges */
- .edge_arr_new = edge_net_new + edge_net_init_len,
- .edge_arr_new_len = 0,
+ for (uint g_index = 1; g_index < group_arr_len; g_index++) {
+ struct EdgeGroupIsland *g = group_arr[g_index];
- .vert_range = vert_range,
- };
+ /* the range of verts this group uses in 'verts_arr' (not uncluding the last index) */
+ vert_range[0] = vert_range[1];
+ vert_range[1] += g->vert_len;
- for (uint g_index = 1; g_index < group_arr_len; g_index++) {
- struct EdgeGroupIsland *g = group_arr[g_index];
+ if (g->has_prev_edge == false) {
+ BMVert *v_origin = g->vert_span.min;
- /* the range of verts this group uses in 'verts_arr' (not uncluding the last index) */
- vert_range[0] = vert_range[1];
- vert_range[1] += g->vert_len;
+ const int index_other = bm_face_split_edgenet_find_connection(&args, v_origin, false);
+ // BLI_assert(index_other >= 0 && index_other < (int)vert_arr_len);
- if (g->has_prev_edge == false) {
- BMVert *v_origin = g->vert_span.min;
-
- const int index_other = bm_face_split_edgenet_find_connection(&args, v_origin, false);
- // BLI_assert(index_other >= 0 && index_other < (int)vert_arr_len);
-
- /* only for degenerate geometry */
- if (index_other != -1) {
+ /* only for degenerate geometry */
+ if (index_other != -1) {
#ifdef USE_PARTIAL_CONNECT
- if ((use_partial_connect == false) ||
- (bm_vert_partial_connect_check_overlap(
- temp_vert_pairs.remap,
- BM_elem_index_get(v_origin), index_other) == false))
+ if ((use_partial_connect == false) ||
+ (bm_vert_partial_connect_check_overlap(
+ temp_vert_pairs.remap, BM_elem_index_get(v_origin), index_other) == false))
#endif
- {
- BMVert *v_end = vert_arr[index_other];
+ {
+ BMVert *v_end = vert_arr[index_other];
- edge_net_new[edge_net_new_index] = BM_edge_create(bm, v_origin, v_end, NULL, 0);
+ edge_net_new[edge_net_new_index] = BM_edge_create(bm, v_origin, v_end, NULL, 0);
#ifdef USE_PARTIAL_CONNECT
- BM_elem_index_set(edge_net_new[edge_net_new_index], edge_net_new_index);
+ BM_elem_index_set(edge_net_new[edge_net_new_index], edge_net_new_index);
#endif
- edge_net_new_index++;
- args.edge_arr_new_len++;
- }
- }
- }
+ edge_net_new_index++;
+ args.edge_arr_new_len++;
+ }
+ }
+ }
- {
- BMVert *v_origin = g->vert_span.max;
+ {
+ BMVert *v_origin = g->vert_span.max;
- const int index_other = bm_face_split_edgenet_find_connection(&args, v_origin, true);
- // BLI_assert(index_other >= 0 && index_other < (int)vert_arr_len);
+ const int index_other = bm_face_split_edgenet_find_connection(&args, v_origin, true);
+ // BLI_assert(index_other >= 0 && index_other < (int)vert_arr_len);
- /* only for degenerate geometry */
- if (index_other != -1) {
+ /* only for degenerate geometry */
+ if (index_other != -1) {
#ifdef USE_PARTIAL_CONNECT
- if ((use_partial_connect == false) ||
- (bm_vert_partial_connect_check_overlap(
- temp_vert_pairs.remap,
- BM_elem_index_get(v_origin), index_other) == false))
+ if ((use_partial_connect == false) ||
+ (bm_vert_partial_connect_check_overlap(
+ temp_vert_pairs.remap, BM_elem_index_get(v_origin), index_other) == false))
#endif
- {
- BMVert *v_end = vert_arr[index_other];
- edge_net_new[edge_net_new_index] = BM_edge_create(bm, v_origin, v_end, NULL, 0);
+ {
+ BMVert *v_end = vert_arr[index_other];
+ edge_net_new[edge_net_new_index] = BM_edge_create(bm, v_origin, v_end, NULL, 0);
#ifdef USE_PARTIAL_CONNECT
- BM_elem_index_set(edge_net_new[edge_net_new_index], edge_net_new_index);
+ BM_elem_index_set(edge_net_new[edge_net_new_index], edge_net_new_index);
#endif
- edge_net_new_index++;
- args.edge_arr_new_len++;
- }
-
- /* tell the 'next' group it doesn't need to create its own back-link */
- uint g_index_other = verts_group_table[index_other];
- group_arr[g_index_other]->has_prev_edge = true;
- }
- }
-
- }
- BLI_assert(edge_net_new_len >= edge_net_new_index);
- edge_net_new_len = edge_net_new_index;
- }
-
- BLI_bvhtree_free(bvhtree);
-
- *r_edge_net_new = edge_net_new;
- *r_edge_net_new_len = edge_net_new_len;
- ok = true;
-
- for (uint i = 0; i < vert_arr_len; i++) {
- copy_v3_v3(vert_arr[i]->co, vert_coords_backup[i]);
- }
+ edge_net_new_index++;
+ args.edge_arr_new_len++;
+ }
+
+ /* tell the 'next' group it doesn't need to create its own back-link */
+ uint g_index_other = verts_group_table[index_other];
+ group_arr[g_index_other]->has_prev_edge = true;
+ }
+ }
+ }
+ BLI_assert(edge_net_new_len >= edge_net_new_index);
+ edge_net_new_len = edge_net_new_index;
+ }
+
+ BLI_bvhtree_free(bvhtree);
+
+ *r_edge_net_new = edge_net_new;
+ *r_edge_net_new_len = edge_net_new_len;
+ ok = true;
+
+ for (uint i = 0; i < vert_arr_len; i++) {
+ copy_v3_v3(vert_arr[i]->co, vert_coords_backup[i]);
+ }
finally:
#ifdef USE_PARTIAL_CONNECT
- /* don't free 'vert_temp_pair_list', its part of the arena */
- if (use_partial_connect) {
-
- /* Sanity check: ensure we don't have connecting edges before splicing begins. */
-#ifdef DEBUG
- {
- struct TempVertPair *tvp = temp_vert_pairs.list;
- do {
- /* we must _never_ create connections here
- * (inface the islands can't have a connection at all) */
- BLI_assert(BM_edge_exists(tvp->v_orig, tvp->v_temp) == NULL);
- } while ((tvp = tvp->next));
- }
-#endif
-
- struct TempVertPair *tvp = temp_vert_pairs.list;
- do {
- /* its _very_ unlikely the edge exists,
- * however splicing may case this. see: T48012 */
- if (!BM_edge_exists(tvp->v_orig, tvp->v_temp)) {
- BM_vert_splice(bm, tvp->v_orig, tvp->v_temp);
- }
- } while ((tvp = tvp->next));
-
- /* Remove edges which have become doubles since splicing vertices together,
- * its less trouble then detecting future-doubles on edge-creation. */
- for (uint i = edge_net_init_len; i < edge_net_new_len; i++) {
- while (BM_edge_find_double(edge_net_new[i])) {
- BM_edge_kill(bm, edge_net_new[i]);
- edge_net_new_len--;
- if (i == edge_net_new_len) {
- break;
- }
- edge_net_new[i] = edge_net_new[edge_net_new_len];
- }
- }
-
- *r_edge_net_new_len = edge_net_new_len;
- }
+ /* don't free 'vert_temp_pair_list', its part of the arena */
+ if (use_partial_connect) {
+
+ /* Sanity check: ensure we don't have connecting edges before splicing begins. */
+# ifdef DEBUG
+ {
+ struct TempVertPair *tvp = temp_vert_pairs.list;
+ do {
+ /* we must _never_ create connections here
+ * (inface the islands can't have a connection at all) */
+ BLI_assert(BM_edge_exists(tvp->v_orig, tvp->v_temp) == NULL);
+ } while ((tvp = tvp->next));
+ }
+# endif
+
+ struct TempVertPair *tvp = temp_vert_pairs.list;
+ do {
+ /* its _very_ unlikely the edge exists,
+ * however splicing may case this. see: T48012 */
+ if (!BM_edge_exists(tvp->v_orig, tvp->v_temp)) {
+ BM_vert_splice(bm, tvp->v_orig, tvp->v_temp);
+ }
+ } while ((tvp = tvp->next));
+
+ /* Remove edges which have become doubles since splicing vertices together,
+ * its less trouble then detecting future-doubles on edge-creation. */
+ for (uint i = edge_net_init_len; i < edge_net_new_len; i++) {
+ while (BM_edge_find_double(edge_net_new[i])) {
+ BM_edge_kill(bm, edge_net_new[i]);
+ edge_net_new_len--;
+ if (i == edge_net_new_len) {
+ break;
+ }
+ edge_net_new[i] = edge_net_new[edge_net_new_len];
+ }
+ }
+
+ *r_edge_net_new_len = edge_net_new_len;
+ }
#endif
-
- for (uint i = 0; i < edge_arr_len; i++) {
- BM_elem_flag_disable(edge_arr[i], EDGE_NOT_IN_STACK);
- BM_elem_flag_disable(edge_arr[i]->v1, VERT_NOT_IN_STACK);
- BM_elem_flag_disable(edge_arr[i]->v2, VERT_NOT_IN_STACK);
- }
+ for (uint i = 0; i < edge_arr_len; i++) {
+ BM_elem_flag_disable(edge_arr[i], EDGE_NOT_IN_STACK);
+ BM_elem_flag_disable(edge_arr[i]->v1, VERT_NOT_IN_STACK);
+ BM_elem_flag_disable(edge_arr[i]->v2, VERT_NOT_IN_STACK);
+ }
#undef VERT_IN_ARRAY
#undef VERT_NOT_IN_STACK
#undef EDGE_NOT_IN_STACK
- return ok;
+ return ok;
}
#undef SORT_AXIS
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.h b/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
index 7e57f648704..38af944d0cd 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
@@ -21,17 +21,21 @@
* \ingroup bmesh
*/
-bool BM_face_split_edgenet(
- BMesh *bm, BMFace *f,
- BMEdge **edge_net, const int edge_net_len,
- BMFace ***r_face_arr, int *r_face_arr_len);
+bool BM_face_split_edgenet(BMesh *bm,
+ BMFace *f,
+ BMEdge **edge_net,
+ const int edge_net_len,
+ BMFace ***r_face_arr,
+ int *r_face_arr_len);
-bool BM_face_split_edgenet_connect_islands(
- BMesh *bm,
- BMFace *f, BMEdge **edge_net_init, const uint edge_net_init_len,
- bool use_partial_connect,
- struct MemArena *arena,
- BMEdge ***r_edge_net_new, uint *r_edge_net_new_len)
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3, 6, 7, 8);
+bool BM_face_split_edgenet_connect_islands(BMesh *bm,
+ BMFace *f,
+ BMEdge **edge_net_init,
+ const uint edge_net_init_len,
+ bool use_partial_connect,
+ struct MemArena *arena,
+ BMEdge ***r_edge_net_new,
+ uint *r_edge_net_new_len) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1, 2, 3, 6, 7, 8);
-#endif /* __BMESH_POLYGON_EDGENET_H__ */
+#endif /* __BMESH_POLYGON_EDGENET_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h
index c0f74c50a3a..b77243f7b26 100644
--- a/source/blender/bmesh/intern/bmesh_private.h
+++ b/source/blender/bmesh/intern/bmesh_private.h
@@ -31,19 +31,23 @@
/* returns positive nonzero on error */
#ifdef NDEBUG
- /* no error checking for release,
+/* no error checking for release,
* it can take most of the CPU time when running some tools */
-# define BM_CHECK_ELEMENT(el) (void)(el)
+# 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), \
- __LINE__, __FILE__); \
- } \
-} ((void)0)
+# 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), \
+ __LINE__, \
+ __FILE__); \
+ } \
+ } \
+ ((void)0)
#endif
int bmesh_radial_length(const BMLoop *l);
@@ -55,20 +59,32 @@ int bmesh_disk_count(const BMVert *v);
* \note Ensure different parts of the API do not conflict
* on using these internal flags!*/
enum {
- _FLAG_JF = (1 << 0), /* join faces */
- _FLAG_MF = (1 << 1), /* make face */
- _FLAG_MV = (1 << 1), /* make face, vertex */
- _FLAG_OVERLAP = (1 << 2), /* general overlap flag */
- _FLAG_WALK = (1 << 3), /* general walk flag (keep clean) */
- _FLAG_WALK_ALT = (1 << 4), /* same as _FLAG_WALK, for when a second tag is needed */
+ _FLAG_JF = (1 << 0), /* join faces */
+ _FLAG_MF = (1 << 1), /* make face */
+ _FLAG_MV = (1 << 1), /* make face, vertex */
+ _FLAG_OVERLAP = (1 << 2), /* general overlap flag */
+ _FLAG_WALK = (1 << 3), /* general walk flag (keep clean) */
+ _FLAG_WALK_ALT = (1 << 4), /* same as _FLAG_WALK, for when a second tag is needed */
- _FLAG_ELEM_CHECK = (1 << 7), /* reserved for bmesh_elem_check */
+ _FLAG_ELEM_CHECK = (1 << 7), /* reserved for bmesh_elem_check */
};
-#define BM_ELEM_API_FLAG_ENABLE(element, f) { ((element)->head.api_flag |= (f)); } (void)0
-#define BM_ELEM_API_FLAG_DISABLE(element, f) { ((element)->head.api_flag &= (uchar)~(f)); } (void)0
-#define BM_ELEM_API_FLAG_TEST(element, f) ((element)->head.api_flag & (f))
-#define BM_ELEM_API_FLAG_CLEAR(element) { ((element)->head.api_flag = 0); } (void)0
+#define BM_ELEM_API_FLAG_ENABLE(element, f) \
+ { \
+ ((element)->head.api_flag |= (f)); \
+ } \
+ (void)0
+#define BM_ELEM_API_FLAG_DISABLE(element, f) \
+ { \
+ ((element)->head.api_flag &= (uchar) ~(f)); \
+ } \
+ (void)0
+#define BM_ELEM_API_FLAG_TEST(element, f) ((element)->head.api_flag & (f))
+#define BM_ELEM_API_FLAG_CLEAR(element) \
+ { \
+ ((element)->head.api_flag = 0); \
+ } \
+ (void)0
void poly_rotate_plane(const float normal[3], float (*verts)[3], unsigned const int nverts);
diff --git a/source/blender/bmesh/intern/bmesh_query.c b/source/blender/bmesh/intern/bmesh_query.c
index 4b34e1fe07d..98ad30b6a28 100644
--- a/source/blender/bmesh/intern/bmesh_query.c
+++ b/source/blender/bmesh/intern/bmesh_query.c
@@ -57,9 +57,9 @@
*/
BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v)
{
- BMLoop *l = BM_face_edge_share_loop(f, e);
- BLI_assert(l != NULL);
- return BM_loop_other_edge_loop(l, v);
+ BMLoop *l = BM_face_edge_share_loop(f, e);
+ BLI_assert(l != NULL);
+ return BM_loop_other_edge_loop(l, v);
}
/**
@@ -68,8 +68,8 @@ BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v)
*/
BMLoop *BM_loop_other_edge_loop(BMLoop *l, BMVert *v)
{
- BLI_assert(BM_vert_in_edge(l->e, v));
- return l->v == v ? l->prev : l->next;
+ BLI_assert(BM_vert_in_edge(l->e, v));
+ return l->v == v ? l->prev : l->next;
}
/**
@@ -96,28 +96,28 @@ BMLoop *BM_loop_other_edge_loop(BMLoop *l, BMVert *v)
*/
BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v)
{
- BMLoop *l_iter = BM_face_vert_share_loop(f, v);
+ BMLoop *l_iter = BM_face_vert_share_loop(f, v);
- BLI_assert(BM_edge_exists(v_prev, v) != NULL);
+ BLI_assert(BM_edge_exists(v_prev, v) != NULL);
- if (l_iter) {
- if (l_iter->prev->v == v_prev) {
- return l_iter->next;
- }
- else if (l_iter->next->v == v_prev) {
- return l_iter->prev;
- }
- else {
- /* invalid args */
- BLI_assert(0);
- return NULL;
- }
- }
- else {
- /* invalid args */
- BLI_assert(0);
- return NULL;
- }
+ if (l_iter) {
+ if (l_iter->prev->v == v_prev) {
+ return l_iter->next;
+ }
+ else if (l_iter->next->v == v_prev) {
+ return l_iter->prev;
+ }
+ else {
+ /* invalid args */
+ BLI_assert(0);
+ return NULL;
+ }
+ }
+ else {
+ /* invalid args */
+ BLI_assert(0);
+ return NULL;
+ }
}
/**
@@ -139,149 +139,144 @@ BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v)
BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v)
{
#if 0 /* works but slow */
- return BM_face_other_vert_loop(l->f, BM_edge_other_vert(l->e, v), v);
+ return BM_face_other_vert_loop(l->f, BM_edge_other_vert(l->e, v), v);
#else
- BMEdge *e = l->e;
- BMVert *v_prev = BM_edge_other_vert(e, v);
- if (l->v == v) {
- if (l->prev->v == v_prev) {
- return l->next;
- }
- else {
- BLI_assert(l->next->v == v_prev);
-
- return l->prev;
- }
- }
- else {
- BLI_assert(l->v == v_prev);
-
- if (l->prev->v == v) {
- return l->prev->prev;
- }
- else {
- BLI_assert(l->next->v == v);
- return l->next->next;
- }
- }
+ BMEdge *e = l->e;
+ BMVert *v_prev = BM_edge_other_vert(e, v);
+ if (l->v == v) {
+ if (l->prev->v == v_prev) {
+ return l->next;
+ }
+ else {
+ BLI_assert(l->next->v == v_prev);
+
+ return l->prev;
+ }
+ }
+ else {
+ BLI_assert(l->v == v_prev);
+
+ if (l->prev->v == v) {
+ return l->prev->prev;
+ }
+ else {
+ BLI_assert(l->next->v == v);
+ return l->next->next;
+ }
+ }
#endif
}
/**
* Check if verts share a face.
*/
-bool BM_vert_pair_share_face_check(
- BMVert *v_a, BMVert *v_b)
+bool BM_vert_pair_share_face_check(BMVert *v_a, BMVert *v_b)
{
- if (v_a->e && v_b->e) {
- BMIter iter;
- BMFace *f;
+ if (v_a->e && v_b->e) {
+ BMIter iter;
+ BMFace *f;
- BM_ITER_ELEM (f, &iter, v_a, BM_FACES_OF_VERT) {
- if (BM_vert_in_face(v_b, f)) {
- return true;
- }
- }
- }
+ BM_ITER_ELEM (f, &iter, v_a, BM_FACES_OF_VERT) {
+ if (BM_vert_in_face(v_b, f)) {
+ return true;
+ }
+ }
+ }
- return false;
+ return false;
}
-bool BM_vert_pair_share_face_check_cb(
- BMVert *v_a, BMVert *v_b,
- bool (*test_fn)(BMFace *, void *user_data), void *user_data)
+bool BM_vert_pair_share_face_check_cb(BMVert *v_a,
+ BMVert *v_b,
+ bool (*test_fn)(BMFace *, void *user_data),
+ void *user_data)
{
- if (v_a->e && v_b->e) {
- BMIter iter;
- BMFace *f;
+ if (v_a->e && v_b->e) {
+ BMIter iter;
+ BMFace *f;
- BM_ITER_ELEM (f, &iter, v_a, BM_FACES_OF_VERT) {
- if (test_fn(f, user_data)) {
- if (BM_vert_in_face(v_b, f)) {
- return true;
- }
- }
- }
- }
+ BM_ITER_ELEM (f, &iter, v_a, BM_FACES_OF_VERT) {
+ if (test_fn(f, user_data)) {
+ if (BM_vert_in_face(v_b, f)) {
+ return true;
+ }
+ }
+ }
+ }
- return false;
+ return false;
}
/**
* Given 2 verts, find the smallest face they share and give back both loops.
*/
BMFace *BM_vert_pair_share_face_by_len(
- BMVert *v_a, BMVert *v_b,
- BMLoop **r_l_a, BMLoop **r_l_b,
- const bool allow_adjacent)
+ BMVert *v_a, BMVert *v_b, BMLoop **r_l_a, BMLoop **r_l_b, const bool allow_adjacent)
{
- BMLoop *l_cur_a = NULL, *l_cur_b = NULL;
- BMFace *f_cur = NULL;
+ BMLoop *l_cur_a = NULL, *l_cur_b = NULL;
+ BMFace *f_cur = NULL;
- if (v_a->e && v_b->e) {
- BMIter iter;
- BMLoop *l_a, *l_b;
+ if (v_a->e && v_b->e) {
+ BMIter iter;
+ BMLoop *l_a, *l_b;
- BM_ITER_ELEM (l_a, &iter, v_a, BM_LOOPS_OF_VERT) {
- if ((f_cur == NULL) || (l_a->f->len < f_cur->len)) {
- l_b = BM_face_vert_share_loop(l_a->f, v_b);
- if (l_b && (allow_adjacent || !BM_loop_is_adjacent(l_a, l_b))) {
- f_cur = l_a->f;
- l_cur_a = l_a;
- l_cur_b = l_b;
- }
- }
- }
- }
+ BM_ITER_ELEM (l_a, &iter, v_a, BM_LOOPS_OF_VERT) {
+ if ((f_cur == NULL) || (l_a->f->len < f_cur->len)) {
+ l_b = BM_face_vert_share_loop(l_a->f, v_b);
+ if (l_b && (allow_adjacent || !BM_loop_is_adjacent(l_a, l_b))) {
+ f_cur = l_a->f;
+ l_cur_a = l_a;
+ l_cur_b = l_b;
+ }
+ }
+ }
+ }
- *r_l_a = l_cur_a;
- *r_l_b = l_cur_b;
+ *r_l_a = l_cur_a;
+ *r_l_b = l_cur_b;
- return f_cur;
+ return f_cur;
}
BMFace *BM_edge_pair_share_face_by_len(
- BMEdge *e_a, BMEdge *e_b,
- BMLoop **r_l_a, BMLoop **r_l_b,
- const bool allow_adjacent)
+ BMEdge *e_a, BMEdge *e_b, BMLoop **r_l_a, BMLoop **r_l_b, const bool allow_adjacent)
{
- BMLoop *l_cur_a = NULL, *l_cur_b = NULL;
- BMFace *f_cur = NULL;
+ BMLoop *l_cur_a = NULL, *l_cur_b = NULL;
+ BMFace *f_cur = NULL;
- if (e_a->l && e_b->l) {
- BMIter iter;
- BMLoop *l_a, *l_b;
+ if (e_a->l && e_b->l) {
+ BMIter iter;
+ BMLoop *l_a, *l_b;
- BM_ITER_ELEM (l_a, &iter, e_a, BM_LOOPS_OF_EDGE) {
- if ((f_cur == NULL) || (l_a->f->len < f_cur->len)) {
- l_b = BM_face_edge_share_loop(l_a->f, e_b);
- if (l_b && (allow_adjacent || !BM_loop_is_adjacent(l_a, l_b))) {
- f_cur = l_a->f;
- l_cur_a = l_a;
- l_cur_b = l_b;
- }
- }
- }
- }
+ BM_ITER_ELEM (l_a, &iter, e_a, BM_LOOPS_OF_EDGE) {
+ if ((f_cur == NULL) || (l_a->f->len < f_cur->len)) {
+ l_b = BM_face_edge_share_loop(l_a->f, e_b);
+ if (l_b && (allow_adjacent || !BM_loop_is_adjacent(l_a, l_b))) {
+ f_cur = l_a->f;
+ l_cur_a = l_a;
+ l_cur_b = l_b;
+ }
+ }
+ }
+ }
- *r_l_a = l_cur_a;
- *r_l_b = l_cur_b;
+ *r_l_a = l_cur_a;
+ *r_l_b = l_cur_b;
- return f_cur;
+ return f_cur;
}
static float bm_face_calc_split_dot(BMLoop *l_a, BMLoop *l_b)
{
- float no[2][3];
+ float no[2][3];
- if ((BM_face_calc_normal_subset(l_a, l_b, no[0]) != 0.0f) &&
- (BM_face_calc_normal_subset(l_b, l_a, no[1]) != 0.0f))
- {
- return dot_v3v3(no[0], no[1]);
- }
- else {
- return -1.0f;
- }
+ if ((BM_face_calc_normal_subset(l_a, l_b, no[0]) != 0.0f) &&
+ (BM_face_calc_normal_subset(l_b, l_a, no[1]) != 0.0f)) {
+ return dot_v3v3(no[0], no[1]);
+ }
+ else {
+ return -1.0f;
+ }
}
/**
@@ -292,8 +287,8 @@ static float bm_face_calc_split_dot(BMLoop *l_a, BMLoop *l_b)
*/
float BM_loop_point_side_of_loop_test(const BMLoop *l, const float co[3])
{
- const float *axis = l->f->no;
- return dist_signed_squared_to_corner_v3v3v3(co, l->prev->v->co, l->v->co, l->next->v->co, axis);
+ const float *axis = l->f->no;
+ return dist_signed_squared_to_corner_v3v3v3(co, l->prev->v->co, l->v->co, l->next->v->co, axis);
}
/**
@@ -304,15 +299,15 @@ float BM_loop_point_side_of_loop_test(const BMLoop *l, const float co[3])
*/
float BM_loop_point_side_of_edge_test(const BMLoop *l, const float co[3])
{
- const float *axis = l->f->no;
- float dir[3];
- float plane[4];
+ const float *axis = l->f->no;
+ float dir[3];
+ float plane[4];
- sub_v3_v3v3(dir, l->next->v->co, l->v->co);
- cross_v3_v3v3(plane, axis, dir);
+ sub_v3_v3v3(dir, l->next->v->co, l->v->co);
+ cross_v3_v3v3(plane, axis, dir);
- plane[3] = -dot_v3v3(plane, l->v->co);
- return dist_signed_squared_to_plane_v3(co, plane);
+ plane[3] = -dot_v3v3(plane, l->v->co);
+ return dist_signed_squared_to_plane_v3(co, plane);
}
/**
@@ -321,68 +316,65 @@ float BM_loop_point_side_of_edge_test(const BMLoop *l, const float co[3])
* This can be better then #BM_vert_pair_share_face_by_len because concave splits are ranked lowest.
*/
BMFace *BM_vert_pair_share_face_by_angle(
- BMVert *v_a, BMVert *v_b,
- BMLoop **r_l_a, BMLoop **r_l_b,
- const bool allow_adjacent)
+ BMVert *v_a, BMVert *v_b, BMLoop **r_l_a, BMLoop **r_l_b, const bool allow_adjacent)
{
- BMLoop *l_cur_a = NULL, *l_cur_b = NULL;
- BMFace *f_cur = NULL;
+ BMLoop *l_cur_a = NULL, *l_cur_b = NULL;
+ BMFace *f_cur = NULL;
- if (v_a->e && v_b->e) {
- BMIter iter;
- BMLoop *l_a, *l_b;
- float dot_best = -1.0f;
+ if (v_a->e && v_b->e) {
+ BMIter iter;
+ BMLoop *l_a, *l_b;
+ float dot_best = -1.0f;
- BM_ITER_ELEM (l_a, &iter, v_a, BM_LOOPS_OF_VERT) {
- l_b = BM_face_vert_share_loop(l_a->f, v_b);
- if (l_b && (allow_adjacent || !BM_loop_is_adjacent(l_a, l_b))) {
+ BM_ITER_ELEM (l_a, &iter, v_a, BM_LOOPS_OF_VERT) {
+ l_b = BM_face_vert_share_loop(l_a->f, v_b);
+ if (l_b && (allow_adjacent || !BM_loop_is_adjacent(l_a, l_b))) {
- if (f_cur == NULL) {
- f_cur = l_a->f;
- l_cur_a = l_a;
- l_cur_b = l_b;
- }
- else {
- /* avoid expensive calculations if we only ever find one face */
- float dot;
- if (dot_best == -1.0f) {
- dot_best = bm_face_calc_split_dot(l_cur_a, l_cur_b);
- }
+ if (f_cur == NULL) {
+ f_cur = l_a->f;
+ l_cur_a = l_a;
+ l_cur_b = l_b;
+ }
+ else {
+ /* avoid expensive calculations if we only ever find one face */
+ float dot;
+ if (dot_best == -1.0f) {
+ dot_best = bm_face_calc_split_dot(l_cur_a, l_cur_b);
+ }
- dot = bm_face_calc_split_dot(l_a, l_b);
- if (dot > dot_best) {
- dot_best = dot;
+ dot = bm_face_calc_split_dot(l_a, l_b);
+ if (dot > dot_best) {
+ dot_best = dot;
- f_cur = l_a->f;
- l_cur_a = l_a;
- l_cur_b = l_b;
- }
- }
- }
- }
- }
+ f_cur = l_a->f;
+ l_cur_a = l_a;
+ l_cur_b = l_b;
+ }
+ }
+ }
+ }
+ }
- *r_l_a = l_cur_a;
- *r_l_b = l_cur_b;
+ *r_l_a = l_cur_a;
+ *r_l_b = l_cur_b;
- return f_cur;
+ return f_cur;
}
-
/**
* Get the first loop of a vert. Uses the same initialization code for the first loop of the
* iterator API
*/
BMLoop *BM_vert_find_first_loop(BMVert *v)
{
- return v->e ? bmesh_disk_faceloop_find_first(v->e, v) : NULL;
+ return v->e ? bmesh_disk_faceloop_find_first(v->e, v) : NULL;
}
/**
* A version of #BM_vert_find_first_loop that ignores hidden loops.
*/
BMLoop *BM_vert_find_first_loop_visible(BMVert *v)
{
- return v->e ? bmesh_disk_faceloop_find_first_visible(v->e, v) : NULL;
+ return v->e ? bmesh_disk_faceloop_find_first_visible(v->e, v) : NULL;
}
/**
@@ -390,26 +382,26 @@ BMLoop *BM_vert_find_first_loop_visible(BMVert *v)
*/
bool BM_vert_in_face(BMVert *v, BMFace *f)
{
- BMLoop *l_iter, *l_first;
+ BMLoop *l_iter, *l_first;
#ifdef USE_BMESH_HOLES
- BMLoopList *lst;
- for (lst = f->loops.first; lst; lst = lst->next)
+ BMLoopList *lst;
+ for (lst = f->loops.first; lst; lst = lst->next)
#endif
- {
+ {
#ifdef USE_BMESH_HOLES
- l_iter = l_first = lst->first;
+ l_iter = l_first = lst->first;
#else
- l_iter = l_first = f->l_first;
+ l_iter = l_first = f->l_first;
#endif
- do {
- if (l_iter->v == v) {
- return true;
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
+ do {
+ if (l_iter->v == v) {
+ return true;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
- return false;
+ return false;
}
/**
@@ -418,96 +410,95 @@ bool BM_vert_in_face(BMVert *v, BMFace *f)
*/
int BM_verts_in_face_count(BMVert **varr, int len, BMFace *f)
{
- BMLoop *l_iter, *l_first;
+ BMLoop *l_iter, *l_first;
#ifdef USE_BMESH_HOLES
- BMLoopList *lst;
+ BMLoopList *lst;
#endif
- int i, count = 0;
+ int i, count = 0;
- for (i = 0; i < len; i++) {
- BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
- }
+ for (i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
+ }
#ifdef USE_BMESH_HOLES
- for (lst = f->loops.first; lst; lst = lst->next)
+ for (lst = f->loops.first; lst; lst = lst->next)
#endif
- {
+ {
#ifdef USE_BMESH_HOLES
- l_iter = l_first = lst->first;
+ l_iter = l_first = lst->first;
#else
- l_iter = l_first = f->l_first;
+ l_iter = l_first = f->l_first;
#endif
- do {
- if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
- count++;
- }
+ do {
+ if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
+ count++;
+ }
- } while ((l_iter = l_iter->next) != l_first);
- }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
- for (i = 0; i < len; i++) {
- BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
- }
+ for (i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
+ }
- return count;
+ return count;
}
-
/**
* Return true if all verts are in the face.
*/
bool BM_verts_in_face(BMVert **varr, int len, BMFace *f)
{
- BMLoop *l_iter, *l_first;
+ BMLoop *l_iter, *l_first;
#ifdef USE_BMESH_HOLES
- BMLoopList *lst;
+ BMLoopList *lst;
#endif
- int i;
- bool ok = true;
+ int i;
+ bool ok = true;
- /* simple check, we know can't succeed */
- if (f->len < len) {
- return false;
- }
+ /* simple check, we know can't succeed */
+ if (f->len < len) {
+ return false;
+ }
- for (i = 0; i < len; i++) {
- BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
- }
+ for (i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_ENABLE(varr[i], _FLAG_OVERLAP);
+ }
#ifdef USE_BMESH_HOLES
- for (lst = f->loops.first; lst; lst = lst->next)
+ for (lst = f->loops.first; lst; lst = lst->next)
#endif
- {
+ {
#ifdef USE_BMESH_HOLES
- l_iter = l_first = lst->first;
+ l_iter = l_first = lst->first;
#else
- l_iter = l_first = f->l_first;
+ l_iter = l_first = f->l_first;
#endif
- do {
- if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
- /* pass */
- }
- else {
- ok = false;
- break;
- }
+ do {
+ if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP)) {
+ /* pass */
+ }
+ else {
+ ok = false;
+ break;
+ }
- } while ((l_iter = l_iter->next) != l_first);
- }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
- for (i = 0; i < len; i++) {
- BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
- }
+ for (i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
+ }
- return ok;
+ return ok;
}
/**
@@ -515,18 +506,18 @@ bool BM_verts_in_face(BMVert **varr, int len, BMFace *f)
*/
bool BM_edge_in_face(const BMEdge *e, const BMFace *f)
{
- if (e->l) {
- const BMLoop *l_iter, *l_first;
+ if (e->l) {
+ const BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- if (l_iter->f == f) {
- return true;
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
+ l_iter = l_first = e->l;
+ do {
+ if (l_iter->f == f) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
- return false;
+ return false;
}
/**
@@ -547,27 +538,27 @@ bool BM_edge_in_face(const BMEdge *e, const BMFace *f)
*/
BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l)
{
- BMLoop *l_other;
+ BMLoop *l_other;
- // BLI_assert(BM_edge_is_manifold(e)); // TOO strict, just check if we have another radial face
- BLI_assert(e->l && e->l->radial_next != e->l);
- BLI_assert(BM_vert_in_edge(e, l->v));
+ // BLI_assert(BM_edge_is_manifold(e)); // TOO strict, just check if we have another radial face
+ BLI_assert(e->l && e->l->radial_next != e->l);
+ BLI_assert(BM_vert_in_edge(e, l->v));
- l_other = (l->e == e) ? l : l->prev;
- l_other = l_other->radial_next;
- BLI_assert(l_other->e == e);
+ l_other = (l->e == e) ? l : l->prev;
+ l_other = l_other->radial_next;
+ BLI_assert(l_other->e == e);
- if (l_other->v == l->v) {
- /* pass */
- }
- else if (l_other->next->v == l->v) {
- l_other = l_other->next;
- }
- else {
- BLI_assert(0);
- }
+ if (l_other->v == l->v) {
+ /* pass */
+ }
+ else if (l_other->next->v == l->v) {
+ l_other = l_other->next;
+ }
+ else {
+ BLI_assert(0);
+ }
- return l_other;
+ return l_other;
}
/**
@@ -597,29 +588,27 @@ BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l)
BMLoop *BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step)
{
- BMEdge *e_prev = *e_step;
- BMEdge *e_next;
- if (l->e == e_prev) {
- e_next = l->prev->e;
- }
- else if (l->prev->e == e_prev) {
- e_next = l->e;
- }
- else {
- BLI_assert(0);
- return NULL;
- }
+ BMEdge *e_prev = *e_step;
+ BMEdge *e_next;
+ if (l->e == e_prev) {
+ e_next = l->prev->e;
+ }
+ else if (l->prev->e == e_prev) {
+ e_next = l->e;
+ }
+ else {
+ BLI_assert(0);
+ return NULL;
+ }
- if (BM_edge_is_manifold(e_next)) {
- return BM_edge_other_loop((*e_step = e_next), l);
- }
- else {
- return NULL;
- }
+ if (BM_edge_is_manifold(e_next)) {
+ return BM_edge_other_loop((*e_step = e_next), l);
+ }
+ else {
+ return NULL;
+ }
}
-
-
/**
* The function takes a vertex at the center of a fan and returns the opposite edge in the fan.
* All edges in the fan must be manifold, otherwise return NULL.
@@ -628,49 +617,48 @@ BMLoop *BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step)
*/
BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e_first)
{
- BMLoop *l_a;
- int tot = 0;
- int i;
+ BMLoop *l_a;
+ int tot = 0;
+ int i;
- BLI_assert(BM_vert_in_edge(e_first, v));
+ BLI_assert(BM_vert_in_edge(e_first, v));
- l_a = e_first->l;
- do {
- l_a = BM_loop_other_vert_loop(l_a, v);
- l_a = BM_vert_in_edge(l_a->e, v) ? l_a : l_a->prev;
- if (BM_edge_is_manifold(l_a->e)) {
- l_a = l_a->radial_next;
- }
- else {
- return NULL;
- }
+ l_a = e_first->l;
+ do {
+ l_a = BM_loop_other_vert_loop(l_a, v);
+ l_a = BM_vert_in_edge(l_a->e, v) ? l_a : l_a->prev;
+ if (BM_edge_is_manifold(l_a->e)) {
+ l_a = l_a->radial_next;
+ }
+ else {
+ return NULL;
+ }
- tot++;
- } while (l_a != e_first->l);
+ tot++;
+ } while (l_a != e_first->l);
- /* we know the total, now loop half way */
- tot /= 2;
- i = 0;
+ /* we know the total, now loop half way */
+ tot /= 2;
+ i = 0;
- l_a = e_first->l;
- do {
- if (i == tot) {
- l_a = BM_vert_in_edge(l_a->e, v) ? l_a : l_a->prev;
- return l_a->e;
- }
+ l_a = e_first->l;
+ do {
+ if (i == tot) {
+ l_a = BM_vert_in_edge(l_a->e, v) ? l_a : l_a->prev;
+ return l_a->e;
+ }
- l_a = BM_loop_other_vert_loop(l_a, v);
- l_a = BM_vert_in_edge(l_a->e, v) ? l_a : l_a->prev;
- if (BM_edge_is_manifold(l_a->e)) {
- l_a = l_a->radial_next;
- }
- /* this wont have changed from the previous loop */
+ l_a = BM_loop_other_vert_loop(l_a, v);
+ l_a = BM_vert_in_edge(l_a->e, v) ? l_a : l_a->prev;
+ if (BM_edge_is_manifold(l_a->e)) {
+ l_a = l_a->radial_next;
+ }
+ /* this wont have changed from the previous loop */
+ i++;
+ } while (l_a != e_first->l);
- i++;
- } while (l_a != e_first->l);
-
- return NULL;
+ return NULL;
}
/**
@@ -678,7 +666,7 @@ BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e_first)
*/
float BM_edge_calc_length(const BMEdge *e)
{
- return len_v3v3(e->v1->co, e->v2->co);
+ return len_v3v3(e->v1->co, e->v2->co);
}
/**
@@ -686,7 +674,7 @@ float BM_edge_calc_length(const BMEdge *e)
*/
float BM_edge_calc_length_squared(const BMEdge *e)
{
- return len_squared_v3v3(e->v1->co, e->v2->co);
+ return len_squared_v3v3(e->v1->co, e->v2->co);
}
/**
@@ -697,22 +685,18 @@ float BM_edge_calc_length_squared(const BMEdge *e)
*/
bool BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb)
{
- BMLoop *la, *lb;
+ BMLoop *la, *lb;
- if ((la = e->l) &&
- (lb = la->radial_next) &&
- (la != lb) &&
- (lb->radial_next == la))
- {
- *r_fa = la->f;
- *r_fb = lb->f;
- return true;
- }
- else {
- *r_fa = NULL;
- *r_fb = NULL;
- return false;
- }
+ if ((la = e->l) && (lb = la->radial_next) && (la != lb) && (lb->radial_next == la)) {
+ *r_fa = la->f;
+ *r_fb = lb->f;
+ return true;
+ }
+ else {
+ *r_fa = NULL;
+ *r_fb = NULL;
+ return false;
+ }
}
/**
@@ -723,22 +707,18 @@ bool BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb)
*/
bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
{
- BMLoop *la, *lb;
+ BMLoop *la, *lb;
- if ((la = e->l) &&
- (lb = la->radial_next) &&
- (la != lb) &&
- (lb->radial_next == la))
- {
- *r_la = la;
- *r_lb = lb;
- return true;
- }
- else {
- *r_la = NULL;
- *r_lb = NULL;
- return false;
- }
+ if ((la = e->l) && (lb = la->radial_next) && (la != lb) && (lb->radial_next == la)) {
+ *r_la = la;
+ *r_lb = lb;
+ return true;
+ }
+ else {
+ *r_la = NULL;
+ *r_lb = NULL;
+ return false;
+ }
}
/**
@@ -746,12 +726,12 @@ bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb)
*/
bool BM_vert_is_edge_pair(const BMVert *v)
{
- const BMEdge *e = v->e;
- if (e) {
- BMEdge *e_other = BM_DISK_EDGE_NEXT(e, v);
- return ((e_other != e) && (BM_DISK_EDGE_NEXT(e_other, v) == e));
- }
- return false;
+ const BMEdge *e = v->e;
+ if (e) {
+ BMEdge *e_other = BM_DISK_EDGE_NEXT(e, v);
+ return ((e_other != e) && (BM_DISK_EDGE_NEXT(e_other, v) == e));
+ }
+ return false;
}
/**
@@ -760,14 +740,14 @@ bool BM_vert_is_edge_pair(const BMVert *v)
*/
bool BM_vert_is_edge_pair_manifold(const BMVert *v)
{
- const BMEdge *e = v->e;
- if (e) {
- BMEdge *e_other = BM_DISK_EDGE_NEXT(e, v);
- if (((e_other != e) && (BM_DISK_EDGE_NEXT(e_other, v) == e))) {
- return BM_edge_is_manifold(e) && BM_edge_is_manifold(e_other);
- }
- }
- return false;
+ const BMEdge *e = v->e;
+ if (e) {
+ BMEdge *e_other = BM_DISK_EDGE_NEXT(e, v);
+ if (((e_other != e) && (BM_DISK_EDGE_NEXT(e_other, v) == e))) {
+ return BM_edge_is_manifold(e) && BM_edge_is_manifold(e_other);
+ }
+ }
+ return false;
}
/**
@@ -777,19 +757,19 @@ bool BM_vert_is_edge_pair_manifold(const BMVert *v)
*/
bool BM_vert_edge_pair(BMVert *v, BMEdge **r_e_a, BMEdge **r_e_b)
{
- BMEdge *e_a = v->e;
- if (e_a) {
- BMEdge *e_b = BM_DISK_EDGE_NEXT(e_a, v);
- if ((e_b != e_a) && (BM_DISK_EDGE_NEXT(e_b, v) == e_a)) {
- *r_e_a = e_a;
- *r_e_b = e_b;
- return true;
- }
- }
+ BMEdge *e_a = v->e;
+ if (e_a) {
+ BMEdge *e_b = BM_DISK_EDGE_NEXT(e_a, v);
+ if ((e_b != e_a) && (BM_DISK_EDGE_NEXT(e_b, v) == e_a)) {
+ *r_e_a = e_a;
+ *r_e_b = e_b;
+ return true;
+ }
+ }
- *r_e_a = NULL;
- *r_e_b = NULL;
- return false;
+ *r_e_a = NULL;
+ *r_e_b = NULL;
+ return false;
}
/**
@@ -797,62 +777,62 @@ bool BM_vert_edge_pair(BMVert *v, BMEdge **r_e_a, BMEdge **r_e_b)
*/
int BM_vert_edge_count(const BMVert *v)
{
- return bmesh_disk_count(v);
+ return bmesh_disk_count(v);
}
int BM_vert_edge_count_at_most(const BMVert *v, const int count_max)
{
- return bmesh_disk_count_at_most(v, count_max);
+ return bmesh_disk_count_at_most(v, count_max);
}
int BM_vert_edge_count_nonwire(const BMVert *v)
{
- int count = 0;
- BMIter eiter;
- BMEdge *edge;
- BM_ITER_ELEM (edge, &eiter, (BMVert *)v, BM_EDGES_OF_VERT) {
- if (edge->l) {
- count++;
- }
- }
- return count;
+ int count = 0;
+ BMIter eiter;
+ BMEdge *edge;
+ BM_ITER_ELEM (edge, &eiter, (BMVert *)v, BM_EDGES_OF_VERT) {
+ if (edge->l) {
+ count++;
+ }
+ }
+ return count;
}
/**
* Returns the number of faces around this edge
*/
int BM_edge_face_count(const BMEdge *e)
{
- int count = 0;
+ int count = 0;
- if (e->l) {
- BMLoop *l_iter, *l_first;
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- count++;
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
+ l_iter = l_first = e->l;
+ do {
+ count++;
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
- return count;
+ return count;
}
int BM_edge_face_count_at_most(const BMEdge *e, const int count_max)
{
- int count = 0;
+ int count = 0;
- if (e->l) {
- BMLoop *l_iter, *l_first;
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- count++;
- if (count == count_max) {
- break;
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
+ l_iter = l_first = e->l;
+ do {
+ count++;
+ if (count == count_max) {
+ break;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
- return count;
+ return count;
}
/**
@@ -861,12 +841,12 @@ int BM_edge_face_count_at_most(const BMEdge *e, const int count_max)
*/
int BM_vert_face_count(const BMVert *v)
{
- return bmesh_disk_facevert_count(v);
+ return bmesh_disk_facevert_count(v);
}
int BM_vert_face_count_at_most(const BMVert *v, int count_max)
{
- return bmesh_disk_facevert_count_at_most(v, count_max);
+ return bmesh_disk_facevert_count_at_most(v, count_max);
}
/**
@@ -876,16 +856,16 @@ int BM_vert_face_count_at_most(const BMVert *v, int count_max)
*/
bool BM_vert_face_check(const BMVert *v)
{
- if (v->e != NULL) {
- const BMEdge *e_iter, *e_first;
- e_first = e_iter = v->e;
- do {
- if (e_iter->l != NULL) {
- return true;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- }
- return false;
+ if (v->e != NULL) {
+ const BMEdge *e_iter, *e_first;
+ e_first = e_iter = v->e;
+ do {
+ if (e_iter->l != NULL) {
+ return true;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return false;
}
/**
@@ -894,21 +874,21 @@ bool BM_vert_face_check(const BMVert *v)
*/
bool BM_vert_is_wire(const BMVert *v)
{
- if (v->e) {
- BMEdge *e_first, *e_iter;
+ if (v->e) {
+ BMEdge *e_first, *e_iter;
- 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);
+ 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;
- }
+ return true;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -920,61 +900,61 @@ bool BM_vert_is_wire(const BMVert *v)
*/
bool BM_vert_is_manifold(const BMVert *v)
{
- BMEdge *e_iter, *e_first, *e_prev;
- BMLoop *l_iter, *l_first;
- int loop_num = 0, loop_num_region = 0, boundary_num = 0;
-
- if (v->e == NULL) {
- /* loose vert */
- return false;
- }
-
- /* count edges while looking for non-manifold edges */
- e_first = e_iter = v->e;
- /* may be null */
- l_first = e_iter->l;
- do {
- /* loose edge or edge shared by more than two faces,
- * edges with 1 face user are OK, otherwise we could
- * use BM_edge_is_manifold() here */
- if (e_iter->l == NULL || (e_iter->l != e_iter->l->radial_next->radial_next)) {
- return false;
- }
-
- /* count radial loops */
- if (e_iter->l->v == v) {
- loop_num += 1;
- }
-
- if (!BM_edge_is_boundary(e_iter)) {
- /* non boundary check opposite loop */
- if (e_iter->l->radial_next->v == v) {
- loop_num += 1;
- }
- }
- else {
- /* start at the boundary */
- l_first = e_iter->l;
- boundary_num += 1;
- /* >2 boundaries cant be manifold */
- if (boundary_num == 3) {
- return false;
- }
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
-
- e_first = l_first->e;
- l_first = (l_first->v == v) ? l_first : l_first->next;
- BLI_assert(l_first->v == v);
-
- l_iter = l_first;
- e_prev = e_first;
-
- do {
- loop_num_region += 1;
- } while (((l_iter = BM_vert_step_fan_loop(l_iter, &e_prev)) != l_first) && (l_iter != NULL));
-
- return (loop_num == loop_num_region);
+ BMEdge *e_iter, *e_first, *e_prev;
+ BMLoop *l_iter, *l_first;
+ int loop_num = 0, loop_num_region = 0, boundary_num = 0;
+
+ if (v->e == NULL) {
+ /* loose vert */
+ return false;
+ }
+
+ /* count edges while looking for non-manifold edges */
+ e_first = e_iter = v->e;
+ /* may be null */
+ l_first = e_iter->l;
+ do {
+ /* loose edge or edge shared by more than two faces,
+ * edges with 1 face user are OK, otherwise we could
+ * use BM_edge_is_manifold() here */
+ if (e_iter->l == NULL || (e_iter->l != e_iter->l->radial_next->radial_next)) {
+ return false;
+ }
+
+ /* count radial loops */
+ if (e_iter->l->v == v) {
+ loop_num += 1;
+ }
+
+ if (!BM_edge_is_boundary(e_iter)) {
+ /* non boundary check opposite loop */
+ if (e_iter->l->radial_next->v == v) {
+ loop_num += 1;
+ }
+ }
+ else {
+ /* start at the boundary */
+ l_first = e_iter->l;
+ boundary_num += 1;
+ /* >2 boundaries cant be manifold */
+ if (boundary_num == 3) {
+ return false;
+ }
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+
+ e_first = l_first->e;
+ l_first = (l_first->v == v) ? l_first : l_first->next;
+ BLI_assert(l_first->v == v);
+
+ l_iter = l_first;
+ e_prev = e_first;
+
+ do {
+ loop_num_region += 1;
+ } while (((l_iter = BM_vert_step_fan_loop(l_iter, &e_prev)) != l_first) && (l_iter != NULL));
+
+ return (loop_num == loop_num_region);
}
#define LOOP_VISIT _FLAG_WALK
@@ -982,64 +962,64 @@ bool BM_vert_is_manifold(const BMVert *v)
static int bm_loop_region_count__recursive(BMEdge *e, BMVert *v)
{
- BMLoop *l_iter, *l_first;
- int count = 0;
-
- BLI_assert(!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT));
- BM_ELEM_API_FLAG_ENABLE(e, EDGE_VISIT);
-
- l_iter = l_first = e->l;
- do {
- if (l_iter->v == v) {
- BMEdge *e_other = l_iter->prev->e;
- if (!BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
- BM_ELEM_API_FLAG_ENABLE(l_iter, LOOP_VISIT);
- count += 1;
- }
- if (!BM_ELEM_API_FLAG_TEST(e_other, EDGE_VISIT)) {
- count += bm_loop_region_count__recursive(e_other, v);
- }
- }
- else if (l_iter->next->v == v) {
- BMEdge *e_other = l_iter->next->e;
- if (!BM_ELEM_API_FLAG_TEST(l_iter->next, LOOP_VISIT)) {
- BM_ELEM_API_FLAG_ENABLE(l_iter->next, LOOP_VISIT);
- count += 1;
- }
- if (!BM_ELEM_API_FLAG_TEST(e_other, EDGE_VISIT)) {
- count += bm_loop_region_count__recursive(e_other, v);
- }
- }
- else {
- BLI_assert(0);
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
-
- return count;
+ BMLoop *l_iter, *l_first;
+ int count = 0;
+
+ BLI_assert(!BM_ELEM_API_FLAG_TEST(e, EDGE_VISIT));
+ BM_ELEM_API_FLAG_ENABLE(e, EDGE_VISIT);
+
+ l_iter = l_first = e->l;
+ do {
+ if (l_iter->v == v) {
+ BMEdge *e_other = l_iter->prev->e;
+ if (!BM_ELEM_API_FLAG_TEST(l_iter, LOOP_VISIT)) {
+ BM_ELEM_API_FLAG_ENABLE(l_iter, LOOP_VISIT);
+ count += 1;
+ }
+ if (!BM_ELEM_API_FLAG_TEST(e_other, EDGE_VISIT)) {
+ count += bm_loop_region_count__recursive(e_other, v);
+ }
+ }
+ else if (l_iter->next->v == v) {
+ BMEdge *e_other = l_iter->next->e;
+ if (!BM_ELEM_API_FLAG_TEST(l_iter->next, LOOP_VISIT)) {
+ BM_ELEM_API_FLAG_ENABLE(l_iter->next, LOOP_VISIT);
+ count += 1;
+ }
+ if (!BM_ELEM_API_FLAG_TEST(e_other, EDGE_VISIT)) {
+ count += bm_loop_region_count__recursive(e_other, v);
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+
+ return count;
}
static int bm_loop_region_count__clear(BMLoop *l)
{
- int count = 0;
- BMEdge *e_iter, *e_first;
+ int count = 0;
+ BMEdge *e_iter, *e_first;
- /* clear flags */
- e_iter = e_first = l->e;
- do {
- BM_ELEM_API_FLAG_DISABLE(e_iter, EDGE_VISIT);
- if (e_iter->l) {
- BMLoop *l_iter, *l_first;
- l_iter = l_first = e_iter->l;
- do {
- if (l_iter->v == l->v) {
- BM_ELEM_API_FLAG_DISABLE(l_iter, LOOP_VISIT);
- count += 1;
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
- } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, l->v)) != e_first);
+ /* clear flags */
+ e_iter = e_first = l->e;
+ do {
+ BM_ELEM_API_FLAG_DISABLE(e_iter, EDGE_VISIT);
+ if (e_iter->l) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e_iter->l;
+ do {
+ if (l_iter->v == l->v) {
+ BM_ELEM_API_FLAG_DISABLE(l_iter, LOOP_VISIT);
+ count += 1;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, l->v)) != e_first);
- return count;
+ return count;
}
/**
@@ -1047,12 +1027,12 @@ static int bm_loop_region_count__clear(BMLoop *l)
*/
int BM_loop_region_loops_count_at_most(BMLoop *l, int *r_loop_total)
{
- const int count = bm_loop_region_count__recursive(l->e, l->v);
- const int count_total = bm_loop_region_count__clear(l);
- if (r_loop_total) {
- *r_loop_total = count_total;
- }
- return count;
+ const int count = bm_loop_region_count__recursive(l->e, l->v);
+ const int count_total = bm_loop_region_count__clear(l);
+ if (r_loop_total) {
+ *r_loop_total = count_total;
+ }
+ return count;
}
#undef LOOP_VISIT
@@ -1060,7 +1040,7 @@ int BM_loop_region_loops_count_at_most(BMLoop *l, int *r_loop_total)
int BM_loop_region_loops_count(BMLoop *l)
{
- return BM_loop_region_loops_count_at_most(l, NULL);
+ return BM_loop_region_loops_count_at_most(l, NULL);
}
/**
@@ -1069,13 +1049,13 @@ int BM_loop_region_loops_count(BMLoop *l)
*/
bool BM_vert_is_manifold_region(const BMVert *v)
{
- BMLoop *l_first = BM_vert_find_first_loop((BMVert *)v);
- if (l_first) {
- int count, count_total;
- count = BM_loop_region_loops_count_at_most(l_first, &count_total);
- return (count == count_total);
- }
- return true;
+ BMLoop *l_first = BM_vert_find_first_loop((BMVert *)v);
+ if (l_first) {
+ int count, count_total;
+ count = BM_loop_region_loops_count_at_most(l_first, &count_total);
+ return (count == count_total);
+ }
+ return true;
}
/**
@@ -1084,85 +1064,82 @@ bool BM_vert_is_manifold_region(const BMVert *v)
*/
bool BM_edge_is_convex(const BMEdge *e)
{
- if (BM_edge_is_manifold(e)) {
- BMLoop *l1 = e->l;
- BMLoop *l2 = e->l->radial_next;
- if (!equals_v3v3(l1->f->no, l2->f->no)) {
- float cross[3];
- float l_dir[3];
- cross_v3_v3v3(cross, l1->f->no, l2->f->no);
- /* we assume contiguous normals, otherwise the result isn't meaningful */
- sub_v3_v3v3(l_dir, l1->next->v->co, l1->v->co);
- return (dot_v3v3(l_dir, cross) > 0.0f);
- }
- }
- return true;
+ if (BM_edge_is_manifold(e)) {
+ BMLoop *l1 = e->l;
+ BMLoop *l2 = e->l->radial_next;
+ if (!equals_v3v3(l1->f->no, l2->f->no)) {
+ float cross[3];
+ float l_dir[3];
+ cross_v3_v3v3(cross, l1->f->no, l2->f->no);
+ /* we assume contiguous normals, otherwise the result isn't meaningful */
+ sub_v3_v3v3(l_dir, l1->next->v->co, l1->v->co);
+ return (dot_v3v3(l_dir, cross) > 0.0f);
+ }
+ }
+ return true;
}
/**
* \return true when loop customdata is contiguous.
*/
-bool BM_edge_is_contiguous_loop_cd(
- const BMEdge *e,
- const int cd_loop_type, const int cd_loop_offset)
-{
- BLI_assert(cd_loop_offset != -1);
-
- if (e->l && e->l->radial_next != e->l) {
- const BMLoop *l_base_v1 = e->l;
- const BMLoop *l_base_v2 = e->l->next;
- const void *l_base_cd_v1 = BM_ELEM_CD_GET_VOID_P(l_base_v1, cd_loop_offset);
- const void *l_base_cd_v2 = BM_ELEM_CD_GET_VOID_P(l_base_v2, cd_loop_offset);
- const BMLoop *l_iter = e->l->radial_next;
- do {
- const BMLoop *l_iter_v1;
- const BMLoop *l_iter_v2;
- const void *l_iter_cd_v1;
- const void *l_iter_cd_v2;
-
- if (l_iter->v == l_base_v1->v) {
- l_iter_v1 = l_iter;
- l_iter_v2 = l_iter->next;
- }
- else {
- l_iter_v1 = l_iter->next;
- l_iter_v2 = l_iter;
- }
- BLI_assert((l_iter_v1->v == l_base_v1->v) &&
- (l_iter_v2->v == l_base_v2->v));
-
- l_iter_cd_v1 = BM_ELEM_CD_GET_VOID_P(l_iter_v1, cd_loop_offset);
- l_iter_cd_v2 = BM_ELEM_CD_GET_VOID_P(l_iter_v2, cd_loop_offset);
-
-
- if ((CustomData_data_equals(cd_loop_type, l_base_cd_v1, l_iter_cd_v1) == 0) ||
- (CustomData_data_equals(cd_loop_type, l_base_cd_v2, l_iter_cd_v2) == 0))
- {
- return false;
- }
-
- } while ((l_iter = l_iter->radial_next) != e->l);
- }
- return true;
+bool BM_edge_is_contiguous_loop_cd(const BMEdge *e,
+ const int cd_loop_type,
+ const int cd_loop_offset)
+{
+ BLI_assert(cd_loop_offset != -1);
+
+ if (e->l && e->l->radial_next != e->l) {
+ const BMLoop *l_base_v1 = e->l;
+ const BMLoop *l_base_v2 = e->l->next;
+ const void *l_base_cd_v1 = BM_ELEM_CD_GET_VOID_P(l_base_v1, cd_loop_offset);
+ const void *l_base_cd_v2 = BM_ELEM_CD_GET_VOID_P(l_base_v2, cd_loop_offset);
+ const BMLoop *l_iter = e->l->radial_next;
+ do {
+ const BMLoop *l_iter_v1;
+ const BMLoop *l_iter_v2;
+ const void *l_iter_cd_v1;
+ const void *l_iter_cd_v2;
+
+ if (l_iter->v == l_base_v1->v) {
+ l_iter_v1 = l_iter;
+ l_iter_v2 = l_iter->next;
+ }
+ else {
+ l_iter_v1 = l_iter->next;
+ l_iter_v2 = l_iter;
+ }
+ BLI_assert((l_iter_v1->v == l_base_v1->v) && (l_iter_v2->v == l_base_v2->v));
+
+ l_iter_cd_v1 = BM_ELEM_CD_GET_VOID_P(l_iter_v1, cd_loop_offset);
+ l_iter_cd_v2 = BM_ELEM_CD_GET_VOID_P(l_iter_v2, cd_loop_offset);
+
+ if ((CustomData_data_equals(cd_loop_type, l_base_cd_v1, l_iter_cd_v1) == 0) ||
+ (CustomData_data_equals(cd_loop_type, l_base_cd_v2, l_iter_cd_v2) == 0)) {
+ return false;
+ }
+
+ } while ((l_iter = l_iter->radial_next) != e->l);
+ }
+ return true;
}
bool BM_vert_is_boundary(const BMVert *v)
{
- if (v->e) {
- BMEdge *e_first, *e_iter;
+ if (v->e) {
+ BMEdge *e_first, *e_iter;
- e_first = e_iter = v->e;
- do {
- if (BM_edge_is_boundary(e_iter)) {
- return true;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ e_first = e_iter = v->e;
+ do {
+ if (BM_edge_is_boundary(e_iter)) {
+ return true;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- return false;
- }
- else {
- return false;
- }
+ return false;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -1172,20 +1149,20 @@ bool BM_vert_is_boundary(const BMVert *v)
*/
int BM_face_share_face_count(BMFace *f1, BMFace *f2)
{
- BMIter iter1, iter2;
- BMEdge *e;
- BMFace *f;
- int count = 0;
+ BMIter iter1, iter2;
+ BMEdge *e;
+ BMFace *f;
+ int count = 0;
- BM_ITER_ELEM (e, &iter1, f1, BM_EDGES_OF_FACE) {
- BM_ITER_ELEM (f, &iter2, e, BM_FACES_OF_EDGE) {
- if (f != f1 && f != f2 && BM_face_share_edge_check(f, f2)) {
- count++;
- }
- }
- }
+ BM_ITER_ELEM (e, &iter1, f1, BM_EDGES_OF_FACE) {
+ BM_ITER_ELEM (f, &iter2, e, BM_FACES_OF_EDGE) {
+ if (f != f1 && f != f2 && BM_face_share_edge_check(f, f2)) {
+ count++;
+ }
+ }
+ }
- return count;
+ return count;
}
/**
@@ -1193,19 +1170,19 @@ int BM_face_share_face_count(BMFace *f1, BMFace *f2)
*/
bool BM_face_share_face_check(BMFace *f1, BMFace *f2)
{
- BMIter iter1, iter2;
- BMEdge *e;
- BMFace *f;
+ BMIter iter1, iter2;
+ BMEdge *e;
+ BMFace *f;
- BM_ITER_ELEM (e, &iter1, f1, BM_EDGES_OF_FACE) {
- BM_ITER_ELEM (f, &iter2, e, BM_FACES_OF_EDGE) {
- if (f != f1 && f != f2 && BM_face_share_edge_check(f, f2)) {
- return true;
- }
- }
- }
+ BM_ITER_ELEM (e, &iter1, f1, BM_EDGES_OF_FACE) {
+ BM_ITER_ELEM (f, &iter2, e, BM_FACES_OF_EDGE) {
+ if (f != f1 && f != f2 && BM_face_share_edge_check(f, f2)) {
+ return true;
+ }
+ }
+ }
- return false;
+ return false;
}
/**
@@ -1213,18 +1190,18 @@ bool BM_face_share_face_check(BMFace *f1, BMFace *f2)
*/
int BM_face_share_edge_count(BMFace *f_a, BMFace *f_b)
{
- BMLoop *l_iter;
- BMLoop *l_first;
- int count = 0;
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ int count = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
- do {
- if (BM_edge_in_face(l_iter->e, f_b)) {
- count++;
- }
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
+ do {
+ if (BM_edge_in_face(l_iter->e, f_b)) {
+ count++;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
- return count;
+ return count;
}
/**
@@ -1232,17 +1209,17 @@ int BM_face_share_edge_count(BMFace *f_a, BMFace *f_b)
*/
bool BM_face_share_edge_check(BMFace *f1, BMFace *f2)
{
- BMLoop *l_iter;
- BMLoop *l_first;
+ BMLoop *l_iter;
+ BMLoop *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f1);
- do {
- if (BM_edge_in_face(l_iter->e, f2)) {
- return true;
- }
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f1);
+ do {
+ if (BM_edge_in_face(l_iter->e, f2)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
- return false;
+ return false;
}
/**
@@ -1250,18 +1227,18 @@ bool BM_face_share_edge_check(BMFace *f1, BMFace *f2)
*/
int BM_face_share_vert_count(BMFace *f_a, BMFace *f_b)
{
- BMLoop *l_iter;
- BMLoop *l_first;
- int count = 0;
+ BMLoop *l_iter;
+ BMLoop *l_first;
+ int count = 0;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
- do {
- if (BM_vert_in_face(l_iter->v, f_b)) {
- count++;
- }
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
+ do {
+ if (BM_vert_in_face(l_iter->v, f_b)) {
+ count++;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
- return count;
+ return count;
}
/**
@@ -1269,17 +1246,17 @@ int BM_face_share_vert_count(BMFace *f_a, BMFace *f_b)
*/
bool BM_face_share_vert_check(BMFace *f_a, BMFace *f_b)
{
- BMLoop *l_iter;
- BMLoop *l_first;
+ BMLoop *l_iter;
+ BMLoop *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
- do {
- if (BM_vert_in_face(l_iter->v, f_b)) {
- return true;
- }
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f_a);
+ do {
+ if (BM_vert_in_face(l_iter->v, f_b)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
- return false;
+ return false;
}
/**
@@ -1287,9 +1264,8 @@ bool BM_face_share_vert_check(BMFace *f_a, BMFace *f_b)
*/
bool BM_loop_share_edge_check(BMLoop *l_a, BMLoop *l_b)
{
- BLI_assert(l_a->v == l_b->v);
- return (ELEM(l_a->e, l_b->e, l_b->prev->e) ||
- ELEM(l_b->e, l_a->e, l_a->prev->e));
+ BLI_assert(l_a->v == l_b->v);
+ return (ELEM(l_a->e, l_b->e, l_b->prev->e) || ELEM(l_b->e, l_a->e, l_a->prev->e));
}
/**
@@ -1297,20 +1273,20 @@ bool BM_loop_share_edge_check(BMLoop *l_a, BMLoop *l_b)
*/
bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2)
{
- BMLoop *l;
- BMFace *f;
+ BMLoop *l;
+ BMFace *f;
- if (e1->l && e2->l) {
- l = e1->l;
- do {
- f = l->f;
- if (BM_edge_in_face(e2, f)) {
- return true;
- }
- l = l->radial_next;
- } while (l != e1->l);
- }
- return false;
+ if (e1->l && e2->l) {
+ l = e1->l;
+ do {
+ f = l->f;
+ if (BM_edge_in_face(e2, f)) {
+ return true;
+ }
+ l = l->radial_next;
+ } while (l != e1->l);
+ }
+ return false;
}
/**
@@ -1318,22 +1294,22 @@ bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2)
*/
bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
{
- BMLoop *l;
- BMFace *f;
+ BMLoop *l;
+ BMFace *f;
- if (e1->l && e2->l) {
- l = e1->l;
- do {
- f = l->f;
- if (f->len == 4) {
- if (BM_edge_in_face(e2, f)) {
- return true;
- }
- }
- l = l->radial_next;
- } while (l != e1->l);
- }
- return false;
+ if (e1->l && e2->l) {
+ l = e1->l;
+ do {
+ f = l->f;
+ if (f->len == 4) {
+ if (BM_edge_in_face(e2, f)) {
+ return true;
+ }
+ }
+ l = l->radial_next;
+ } while (l != e1->l);
+ }
+ return false;
}
/**
@@ -1341,10 +1317,7 @@ bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2)
*/
bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
{
- return (e1->v1 == e2->v1 ||
- e1->v1 == e2->v2 ||
- e1->v2 == e2->v1 ||
- e1->v2 == e2->v2);
+ return (e1->v1 == e2->v1 || e1->v1 == e2->v2 || e1->v2 == e2->v1 || e1->v2 == e2->v2);
}
/**
@@ -1352,16 +1325,16 @@ bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2)
*/
BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2)
{
- BLI_assert(e1 != e2);
- if (BM_vert_in_edge(e2, e1->v1)) {
- return e1->v1;
- }
- else if (BM_vert_in_edge(e2, e1->v2)) {
- return e1->v2;
- }
- else {
- return NULL;
- }
+ BLI_assert(e1 != e2);
+ if (BM_vert_in_edge(e2, e1->v1)) {
+ return e1->v1;
+ }
+ else if (BM_vert_in_edge(e2, e1->v2)) {
+ return e1->v2;
+ }
+ else {
+ return NULL;
+ }
}
/**
@@ -1374,13 +1347,13 @@ BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2)
*/
BMLoop *BM_edge_vert_share_loop(BMLoop *l, BMVert *v)
{
- BLI_assert(BM_vert_in_edge(l->e, v));
- if (l->v == v) {
- return l;
- }
- else {
- return l->next;
- }
+ BLI_assert(BM_vert_in_edge(l->e, v));
+ if (l->v == v) {
+ return l;
+ }
+ else {
+ return l->next;
+ }
}
/**
@@ -1393,17 +1366,17 @@ BMLoop *BM_edge_vert_share_loop(BMLoop *l, BMVert *v)
*/
BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v)
{
- BMLoop *l_first;
- BMLoop *l_iter;
+ BMLoop *l_first;
+ BMLoop *l_iter;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (l_iter->v == v) {
- return l_iter;
- }
- } while ((l_iter = l_iter->next) != l_first);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (l_iter->v == v) {
+ return l_iter;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
- return NULL;
+ return NULL;
}
/**
@@ -1416,17 +1389,17 @@ BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v)
*/
BMLoop *BM_face_edge_share_loop(BMFace *f, BMEdge *e)
{
- BMLoop *l_first;
- BMLoop *l_iter;
+ BMLoop *l_first;
+ BMLoop *l_iter;
- l_iter = l_first = e->l;
- do {
- if (l_iter->f == f) {
- return l_iter;
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
+ l_iter = l_first = e->l;
+ do {
+ if (l_iter->f == f) {
+ return l_iter;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
- return NULL;
+ return NULL;
}
/**
@@ -1440,19 +1413,20 @@ BMLoop *BM_face_edge_share_loop(BMFace *f, BMEdge *e)
* \note This is in fact quite a simple check, mainly include this function so the intent is more obvious.
* We know these 2 verts will _always_ make up the loops edge
*/
-void BM_edge_ordered_verts_ex(
- const BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
- const BMLoop *edge_loop)
+void BM_edge_ordered_verts_ex(const BMEdge *edge,
+ BMVert **r_v1,
+ BMVert **r_v2,
+ const BMLoop *edge_loop)
{
- BLI_assert(edge_loop->e == edge);
- (void)edge; /* quiet warning in release build */
- *r_v1 = edge_loop->v;
- *r_v2 = edge_loop->next->v;
+ BLI_assert(edge_loop->e == edge);
+ (void)edge; /* quiet warning in release build */
+ *r_v1 = edge_loop->v;
+ *r_v2 = edge_loop->next->v;
}
void BM_edge_ordered_verts(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2)
{
- BM_edge_ordered_verts_ex(edge, r_v1, r_v2, edge->l);
+ BM_edge_ordered_verts_ex(edge, r_v1, r_v2, edge->l);
}
/**
@@ -1460,19 +1434,19 @@ void BM_edge_ordered_verts(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2)
*/
BMLoop *BM_loop_find_prev_nodouble(BMLoop *l, BMLoop *l_stop, const float eps_sq)
{
- BMLoop *l_step = l->prev;
+ BMLoop *l_step = l->prev;
- BLI_assert(!ELEM(l_stop, NULL, l));
+ BLI_assert(!ELEM(l_stop, NULL, l));
- while (UNLIKELY(len_squared_v3v3(l->v->co, l_step->v->co) < eps_sq)) {
- l_step = l_step->prev;
- BLI_assert(l_step != l);
- if (UNLIKELY(l_step == l_stop)) {
- return NULL;
- }
- }
+ while (UNLIKELY(len_squared_v3v3(l->v->co, l_step->v->co) < eps_sq)) {
+ l_step = l_step->prev;
+ BLI_assert(l_step != l);
+ if (UNLIKELY(l_step == l_stop)) {
+ return NULL;
+ }
+ }
- return l_step;
+ return l_step;
}
/**
@@ -1480,19 +1454,19 @@ BMLoop *BM_loop_find_prev_nodouble(BMLoop *l, BMLoop *l_stop, const float eps_sq
*/
BMLoop *BM_loop_find_next_nodouble(BMLoop *l, BMLoop *l_stop, const float eps_sq)
{
- BMLoop *l_step = l->next;
+ BMLoop *l_step = l->next;
- BLI_assert(!ELEM(l_stop, NULL, l));
+ BLI_assert(!ELEM(l_stop, NULL, l));
- while (UNLIKELY(len_squared_v3v3(l->v->co, l_step->v->co) < eps_sq)) {
- l_step = l_step->next;
- BLI_assert(l_step != l);
- if (UNLIKELY(l_step == l_stop)) {
- return NULL;
- }
- }
+ while (UNLIKELY(len_squared_v3v3(l->v->co, l_step->v->co) < eps_sq)) {
+ l_step = l_step->next;
+ BLI_assert(l_step != l);
+ if (UNLIKELY(l_step == l_stop)) {
+ return NULL;
+ }
+ }
- return l_step;
+ return l_step;
}
/**
@@ -1501,14 +1475,14 @@ BMLoop *BM_loop_find_next_nodouble(BMLoop *l, BMLoop *l_stop, const float eps_sq
*/
bool BM_loop_is_convex(const BMLoop *l)
{
- float e_dir_prev[3];
- float e_dir_next[3];
- float l_no[3];
+ float e_dir_prev[3];
+ float e_dir_next[3];
+ float l_no[3];
- sub_v3_v3v3(e_dir_prev, l->prev->v->co, l->v->co);
- sub_v3_v3v3(e_dir_next, l->next->v->co, l->v->co);
- cross_v3_v3v3(l_no, e_dir_next, e_dir_prev);
- return dot_v3v3(l_no, l->f->no) > 0.0f;
+ sub_v3_v3v3(e_dir_prev, l->prev->v->co, l->v->co);
+ sub_v3_v3v3(e_dir_next, l->next->v->co, l->v->co);
+ cross_v3_v3v3(l_no, e_dir_next, e_dir_prev);
+ return dot_v3v3(l_no, l->f->no) > 0.0f;
}
/**
@@ -1519,9 +1493,7 @@ bool BM_loop_is_convex(const BMLoop *l)
*/
float BM_loop_calc_face_angle(const BMLoop *l)
{
- return angle_v3v3v3(l->prev->v->co,
- l->v->co,
- l->next->v->co);
+ return angle_v3v3v3(l->prev->v->co, l->v->co, l->next->v->co);
}
/**
@@ -1535,30 +1507,30 @@ float BM_loop_calc_face_angle(const BMLoop *l)
*/
float BM_loop_calc_face_normal_safe_ex(const BMLoop *l, const float epsilon_sq, float r_normal[3])
{
- /* Note: we cannot use result of normal_tri_v3 here to detect colinear vectors (vertex on a straight line)
- * from zero value, because it does not normalize both vectors before making crossproduct.
- * Instead of adding two costly normalize computations, just check ourselves for colinear case. */
- /* Note: FEPSILON might need some finer tweaking at some point? Seems to be working OK for now though. */
- float v1[3], v2[3], v_tmp[3];
- sub_v3_v3v3(v1, l->prev->v->co, l->v->co);
- sub_v3_v3v3(v2, l->next->v->co, l->v->co);
-
- const float fac =
- ((v2[0] == 0.0f) ?
- ((v2[1] == 0.0f) ?
- ((v2[2] == 0.0f) ? 0.0f : v1[2] / v2[2]) : v1[1] / v2[1]) : v1[0] / v2[0]);
-
- mul_v3_v3fl(v_tmp, v2, fac);
- sub_v3_v3(v_tmp, v1);
- if (fac != 0.0f && !is_zero_v3(v1) && len_squared_v3(v_tmp) > epsilon_sq) {
- /* Not co-linear, we can compute crossproduct and normalize it into normal. */
- cross_v3_v3v3(r_normal, v1, v2);
- return normalize_v3(r_normal);
- }
- else {
- copy_v3_v3(r_normal, l->f->no);
- return 0.0f;
- }
+ /* Note: we cannot use result of normal_tri_v3 here to detect colinear vectors (vertex on a straight line)
+ * from zero value, because it does not normalize both vectors before making crossproduct.
+ * Instead of adding two costly normalize computations, just check ourselves for colinear case. */
+ /* Note: FEPSILON might need some finer tweaking at some point? Seems to be working OK for now though. */
+ float v1[3], v2[3], v_tmp[3];
+ sub_v3_v3v3(v1, l->prev->v->co, l->v->co);
+ sub_v3_v3v3(v2, l->next->v->co, l->v->co);
+
+ const float fac = ((v2[0] == 0.0f) ?
+ ((v2[1] == 0.0f) ? ((v2[2] == 0.0f) ? 0.0f : v1[2] / v2[2]) :
+ v1[1] / v2[1]) :
+ v1[0] / v2[0]);
+
+ mul_v3_v3fl(v_tmp, v2, fac);
+ sub_v3_v3(v_tmp, v1);
+ if (fac != 0.0f && !is_zero_v3(v1) && len_squared_v3(v_tmp) > epsilon_sq) {
+ /* Not co-linear, we can compute crossproduct and normalize it into normal. */
+ cross_v3_v3v3(r_normal, v1, v2);
+ return normalize_v3(r_normal);
+ }
+ else {
+ copy_v3_v3(r_normal, l->f->no);
+ return 0.0f;
+ }
}
/**
@@ -1568,7 +1540,7 @@ float BM_loop_calc_face_normal_safe_ex(const BMLoop *l, const float epsilon_sq,
*/
float BM_loop_calc_face_normal_safe(const BMLoop *l, float r_normal[3])
{
- return BM_loop_calc_face_normal_safe_ex(l, 1e-5f, r_normal);
+ return BM_loop_calc_face_normal_safe_ex(l, 1e-5f, r_normal);
}
/**
@@ -1582,16 +1554,16 @@ float BM_loop_calc_face_normal_safe(const BMLoop *l, float r_normal[3])
*/
float BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3])
{
- float v1[3], v2[3];
- sub_v3_v3v3(v1, l->prev->v->co, l->v->co);
- sub_v3_v3v3(v2, l->next->v->co, l->v->co);
+ float v1[3], v2[3];
+ sub_v3_v3v3(v1, l->prev->v->co, l->v->co);
+ sub_v3_v3v3(v2, l->next->v->co, l->v->co);
- cross_v3_v3v3(r_normal, v1, v2);
- const float len = normalize_v3(r_normal);
- if (UNLIKELY(len == 0.0f)) {
- copy_v3_v3(r_normal, l->f->no);
- }
- return len;
+ cross_v3_v3v3(r_normal, v1, v2);
+ const float len = normalize_v3(r_normal);
+ if (UNLIKELY(len == 0.0f)) {
+ copy_v3_v3(r_normal, l->f->no);
+ }
+ return len;
}
/**
@@ -1604,17 +1576,17 @@ float BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3])
*/
void BM_loop_calc_face_direction(const BMLoop *l, float r_dir[3])
{
- float v_prev[3];
- float v_next[3];
+ float v_prev[3];
+ float v_next[3];
- sub_v3_v3v3(v_prev, l->v->co, l->prev->v->co);
- sub_v3_v3v3(v_next, l->next->v->co, l->v->co);
+ sub_v3_v3v3(v_prev, l->v->co, l->prev->v->co);
+ sub_v3_v3v3(v_next, l->next->v->co, l->v->co);
- normalize_v3(v_prev);
- normalize_v3(v_next);
+ normalize_v3(v_prev);
+ normalize_v3(v_next);
- add_v3_v3v3(r_dir, v_prev, v_next);
- normalize_v3(r_dir);
+ add_v3_v3v3(r_dir, v_prev, v_next);
+ normalize_v3(r_dir);
}
/**
@@ -1628,32 +1600,32 @@ void BM_loop_calc_face_direction(const BMLoop *l, float r_dir[3])
*/
void BM_loop_calc_face_tangent(const BMLoop *l, float r_tangent[3])
{
- float v_prev[3];
- float v_next[3];
- float dir[3];
+ float v_prev[3];
+ float v_next[3];
+ float dir[3];
- sub_v3_v3v3(v_prev, l->prev->v->co, l->v->co);
- sub_v3_v3v3(v_next, l->v->co, l->next->v->co);
+ sub_v3_v3v3(v_prev, l->prev->v->co, l->v->co);
+ sub_v3_v3v3(v_next, l->v->co, l->next->v->co);
- normalize_v3(v_prev);
- normalize_v3(v_next);
- add_v3_v3v3(dir, v_prev, v_next);
+ normalize_v3(v_prev);
+ normalize_v3(v_next);
+ add_v3_v3v3(dir, v_prev, v_next);
- if (compare_v3v3(v_prev, v_next, FLT_EPSILON * 10.0f) == false) {
- float nor[3]; /* for this purpose doesn't need to be normalized */
- cross_v3_v3v3(nor, v_prev, v_next);
- /* concave face check */
- if (UNLIKELY(dot_v3v3(nor, l->f->no) < 0.0f)) {
- negate_v3(nor);
- }
- cross_v3_v3v3(r_tangent, dir, nor);
- }
- else {
- /* prev/next are the same - compare with face normal since we don't have one */
- cross_v3_v3v3(r_tangent, dir, l->f->no);
- }
+ if (compare_v3v3(v_prev, v_next, FLT_EPSILON * 10.0f) == false) {
+ float nor[3]; /* for this purpose doesn't need to be normalized */
+ cross_v3_v3v3(nor, v_prev, v_next);
+ /* concave face check */
+ if (UNLIKELY(dot_v3v3(nor, l->f->no) < 0.0f)) {
+ negate_v3(nor);
+ }
+ cross_v3_v3v3(r_tangent, dir, nor);
+ }
+ else {
+ /* prev/next are the same - compare with face normal since we don't have one */
+ cross_v3_v3v3(r_tangent, dir, l->f->no);
+ }
- normalize_v3(r_tangent);
+ normalize_v3(r_tangent);
}
/**
@@ -1666,18 +1638,18 @@ void BM_loop_calc_face_tangent(const BMLoop *l, float r_tangent[3])
*/
float BM_edge_calc_face_angle_ex(const BMEdge *e, const float fallback)
{
- if (BM_edge_is_manifold(e)) {
- const BMLoop *l1 = e->l;
- const BMLoop *l2 = e->l->radial_next;
- return angle_normalized_v3v3(l1->f->no, l2->f->no);
- }
- else {
- return fallback;
- }
+ if (BM_edge_is_manifold(e)) {
+ const BMLoop *l1 = e->l;
+ const BMLoop *l2 = e->l->radial_next;
+ return angle_normalized_v3v3(l1->f->no, l2->f->no);
+ }
+ else {
+ return fallback;
+ }
}
float BM_edge_calc_face_angle(const BMEdge *e)
{
- return BM_edge_calc_face_angle_ex(e, DEG2RADF(90.0f));
+ return BM_edge_calc_face_angle_ex(e, DEG2RADF(90.0f));
}
/**
@@ -1688,30 +1660,32 @@ float BM_edge_calc_face_angle(const BMEdge *e)
*
* \return angle in radians
*/
-float BM_edge_calc_face_angle_with_imat3_ex(const BMEdge *e, const float imat3[3][3], const float fallback)
+float BM_edge_calc_face_angle_with_imat3_ex(const BMEdge *e,
+ const float imat3[3][3],
+ const float fallback)
{
- if (BM_edge_is_manifold(e)) {
- const BMLoop *l1 = e->l;
- const BMLoop *l2 = e->l->radial_next;
- float no1[3], no2[3];
- copy_v3_v3(no1, l1->f->no);
- copy_v3_v3(no2, l2->f->no);
+ if (BM_edge_is_manifold(e)) {
+ const BMLoop *l1 = e->l;
+ const BMLoop *l2 = e->l->radial_next;
+ float no1[3], no2[3];
+ copy_v3_v3(no1, l1->f->no);
+ copy_v3_v3(no2, l2->f->no);
- mul_transposed_m3_v3(imat3, no1);
- mul_transposed_m3_v3(imat3, no2);
+ mul_transposed_m3_v3(imat3, no1);
+ mul_transposed_m3_v3(imat3, no2);
- normalize_v3(no1);
- normalize_v3(no2);
+ normalize_v3(no1);
+ normalize_v3(no2);
- return angle_normalized_v3v3(no1, no2);
- }
- else {
- return fallback;
- }
+ return angle_normalized_v3v3(no1, no2);
+ }
+ else {
+ return fallback;
+ }
}
float BM_edge_calc_face_angle_with_imat3(const BMEdge *e, const float imat3[3][3])
{
- return BM_edge_calc_face_angle_with_imat3_ex(e, imat3, DEG2RADF(90.0f));
+ return BM_edge_calc_face_angle_with_imat3_ex(e, imat3, DEG2RADF(90.0f));
}
/**
@@ -1724,19 +1698,19 @@ float BM_edge_calc_face_angle_with_imat3(const BMEdge *e, const float imat3[3][3
*/
float BM_edge_calc_face_angle_signed_ex(const BMEdge *e, const float fallback)
{
- if (BM_edge_is_manifold(e)) {
- BMLoop *l1 = e->l;
- BMLoop *l2 = e->l->radial_next;
- const float angle = angle_normalized_v3v3(l1->f->no, l2->f->no);
- return BM_edge_is_convex(e) ? angle : -angle;
- }
- else {
- return fallback;
- }
+ if (BM_edge_is_manifold(e)) {
+ BMLoop *l1 = e->l;
+ BMLoop *l2 = e->l->radial_next;
+ const float angle = angle_normalized_v3v3(l1->f->no, l2->f->no);
+ return BM_edge_is_convex(e) ? angle : -angle;
+ }
+ else {
+ return fallback;
+ }
}
float BM_edge_calc_face_angle_signed(const BMEdge *e)
{
- return BM_edge_calc_face_angle_signed_ex(e, DEG2RADF(90.0f));
+ return BM_edge_calc_face_angle_signed_ex(e, DEG2RADF(90.0f));
}
/**
@@ -1754,15 +1728,15 @@ float BM_edge_calc_face_angle_signed(const BMEdge *e)
void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3])
{
- float tvec[3];
- BMVert *v1, *v2;
- BM_edge_ordered_verts_ex(e, &v1, &v2, e_loop);
+ float tvec[3];
+ BMVert *v1, *v2;
+ BM_edge_ordered_verts_ex(e, &v1, &v2, e_loop);
- sub_v3_v3v3(tvec, v1->co, v2->co); /* use for temp storage */
- /* note, we could average the tangents of both loops,
- * for non flat ngons it will give a better direction */
- cross_v3_v3v3(r_tangent, tvec, e_loop->f->no);
- normalize_v3(r_tangent);
+ sub_v3_v3v3(tvec, v1->co, v2->co); /* use for temp storage */
+ /* note, we could average the tangents of both loops,
+ * for non flat ngons it will give a better direction */
+ cross_v3_v3v3(r_tangent, tvec, e_loop->f->no);
+ normalize_v3(r_tangent);
}
/**
@@ -1774,30 +1748,27 @@ void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_ta
*/
float BM_vert_calc_edge_angle_ex(const BMVert *v, const float fallback)
{
- BMEdge *e1, *e2;
+ BMEdge *e1, *e2;
- /* saves BM_vert_edge_count(v) and and edge iterator,
- * get the edges and count them both at once */
+ /* saves BM_vert_edge_count(v) and and edge iterator,
+ * get the edges and count them both at once */
- if ((e1 = v->e) &&
- (e2 = bmesh_disk_edge_next(e1, v)) &&
- (e1 != e2) &&
- /* make sure we come full circle and only have 2 connected edges */
- (e1 == bmesh_disk_edge_next(e2, v)))
- {
- BMVert *v1 = BM_edge_other_vert(e1, v);
- BMVert *v2 = BM_edge_other_vert(e2, v);
+ if ((e1 = v->e) && (e2 = bmesh_disk_edge_next(e1, v)) && (e1 != e2) &&
+ /* make sure we come full circle and only have 2 connected edges */
+ (e1 == bmesh_disk_edge_next(e2, v))) {
+ BMVert *v1 = BM_edge_other_vert(e1, v);
+ BMVert *v2 = BM_edge_other_vert(e2, v);
- return (float)M_PI - angle_v3v3v3(v1->co, v->co, v2->co);
- }
- else {
- return fallback;
- }
+ return (float)M_PI - angle_v3v3v3(v1->co, v->co, v2->co);
+ }
+ else {
+ return fallback;
+ }
}
float BM_vert_calc_edge_angle(const BMVert *v)
{
- return BM_vert_calc_edge_angle_ex(v, DEG2RADF(90.0f));
+ return BM_vert_calc_edge_angle_ex(v, DEG2RADF(90.0f));
}
/**
@@ -1806,57 +1777,57 @@ float BM_vert_calc_edge_angle(const BMVert *v)
*/
float BM_vert_calc_shell_factor(const BMVert *v)
{
- BMIter iter;
- BMLoop *l;
- float accum_shell = 0.0f;
- float accum_angle = 0.0f;
+ BMIter iter;
+ BMLoop *l;
+ float accum_shell = 0.0f;
+ float accum_angle = 0.0f;
- BM_ITER_ELEM (l, &iter, (BMVert *)v, BM_LOOPS_OF_VERT) {
- const float face_angle = BM_loop_calc_face_angle(l);
- accum_shell += shell_v3v3_normalized_to_dist(v->no, l->f->no) * face_angle;
- accum_angle += face_angle;
- }
+ BM_ITER_ELEM (l, &iter, (BMVert *)v, BM_LOOPS_OF_VERT) {
+ const float face_angle = BM_loop_calc_face_angle(l);
+ accum_shell += shell_v3v3_normalized_to_dist(v->no, l->f->no) * face_angle;
+ accum_angle += face_angle;
+ }
- if (accum_angle != 0.0f) {
- return accum_shell / accum_angle;
- }
- else {
- return 1.0f;
- }
+ if (accum_angle != 0.0f) {
+ return accum_shell / accum_angle;
+ }
+ else {
+ return 1.0f;
+ }
}
/* alternate version of #BM_vert_calc_shell_factor which only
* uses 'hflag' faces, but falls back to all if none found. */
float BM_vert_calc_shell_factor_ex(const BMVert *v, const float no[3], const char hflag)
{
- BMIter iter;
- const BMLoop *l;
- float accum_shell = 0.0f;
- float accum_angle = 0.0f;
- int tot_sel = 0, tot = 0;
-
- BM_ITER_ELEM (l, &iter, (BMVert *)v, BM_LOOPS_OF_VERT) {
- if (BM_elem_flag_test(l->f, hflag)) { /* <-- main difference to BM_vert_calc_shell_factor! */
- const float face_angle = BM_loop_calc_face_angle(l);
- accum_shell += shell_v3v3_normalized_to_dist(no, l->f->no) * face_angle;
- accum_angle += face_angle;
- tot_sel++;
- }
- tot++;
- }
-
- if (accum_angle != 0.0f) {
- return accum_shell / accum_angle;
- }
- else {
- /* other main difference from BM_vert_calc_shell_factor! */
- if (tot != 0 && tot_sel == 0) {
- /* none selected, so use all */
- return BM_vert_calc_shell_factor(v);
- }
- else {
- return 1.0f;
- }
- }
+ BMIter iter;
+ const BMLoop *l;
+ float accum_shell = 0.0f;
+ float accum_angle = 0.0f;
+ int tot_sel = 0, tot = 0;
+
+ BM_ITER_ELEM (l, &iter, (BMVert *)v, BM_LOOPS_OF_VERT) {
+ if (BM_elem_flag_test(l->f, hflag)) { /* <-- main difference to BM_vert_calc_shell_factor! */
+ const float face_angle = BM_loop_calc_face_angle(l);
+ accum_shell += shell_v3v3_normalized_to_dist(no, l->f->no) * face_angle;
+ accum_angle += face_angle;
+ tot_sel++;
+ }
+ tot++;
+ }
+
+ if (accum_angle != 0.0f) {
+ return accum_shell / accum_angle;
+ }
+ else {
+ /* other main difference from BM_vert_calc_shell_factor! */
+ if (tot != 0 && tot_sel == 0) {
+ /* none selected, so use all */
+ return BM_vert_calc_shell_factor(v);
+ }
+ else {
+ return 1.0f;
+ }
+ }
}
/**
@@ -1865,49 +1836,49 @@ float BM_vert_calc_shell_factor_ex(const BMVert *v, const float no[3], const cha
*/
float BM_vert_calc_median_tagged_edge_length(const BMVert *v)
{
- BMIter iter;
- BMEdge *e;
- int tot;
- float length = 0.0f;
+ BMIter iter;
+ BMEdge *e;
+ int tot;
+ float length = 0.0f;
- BM_ITER_ELEM_INDEX (e, &iter, (BMVert *)v, BM_EDGES_OF_VERT, tot) {
- const BMVert *v_other = BM_edge_other_vert(e, v);
- if (BM_elem_flag_test(v_other, BM_ELEM_TAG)) {
- length += BM_edge_calc_length(e);
- }
- }
+ BM_ITER_ELEM_INDEX(e, &iter, (BMVert *)v, BM_EDGES_OF_VERT, tot)
+ {
+ const BMVert *v_other = BM_edge_other_vert(e, v);
+ if (BM_elem_flag_test(v_other, BM_ELEM_TAG)) {
+ length += BM_edge_calc_length(e);
+ }
+ }
- if (tot) {
- return length / (float)tot;
- }
- else {
- return 0.0f;
- }
+ if (tot) {
+ return length / (float)tot;
+ }
+ else {
+ return 0.0f;
+ }
}
-
/**
* Returns the loop of the shortest edge in f.
*/
BMLoop *BM_face_find_shortest_loop(BMFace *f)
{
- BMLoop *shortest_loop = NULL;
- float shortest_len = FLT_MAX;
+ BMLoop *shortest_loop = NULL;
+ float shortest_len = FLT_MAX;
- BMLoop *l_iter;
- BMLoop *l_first;
+ BMLoop *l_iter;
+ BMLoop *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- const float len_sq = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
- if (len_sq <= shortest_len) {
- shortest_loop = l_iter;
- shortest_len = len_sq;
- }
- } while ((l_iter = l_iter->next) != l_first);
+ do {
+ const float len_sq = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
+ if (len_sq <= shortest_len) {
+ shortest_loop = l_iter;
+ shortest_len = len_sq;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
- return shortest_loop;
+ return shortest_loop;
}
/**
@@ -1915,23 +1886,23 @@ BMLoop *BM_face_find_shortest_loop(BMFace *f)
*/
BMLoop *BM_face_find_longest_loop(BMFace *f)
{
- BMLoop *longest_loop = NULL;
- float len_max_sq = 0.0f;
+ BMLoop *longest_loop = NULL;
+ float len_max_sq = 0.0f;
- BMLoop *l_iter;
- BMLoop *l_first;
+ BMLoop *l_iter;
+ BMLoop *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- const float len_sq = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
- if (len_sq >= len_max_sq) {
- longest_loop = l_iter;
- len_max_sq = len_sq;
- }
- } while ((l_iter = l_iter->next) != l_first);
+ do {
+ const float len_sq = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
+ if (len_sq >= len_max_sq) {
+ longest_loop = l_iter;
+ len_max_sq = len_sq;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
- return longest_loop;
+ return longest_loop;
}
/**
@@ -1943,46 +1914,46 @@ BMLoop *BM_face_find_longest_loop(BMFace *f)
#if 0
BMEdge *BM_edge_exists(BMVert *v_a, BMVert *v_b)
{
- BMIter iter;
- BMEdge *e;
+ BMIter iter;
+ BMEdge *e;
- BLI_assert(v_a != v_b);
- BLI_assert(v_a->head.htype == BM_VERT && v_b->head.htype == BM_VERT);
+ BLI_assert(v_a != v_b);
+ BLI_assert(v_a->head.htype == BM_VERT && v_b->head.htype == BM_VERT);
- BM_ITER_ELEM (e, &iter, v_a, BM_EDGES_OF_VERT) {
- if (e->v1 == v_b || e->v2 == v_b)
- return e;
- }
+ BM_ITER_ELEM (e, &iter, v_a, BM_EDGES_OF_VERT) {
+ if (e->v1 == v_b || e->v2 == v_b)
+ return e;
+ }
- return NULL;
+ return NULL;
}
#else
BMEdge *BM_edge_exists(BMVert *v_a, BMVert *v_b)
{
- /* speedup by looping over both edges verts
- * where one vert may connect to many edges but not the other. */
+ /* speedup by looping over both edges verts
+ * where one vert may connect to many edges but not the other. */
- BMEdge *e_a, *e_b;
+ BMEdge *e_a, *e_b;
- BLI_assert(v_a != v_b);
- BLI_assert(v_a->head.htype == BM_VERT && v_b->head.htype == BM_VERT);
+ BLI_assert(v_a != v_b);
+ BLI_assert(v_a->head.htype == BM_VERT && v_b->head.htype == BM_VERT);
- if ((e_a = v_a->e) && (e_b = v_b->e)) {
- BMEdge *e_a_iter = e_a, *e_b_iter = e_b;
+ if ((e_a = v_a->e) && (e_b = v_b->e)) {
+ BMEdge *e_a_iter = e_a, *e_b_iter = e_b;
- do {
- if (BM_vert_in_edge(e_a_iter, v_b)) {
- return e_a_iter;
- }
- if (BM_vert_in_edge(e_b_iter, v_a)) {
- return e_b_iter;
- }
- } while (((e_a_iter = bmesh_disk_edge_next(e_a_iter, v_a)) != e_a) &&
- ((e_b_iter = bmesh_disk_edge_next(e_b_iter, v_b)) != e_b));
- }
+ do {
+ if (BM_vert_in_edge(e_a_iter, v_b)) {
+ return e_a_iter;
+ }
+ if (BM_vert_in_edge(e_b_iter, v_a)) {
+ return e_b_iter;
+ }
+ } while (((e_a_iter = bmesh_disk_edge_next(e_a_iter, v_a)) != e_a) &&
+ ((e_b_iter = bmesh_disk_edge_next(e_b_iter, v_b)) != e_b));
+ }
- return NULL;
+ return NULL;
}
#endif
@@ -1993,19 +1964,19 @@ BMEdge *BM_edge_exists(BMVert *v_a, BMVert *v_b)
*/
BMEdge *BM_edge_find_double(BMEdge *e)
{
- BMVert *v = e->v1;
- BMVert *v_other = e->v2;
+ BMVert *v = e->v1;
+ BMVert *v_other = e->v2;
- BMEdge *e_iter;
+ BMEdge *e_iter;
- e_iter = e;
- while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e) {
- if (UNLIKELY(BM_vert_in_edge(e_iter, v_other))) {
- return e_iter;
- }
- }
+ e_iter = e;
+ while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e) {
+ if (UNLIKELY(BM_vert_in_edge(e_iter, v_other))) {
+ return e_iter;
+ }
+ }
- return NULL;
+ return NULL;
}
/**
@@ -2014,16 +1985,16 @@ BMEdge *BM_edge_find_double(BMEdge *e)
*/
BMLoop *BM_edge_find_first_loop_visible(BMEdge *e)
{
- if (e->l != NULL) {
- BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
- return l_iter;
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
- return NULL;
+ if (e->l != NULL) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
+ return l_iter;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ return NULL;
}
/**
@@ -2035,53 +2006,50 @@ BMLoop *BM_edge_find_first_loop_visible(BMEdge *e)
*/
BMFace *BM_face_exists(BMVert **varr, int len)
{
- if (varr[0]->e) {
- BMEdge *e_iter, *e_first;
- e_iter = e_first = varr[0]->e;
-
- /* would normally use BM_LOOPS_OF_VERT, but this runs so often,
- * its faster to iterate on the data directly */
- do {
- if (e_iter->l) {
- BMLoop *l_iter_radial, *l_first_radial;
- l_iter_radial = l_first_radial = e_iter->l;
-
- do {
- if ((l_iter_radial->v == varr[0]) &&
- (l_iter_radial->f->len == len))
- {
- /* the fist 2 verts match, now check the remaining (len - 2) faces do too
- * winding isn't known, so check in both directions */
- int i_walk = 2;
-
- if (l_iter_radial->next->v == varr[1]) {
- BMLoop *l_walk = l_iter_radial->next->next;
- do {
- if (l_walk->v != varr[i_walk]) {
- break;
- }
- } while ((void)(l_walk = l_walk->next), ++i_walk != len);
- }
- else if (l_iter_radial->prev->v == varr[1]) {
- BMLoop *l_walk = l_iter_radial->prev->prev;
- do {
- if (l_walk->v != varr[i_walk]) {
- break;
- }
- } while ((void)(l_walk = l_walk->prev), ++i_walk != len);
- }
-
- if (i_walk == len) {
- return l_iter_radial->f;
- }
- }
- } while ((l_iter_radial = l_iter_radial->radial_next) != l_first_radial);
-
- }
- } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, varr[0])) != e_first);
- }
-
- return NULL;
+ if (varr[0]->e) {
+ BMEdge *e_iter, *e_first;
+ e_iter = e_first = varr[0]->e;
+
+ /* would normally use BM_LOOPS_OF_VERT, but this runs so often,
+ * its faster to iterate on the data directly */
+ do {
+ if (e_iter->l) {
+ BMLoop *l_iter_radial, *l_first_radial;
+ l_iter_radial = l_first_radial = e_iter->l;
+
+ do {
+ if ((l_iter_radial->v == varr[0]) && (l_iter_radial->f->len == len)) {
+ /* the fist 2 verts match, now check the remaining (len - 2) faces do too
+ * winding isn't known, so check in both directions */
+ int i_walk = 2;
+
+ if (l_iter_radial->next->v == varr[1]) {
+ BMLoop *l_walk = l_iter_radial->next->next;
+ do {
+ if (l_walk->v != varr[i_walk]) {
+ break;
+ }
+ } while ((void)(l_walk = l_walk->next), ++i_walk != len);
+ }
+ else if (l_iter_radial->prev->v == varr[1]) {
+ BMLoop *l_walk = l_iter_radial->prev->prev;
+ do {
+ if (l_walk->v != varr[i_walk]) {
+ break;
+ }
+ } while ((void)(l_walk = l_walk->prev), ++i_walk != len);
+ }
+
+ if (i_walk == len) {
+ return l_iter_radial->f;
+ }
+ }
+ } while ((l_iter_radial = l_iter_radial->radial_next) != l_first_radial);
+ }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, varr[0])) != e_first);
+ }
+
+ return NULL;
}
/**
@@ -2089,34 +2057,34 @@ BMFace *BM_face_exists(BMVert **varr, int len)
*/
BMFace *BM_face_find_double(BMFace *f)
{
- BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
- for (BMLoop *l_iter = l_first->radial_next; l_first != l_iter; l_iter = l_iter->radial_next) {
- if (l_iter->f->len == l_first->f->len) {
- if (l_iter->v == l_first->v) {
- BMLoop *l_a = l_first, *l_b = l_iter, *l_b_init = l_iter;
- do {
- if (l_a->e != l_b->e) {
- break;
- }
- } while (((void)(l_a = l_a->next), (l_b = l_b->next)) != l_b_init);
- if (l_b == l_b_init) {
- return l_iter->f;
- }
- }
- else {
- BMLoop *l_a = l_first, *l_b = l_iter, *l_b_init = l_iter;
- do {
- if (l_a->e != l_b->e) {
- break;
- }
- } while (((void)(l_a = l_a->prev), (l_b = l_b->next)) != l_b_init);
- if (l_b == l_b_init) {
- return l_iter->f;
- }
- }
- }
- }
- return NULL;
+ BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
+ for (BMLoop *l_iter = l_first->radial_next; l_first != l_iter; l_iter = l_iter->radial_next) {
+ if (l_iter->f->len == l_first->f->len) {
+ if (l_iter->v == l_first->v) {
+ BMLoop *l_a = l_first, *l_b = l_iter, *l_b_init = l_iter;
+ do {
+ if (l_a->e != l_b->e) {
+ break;
+ }
+ } while (((void)(l_a = l_a->next), (l_b = l_b->next)) != l_b_init);
+ if (l_b == l_b_init) {
+ return l_iter->f;
+ }
+ }
+ else {
+ BMLoop *l_a = l_first, *l_b = l_iter, *l_b_init = l_iter;
+ do {
+ if (l_a->e != l_b->e) {
+ break;
+ }
+ } while (((void)(l_a = l_a->prev), (l_b = l_b->next)) != l_b_init);
+ if (l_b == l_b_init) {
+ return l_iter->f;
+ }
+ }
+ }
+ }
+ return NULL;
}
/**
@@ -2133,131 +2101,126 @@ BMFace *BM_face_find_double(BMFace *f)
*/
bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len)
{
- BMFace *f;
- BMEdge *e;
- BMVert *v;
- bool ok;
- int tot_tag;
-
- BMIter fiter;
- BMIter viter;
-
- int i;
-
- for (i = 0; i < len; i++) {
- /* save some time by looping over edge faces rather then vert faces
- * will still loop over some faces twice but not as many */
- BM_ITER_ELEM (f, &fiter, earr[i], BM_FACES_OF_EDGE) {
- BM_elem_flag_disable(f, BM_ELEM_INTERNAL_TAG);
- BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
- BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG);
- }
- }
-
- /* clear all edge tags */
- BM_ITER_ELEM (e, &fiter, varr[i], BM_EDGES_OF_VERT) {
- BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
- }
- }
-
- /* now tag all verts and edges in the boundary array as true so
- * we can know if a face-vert is from our array */
- for (i = 0; i < len; i++) {
- BM_elem_flag_enable(varr[i], BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_enable(earr[i], BM_ELEM_INTERNAL_TAG);
- }
-
-
- /* so! boundary is tagged, everything else cleared */
-
-
- /* 1) tag all faces connected to edges - if all their verts are boundary */
- tot_tag = 0;
- for (i = 0; i < len; i++) {
- BM_ITER_ELEM (f, &fiter, earr[i], BM_FACES_OF_EDGE) {
- if (!BM_elem_flag_test(f, BM_ELEM_INTERNAL_TAG)) {
- ok = true;
- BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
- if (!BM_elem_flag_test(v, BM_ELEM_INTERNAL_TAG)) {
- ok = false;
- break;
- }
- }
-
- if (ok) {
- /* we only use boundary verts */
- BM_elem_flag_enable(f, BM_ELEM_INTERNAL_TAG);
- tot_tag++;
- }
- }
- else {
- /* we already found! */
- }
- }
- }
-
- if (tot_tag == 0) {
- /* no faces use only boundary verts, quit early */
- ok = false;
- goto finally;
- }
-
- /* 2) loop over non-boundary edges that use boundary verts,
- * check each have 2 tagged faces connected (faces that only use 'varr' verts) */
- ok = true;
- for (i = 0; i < len; i++) {
- BM_ITER_ELEM (e, &fiter, varr[i], BM_EDGES_OF_VERT) {
-
- if (/* non-boundary edge */
- BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG) == false &&
- /* ...using boundary verts */
- BM_elem_flag_test(e->v1, BM_ELEM_INTERNAL_TAG) &&
- BM_elem_flag_test(e->v2, BM_ELEM_INTERNAL_TAG))
- {
- int tot_face_tag = 0;
- BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
- if (BM_elem_flag_test(f, BM_ELEM_INTERNAL_TAG)) {
- tot_face_tag++;
- }
- }
-
- if (tot_face_tag != 2) {
- ok = false;
- break;
- }
-
- }
- }
-
- if (ok == false) {
- break;
- }
- }
+ BMFace *f;
+ BMEdge *e;
+ BMVert *v;
+ bool ok;
+ int tot_tag;
+
+ BMIter fiter;
+ BMIter viter;
+
+ int i;
+
+ for (i = 0; i < len; i++) {
+ /* save some time by looping over edge faces rather then vert faces
+ * will still loop over some faces twice but not as many */
+ BM_ITER_ELEM (f, &fiter, earr[i], BM_FACES_OF_EDGE) {
+ BM_elem_flag_disable(f, BM_ELEM_INTERNAL_TAG);
+ BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
+ BM_elem_flag_disable(v, BM_ELEM_INTERNAL_TAG);
+ }
+ }
+
+ /* clear all edge tags */
+ BM_ITER_ELEM (e, &fiter, varr[i], BM_EDGES_OF_VERT) {
+ BM_elem_flag_disable(e, BM_ELEM_INTERNAL_TAG);
+ }
+ }
+
+ /* now tag all verts and edges in the boundary array as true so
+ * we can know if a face-vert is from our array */
+ for (i = 0; i < len; i++) {
+ BM_elem_flag_enable(varr[i], BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_enable(earr[i], BM_ELEM_INTERNAL_TAG);
+ }
+
+ /* so! boundary is tagged, everything else cleared */
+
+ /* 1) tag all faces connected to edges - if all their verts are boundary */
+ tot_tag = 0;
+ for (i = 0; i < len; i++) {
+ BM_ITER_ELEM (f, &fiter, earr[i], BM_FACES_OF_EDGE) {
+ if (!BM_elem_flag_test(f, BM_ELEM_INTERNAL_TAG)) {
+ ok = true;
+ BM_ITER_ELEM (v, &viter, f, BM_VERTS_OF_FACE) {
+ if (!BM_elem_flag_test(v, BM_ELEM_INTERNAL_TAG)) {
+ ok = false;
+ break;
+ }
+ }
+
+ if (ok) {
+ /* we only use boundary verts */
+ BM_elem_flag_enable(f, BM_ELEM_INTERNAL_TAG);
+ tot_tag++;
+ }
+ }
+ else {
+ /* we already found! */
+ }
+ }
+ }
+
+ if (tot_tag == 0) {
+ /* no faces use only boundary verts, quit early */
+ ok = false;
+ goto finally;
+ }
+
+ /* 2) loop over non-boundary edges that use boundary verts,
+ * check each have 2 tagged faces connected (faces that only use 'varr' verts) */
+ ok = true;
+ for (i = 0; i < len; i++) {
+ BM_ITER_ELEM (e, &fiter, varr[i], BM_EDGES_OF_VERT) {
+
+ if (/* non-boundary edge */
+ BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG) == false &&
+ /* ...using boundary verts */
+ BM_elem_flag_test(e->v1, BM_ELEM_INTERNAL_TAG) &&
+ BM_elem_flag_test(e->v2, BM_ELEM_INTERNAL_TAG)) {
+ int tot_face_tag = 0;
+ BM_ITER_ELEM (f, &fiter, e, BM_FACES_OF_EDGE) {
+ if (BM_elem_flag_test(f, BM_ELEM_INTERNAL_TAG)) {
+ tot_face_tag++;
+ }
+ }
+
+ if (tot_face_tag != 2) {
+ ok = false;
+ break;
+ }
+ }
+ }
+
+ if (ok == false) {
+ break;
+ }
+ }
finally:
- /* Cleanup */
- for (i = 0; i < len; i++) {
- BM_elem_flag_disable(varr[i], BM_ELEM_INTERNAL_TAG);
- BM_elem_flag_disable(earr[i], BM_ELEM_INTERNAL_TAG);
- }
- return ok;
+ /* Cleanup */
+ for (i = 0; i < len; i++) {
+ BM_elem_flag_disable(varr[i], BM_ELEM_INTERNAL_TAG);
+ BM_elem_flag_disable(earr[i], BM_ELEM_INTERNAL_TAG);
+ }
+ return ok;
}
/* same as 'BM_face_exists_multi' but built vert array from edges */
bool BM_face_exists_multi_edge(BMEdge **earr, int len)
{
- BMVert **varr = BLI_array_alloca(varr, len);
+ BMVert **varr = BLI_array_alloca(varr, len);
- /* first check if verts have edges, if not we can bail out early */
- if (!BM_verts_from_edges(varr, earr, len)) {
- BMESH_ASSERT(0);
- return false;
- }
+ /* first check if verts have edges, if not we can bail out early */
+ if (!BM_verts_from_edges(varr, earr, len)) {
+ BMESH_ASSERT(0);
+ return false;
+ }
- return BM_face_exists_multi(varr, earr, len);
+ return BM_face_exists_multi(varr, earr, len);
}
-
/**
* Given a set of vertices (varr), find out if
* all those vertices overlap an existing face.
@@ -2274,40 +2237,40 @@ bool BM_face_exists_multi_edge(BMEdge **earr, int len)
BMFace *BM_face_exists_overlap(BMVert **varr, const int len)
{
- BMIter viter;
- BMFace *f;
- int i;
- BMFace *f_overlap = NULL;
- LinkNode *f_lnk = NULL;
+ BMIter viter;
+ BMFace *f;
+ int i;
+ BMFace *f_overlap = NULL;
+ LinkNode *f_lnk = NULL;
#ifdef DEBUG
- /* check flag isn't already set */
- for (i = 0; i < len; i++) {
- BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
- BLI_assert(BM_ELEM_API_FLAG_TEST(f, _FLAG_OVERLAP) == 0);
- }
- }
+ /* check flag isn't already set */
+ for (i = 0; i < len; i++) {
+ BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
+ BLI_assert(BM_ELEM_API_FLAG_TEST(f, _FLAG_OVERLAP) == 0);
+ }
+ }
#endif
- for (i = 0; i < len; i++) {
- BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
- if (BM_ELEM_API_FLAG_TEST(f, _FLAG_OVERLAP) == 0) {
- if (len <= BM_verts_in_face_count(varr, len, f)) {
- f_overlap = f;
- break;
- }
+ for (i = 0; i < len; i++) {
+ BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
+ if (BM_ELEM_API_FLAG_TEST(f, _FLAG_OVERLAP) == 0) {
+ if (len <= BM_verts_in_face_count(varr, len, f)) {
+ f_overlap = f;
+ break;
+ }
- BM_ELEM_API_FLAG_ENABLE(f, _FLAG_OVERLAP);
- BLI_linklist_prepend_alloca(&f_lnk, f);
- }
- }
- }
+ BM_ELEM_API_FLAG_ENABLE(f, _FLAG_OVERLAP);
+ BLI_linklist_prepend_alloca(&f_lnk, f);
+ }
+ }
+ }
- for (; f_lnk; f_lnk = f_lnk->next) {
- BM_ELEM_API_FLAG_DISABLE((BMFace *)f_lnk->link, _FLAG_OVERLAP);
- }
+ for (; f_lnk; f_lnk = f_lnk->next) {
+ BM_ELEM_API_FLAG_DISABLE((BMFace *)f_lnk->link, _FLAG_OVERLAP);
+ }
- return f_overlap;
+ return f_overlap;
}
/**
@@ -2320,155 +2283,153 @@ BMFace *BM_face_exists_overlap(BMVert **varr, const int len)
*/
bool BM_face_exists_overlap_subset(BMVert **varr, const int len)
{
- BMIter viter;
- BMFace *f;
- bool is_init = false;
- bool is_overlap = false;
- LinkNode *f_lnk = NULL;
+ BMIter viter;
+ BMFace *f;
+ bool is_init = false;
+ bool is_overlap = false;
+ LinkNode *f_lnk = NULL;
#ifdef DEBUG
- /* check flag isn't already set */
- for (int i = 0; i < len; i++) {
- BLI_assert(BM_ELEM_API_FLAG_TEST(varr[i], _FLAG_OVERLAP) == 0);
- BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
- BLI_assert(BM_ELEM_API_FLAG_TEST(f, _FLAG_OVERLAP) == 0);
- }
- }
+ /* check flag isn't already set */
+ for (int i = 0; i < len; i++) {
+ BLI_assert(BM_ELEM_API_FLAG_TEST(varr[i], _FLAG_OVERLAP) == 0);
+ BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
+ BLI_assert(BM_ELEM_API_FLAG_TEST(f, _FLAG_OVERLAP) == 0);
+ }
+ }
#endif
- for (int i = 0; i < len; i++) {
- BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
- if ((f->len <= len) && (BM_ELEM_API_FLAG_TEST(f, _FLAG_OVERLAP) == 0)) {
- /* check if all vers in this face are flagged*/
- BMLoop *l_iter, *l_first;
-
- if (is_init == false) {
- is_init = true;
- for (int j = 0; j < len; j++) {
- BM_ELEM_API_FLAG_ENABLE(varr[j], _FLAG_OVERLAP);
- }
- }
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- is_overlap = true;
- do {
- if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP) == 0) {
- is_overlap = false;
- break;
- }
- } while ((l_iter = l_iter->next) != l_first);
-
- if (is_overlap) {
- break;
- }
-
- BM_ELEM_API_FLAG_ENABLE(f, _FLAG_OVERLAP);
- BLI_linklist_prepend_alloca(&f_lnk, f);
- }
- }
- }
-
- if (is_init == true) {
- for (int i = 0; i < len; i++) {
- BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
- }
- }
-
- for (; f_lnk; f_lnk = f_lnk->next) {
- BM_ELEM_API_FLAG_DISABLE((BMFace *)f_lnk->link, _FLAG_OVERLAP);
- }
-
- return is_overlap;
+ for (int i = 0; i < len; i++) {
+ BM_ITER_ELEM (f, &viter, varr[i], BM_FACES_OF_VERT) {
+ if ((f->len <= len) && (BM_ELEM_API_FLAG_TEST(f, _FLAG_OVERLAP) == 0)) {
+ /* check if all vers in this face are flagged*/
+ BMLoop *l_iter, *l_first;
+
+ if (is_init == false) {
+ is_init = true;
+ for (int j = 0; j < len; j++) {
+ BM_ELEM_API_FLAG_ENABLE(varr[j], _FLAG_OVERLAP);
+ }
+ }
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ is_overlap = true;
+ do {
+ if (BM_ELEM_API_FLAG_TEST(l_iter->v, _FLAG_OVERLAP) == 0) {
+ is_overlap = false;
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (is_overlap) {
+ break;
+ }
+
+ BM_ELEM_API_FLAG_ENABLE(f, _FLAG_OVERLAP);
+ BLI_linklist_prepend_alloca(&f_lnk, f);
+ }
+ }
+ }
+
+ if (is_init == true) {
+ for (int i = 0; i < len; i++) {
+ BM_ELEM_API_FLAG_DISABLE(varr[i], _FLAG_OVERLAP);
+ }
+ }
+
+ for (; f_lnk; f_lnk = f_lnk->next) {
+ BM_ELEM_API_FLAG_DISABLE((BMFace *)f_lnk->link, _FLAG_OVERLAP);
+ }
+
+ return is_overlap;
}
bool BM_vert_is_all_edge_flag_test(const BMVert *v, const char hflag, const bool respect_hide)
{
- if (v->e) {
- BMEdge *e_other;
- BMIter eiter;
+ if (v->e) {
+ BMEdge *e_other;
+ BMIter eiter;
- BM_ITER_ELEM (e_other, &eiter, (BMVert *)v, BM_EDGES_OF_VERT) {
- if (!respect_hide || !BM_elem_flag_test(e_other, BM_ELEM_HIDDEN)) {
- if (!BM_elem_flag_test(e_other, hflag)) {
- return false;
- }
- }
- }
- }
+ BM_ITER_ELEM (e_other, &eiter, (BMVert *)v, BM_EDGES_OF_VERT) {
+ if (!respect_hide || !BM_elem_flag_test(e_other, BM_ELEM_HIDDEN)) {
+ if (!BM_elem_flag_test(e_other, hflag)) {
+ return false;
+ }
+ }
+ }
+ }
- return true;
+ return true;
}
bool BM_vert_is_all_face_flag_test(const BMVert *v, const char hflag, const bool respect_hide)
{
- if (v->e) {
- BMEdge *f_other;
- BMIter fiter;
+ if (v->e) {
+ BMEdge *f_other;
+ BMIter fiter;
- BM_ITER_ELEM (f_other, &fiter, (BMVert *)v, BM_FACES_OF_VERT) {
- if (!respect_hide || !BM_elem_flag_test(f_other, BM_ELEM_HIDDEN)) {
- if (!BM_elem_flag_test(f_other, hflag)) {
- return false;
- }
- }
- }
- }
+ BM_ITER_ELEM (f_other, &fiter, (BMVert *)v, BM_FACES_OF_VERT) {
+ if (!respect_hide || !BM_elem_flag_test(f_other, BM_ELEM_HIDDEN)) {
+ if (!BM_elem_flag_test(f_other, hflag)) {
+ return false;
+ }
+ }
+ }
+ }
- return true;
+ return true;
}
-
bool BM_edge_is_all_face_flag_test(const BMEdge *e, const char hflag, const bool respect_hide)
{
- if (e->l) {
- BMLoop *l_iter, *l_first;
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- if (!respect_hide || !BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
- if (!BM_elem_flag_test(l_iter->f, hflag)) {
- return false;
- }
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
+ l_iter = l_first = e->l;
+ do {
+ if (!respect_hide || !BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
+ if (!BM_elem_flag_test(l_iter->f, hflag)) {
+ return false;
+ }
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
- return true;
+ return true;
}
/* convenience functions for checking flags */
bool BM_edge_is_any_vert_flag_test(const BMEdge *e, const char hflag)
{
- return (BM_elem_flag_test(e->v1, hflag) ||
- BM_elem_flag_test(e->v2, hflag));
+ return (BM_elem_flag_test(e->v1, hflag) || BM_elem_flag_test(e->v2, hflag));
}
bool BM_face_is_any_vert_flag_test(const BMFace *f, const char hflag)
{
- BMLoop *l_iter;
- BMLoop *l_first;
+ BMLoop *l_iter;
+ BMLoop *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (BM_elem_flag_test(l_iter->v, hflag)) {
- return true;
- }
- } while ((l_iter = l_iter->next) != l_first);
- return false;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter->v, hflag)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ return false;
}
bool BM_face_is_any_edge_flag_test(const BMFace *f, const char hflag)
{
- BMLoop *l_iter;
- BMLoop *l_first;
+ BMLoop *l_iter;
+ BMLoop *l_first;
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if (BM_elem_flag_test(l_iter->e, hflag)) {
- return true;
- }
- } while ((l_iter = l_iter->next) != l_first);
- return false;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter->e, hflag)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ return false;
}
/**
@@ -2476,49 +2437,49 @@ bool BM_face_is_any_edge_flag_test(const BMFace *f, const char hflag)
*/
bool BM_face_is_normal_valid(const BMFace *f)
{
- const float eps = 0.0001f;
- float no[3];
+ const float eps = 0.0001f;
+ float no[3];
- BM_face_calc_normal(f, no);
- return len_squared_v3v3(no, f->no) < (eps * eps);
+ BM_face_calc_normal(f, no);
+ return len_squared_v3v3(no, f->no) < (eps * eps);
}
static void bm_mesh_calc_volume_face(const BMFace *f, float *r_vol)
{
- const int tottri = f->len - 2;
- BMLoop **loops = BLI_array_alloca(loops, f->len);
- uint (*index)[3] = BLI_array_alloca(index, tottri);
- int j;
+ const int tottri = f->len - 2;
+ BMLoop **loops = BLI_array_alloca(loops, f->len);
+ uint(*index)[3] = BLI_array_alloca(index, tottri);
+ int j;
- BM_face_calc_tessellation(f, false, loops, index);
+ BM_face_calc_tessellation(f, false, loops, index);
- 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;
+ 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);
- }
+ /* 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, bool is_signed)
{
- /* warning, calls own tessellation function, may be slow */
- float vol = 0.0f;
- BMFace *f;
- BMIter fiter;
+ /* 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);
- }
+ BM_ITER_MESH (f, &fiter, bm, BM_FACES_OF_MESH) {
+ bm_mesh_calc_volume_face(f, &vol);
+ }
- if (is_signed == false) {
- vol = fabsf(vol);
- }
+ if (is_signed == false) {
+ vol = fabsf(vol);
+ }
- return vol;
+ return vol;
}
/* note, almost duplicate of BM_mesh_calc_edge_groups, keep in sync */
@@ -2538,143 +2499,144 @@ float BM_mesh_calc_volume(BMesh *bm, bool is_signed)
* (having both set is supported too).
* \return The number of groups found.
*/
-int BM_mesh_calc_face_groups(
- BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
- BMLoopFilterFunc filter_fn, void *user_data,
- const char hflag_test, const char htype_step)
+int BM_mesh_calc_face_groups(BMesh *bm,
+ int *r_groups_array,
+ int (**r_group_index)[2],
+ BMLoopFilterFunc filter_fn,
+ void *user_data,
+ const char hflag_test,
+ const char htype_step)
{
#ifdef DEBUG
- int group_index_len = 1;
+ int group_index_len = 1;
#else
- int group_index_len = 32;
+ int group_index_len = 32;
#endif
- int (*group_index)[2] = MEM_mallocN(sizeof(*group_index) * group_index_len, __func__);
-
- int *group_array = r_groups_array;
- STACK_DECLARE(group_array);
-
- int group_curr = 0;
-
- uint tot_faces = 0;
- uint tot_touch = 0;
-
- BMFace **stack;
- STACK_DECLARE(stack);
-
- BMIter iter;
- BMFace *f;
- int i;
-
- STACK_INIT(group_array, bm->totface);
-
- BLI_assert(((htype_step & ~(BM_VERT | BM_EDGE)) == 0) && (htype_step != 0));
-
- /* init the array */
- BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
- if ((hflag_test == 0) || BM_elem_flag_test(f, hflag_test)) {
- tot_faces++;
- BM_elem_flag_disable(f, BM_ELEM_TAG);
- }
- else {
- /* never walk over tagged */
- BM_elem_flag_enable(f, BM_ELEM_TAG);
- }
-
- BM_elem_index_set(f, i); /* set_inline */
- }
- bm->elem_index_dirty &= ~BM_FACE;
-
- /* detect groups */
- stack = MEM_mallocN(sizeof(*stack) * tot_faces, __func__);
-
- while (tot_touch != tot_faces) {
- int *group_item;
- bool ok = false;
-
- BLI_assert(tot_touch < tot_faces);
-
- STACK_INIT(stack, tot_faces);
-
- BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- if (BM_elem_flag_test(f, BM_ELEM_TAG) == false) {
- BM_elem_flag_enable(f, BM_ELEM_TAG);
- STACK_PUSH(stack, f);
- ok = true;
- break;
- }
- }
-
- BLI_assert(ok == true);
- UNUSED_VARS_NDEBUG(ok);
-
- /* manage arrays */
- if (group_index_len == group_curr) {
- group_index_len *= 2;
- group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_index_len);
- }
-
- group_item = group_index[group_curr];
- group_item[0] = STACK_SIZE(group_array);
- group_item[1] = 0;
-
- while ((f = STACK_POP(stack))) {
- BMLoop *l_iter, *l_first;
-
- /* add face */
- STACK_PUSH(group_array, BM_elem_index_get(f));
- tot_touch++;
- group_item[1]++;
- /* done */
-
- if (htype_step & BM_EDGE) {
- /* search for other faces */
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- BMLoop *l_radial_iter = l_iter->radial_next;
- if ((l_radial_iter != l_iter) &&
- ((filter_fn == NULL) || filter_fn(l_iter, user_data)))
- {
- do {
- BMFace *f_other = l_radial_iter->f;
- if (BM_elem_flag_test(f_other, BM_ELEM_TAG) == false) {
- BM_elem_flag_enable(f_other, BM_ELEM_TAG);
- STACK_PUSH(stack, f_other);
- }
- } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter);
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
-
- if (htype_step & BM_VERT) {
- BMIter liter;
- /* search for other faces */
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- if ((filter_fn == NULL) || filter_fn(l_iter, user_data)) {
- BMLoop *l_other;
- BM_ITER_ELEM (l_other, &liter, l_iter, BM_LOOPS_OF_LOOP) {
- BMFace *f_other = l_other->f;
- if (BM_elem_flag_test(f_other, BM_ELEM_TAG) == false) {
- BM_elem_flag_enable(f_other, BM_ELEM_TAG);
- STACK_PUSH(stack, f_other);
- }
- }
- }
- } while ((l_iter = l_iter->next) != l_first);
- }
- }
-
- group_curr++;
- }
-
- MEM_freeN(stack);
-
- /* reduce alloc to required size */
- group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_curr);
- *r_group_index = group_index;
-
- return group_curr;
+ int(*group_index)[2] = MEM_mallocN(sizeof(*group_index) * group_index_len, __func__);
+
+ int *group_array = r_groups_array;
+ STACK_DECLARE(group_array);
+
+ int group_curr = 0;
+
+ uint tot_faces = 0;
+ uint tot_touch = 0;
+
+ BMFace **stack;
+ STACK_DECLARE(stack);
+
+ BMIter iter;
+ BMFace *f;
+ int i;
+
+ STACK_INIT(group_array, bm->totface);
+
+ BLI_assert(((htype_step & ~(BM_VERT | BM_EDGE)) == 0) && (htype_step != 0));
+
+ /* init the array */
+ BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
+ if ((hflag_test == 0) || BM_elem_flag_test(f, hflag_test)) {
+ tot_faces++;
+ BM_elem_flag_disable(f, BM_ELEM_TAG);
+ }
+ else {
+ /* never walk over tagged */
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ }
+
+ BM_elem_index_set(f, i); /* set_inline */
+ }
+ bm->elem_index_dirty &= ~BM_FACE;
+
+ /* detect groups */
+ stack = MEM_mallocN(sizeof(*stack) * tot_faces, __func__);
+
+ while (tot_touch != tot_faces) {
+ int *group_item;
+ bool ok = false;
+
+ BLI_assert(tot_touch < tot_faces);
+
+ STACK_INIT(stack, tot_faces);
+
+ BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(f, BM_ELEM_TAG) == false) {
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ STACK_PUSH(stack, f);
+ ok = true;
+ break;
+ }
+ }
+
+ BLI_assert(ok == true);
+ UNUSED_VARS_NDEBUG(ok);
+
+ /* manage arrays */
+ if (group_index_len == group_curr) {
+ group_index_len *= 2;
+ group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_index_len);
+ }
+
+ group_item = group_index[group_curr];
+ group_item[0] = STACK_SIZE(group_array);
+ group_item[1] = 0;
+
+ while ((f = STACK_POP(stack))) {
+ BMLoop *l_iter, *l_first;
+
+ /* add face */
+ STACK_PUSH(group_array, BM_elem_index_get(f));
+ tot_touch++;
+ group_item[1]++;
+ /* done */
+
+ if (htype_step & BM_EDGE) {
+ /* search for other faces */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BMLoop *l_radial_iter = l_iter->radial_next;
+ if ((l_radial_iter != l_iter) && ((filter_fn == NULL) || filter_fn(l_iter, user_data))) {
+ do {
+ BMFace *f_other = l_radial_iter->f;
+ if (BM_elem_flag_test(f_other, BM_ELEM_TAG) == false) {
+ BM_elem_flag_enable(f_other, BM_ELEM_TAG);
+ STACK_PUSH(stack, f_other);
+ }
+ } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ if (htype_step & BM_VERT) {
+ BMIter liter;
+ /* search for other faces */
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if ((filter_fn == NULL) || filter_fn(l_iter, user_data)) {
+ BMLoop *l_other;
+ BM_ITER_ELEM (l_other, &liter, l_iter, BM_LOOPS_OF_LOOP) {
+ BMFace *f_other = l_other->f;
+ if (BM_elem_flag_test(f_other, BM_ELEM_TAG) == false) {
+ BM_elem_flag_enable(f_other, BM_ELEM_TAG);
+ STACK_PUSH(stack, f_other);
+ }
+ }
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+ }
+
+ group_curr++;
+ }
+
+ MEM_freeN(stack);
+
+ /* reduce alloc to required size */
+ group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_curr);
+ *r_group_index = group_index;
+
+ return group_curr;
}
/* note, almost duplicate of BM_mesh_calc_face_groups, keep in sync */
@@ -2696,145 +2658,147 @@ int BM_mesh_calc_face_groups(
* \note Unlike #BM_mesh_calc_face_groups there is no 'htype_step' argument,
* since we always walk over verts.
*/
-int BM_mesh_calc_edge_groups(
- BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
- BMVertFilterFunc filter_fn, void *user_data,
- const char hflag_test)
+int BM_mesh_calc_edge_groups(BMesh *bm,
+ int *r_groups_array,
+ int (**r_group_index)[2],
+ BMVertFilterFunc filter_fn,
+ void *user_data,
+ const char hflag_test)
{
#ifdef DEBUG
- int group_index_len = 1;
+ int group_index_len = 1;
#else
- int group_index_len = 32;
+ int group_index_len = 32;
#endif
- int (*group_index)[2] = MEM_mallocN(sizeof(*group_index) * group_index_len, __func__);
-
- int *group_array = r_groups_array;
- STACK_DECLARE(group_array);
+ int(*group_index)[2] = MEM_mallocN(sizeof(*group_index) * group_index_len, __func__);
+
+ int *group_array = r_groups_array;
+ STACK_DECLARE(group_array);
- int group_curr = 0;
+ int group_curr = 0;
- uint tot_edges = 0;
- uint tot_touch = 0;
+ uint tot_edges = 0;
+ uint tot_touch = 0;
- BMEdge **stack;
- STACK_DECLARE(stack);
+ BMEdge **stack;
+ STACK_DECLARE(stack);
- BMIter iter;
- BMEdge *e;
- int i;
+ BMIter iter;
+ BMEdge *e;
+ int i;
- STACK_INIT(group_array, bm->totedge);
+ STACK_INIT(group_array, bm->totedge);
- /* init the array */
- BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
- if ((hflag_test == 0) || BM_elem_flag_test(e, hflag_test)) {
- tot_edges++;
- BM_elem_flag_disable(e, BM_ELEM_TAG);
- }
- else {
- /* never walk over tagged */
- BM_elem_flag_enable(e, BM_ELEM_TAG);
- }
+ /* init the array */
+ BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
+ if ((hflag_test == 0) || BM_elem_flag_test(e, hflag_test)) {
+ tot_edges++;
+ BM_elem_flag_disable(e, BM_ELEM_TAG);
+ }
+ else {
+ /* never walk over tagged */
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
- BM_elem_index_set(e, i); /* set_inline */
- }
- bm->elem_index_dirty &= ~BM_EDGE;
+ BM_elem_index_set(e, i); /* set_inline */
+ }
+ bm->elem_index_dirty &= ~BM_EDGE;
- /* detect groups */
- stack = MEM_mallocN(sizeof(*stack) * tot_edges, __func__);
+ /* detect groups */
+ stack = MEM_mallocN(sizeof(*stack) * tot_edges, __func__);
- while (tot_touch != tot_edges) {
- int *group_item;
- bool ok = false;
+ while (tot_touch != tot_edges) {
+ int *group_item;
+ bool ok = false;
- BLI_assert(tot_touch < tot_edges);
+ BLI_assert(tot_touch < tot_edges);
- STACK_INIT(stack, tot_edges);
+ STACK_INIT(stack, tot_edges);
- BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- if (BM_elem_flag_test(e, BM_ELEM_TAG) == false) {
- BM_elem_flag_enable(e, BM_ELEM_TAG);
- STACK_PUSH(stack, e);
- ok = true;
- break;
- }
- }
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG) == false) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ STACK_PUSH(stack, e);
+ ok = true;
+ break;
+ }
+ }
- BLI_assert(ok == true);
- UNUSED_VARS_NDEBUG(ok);
+ BLI_assert(ok == true);
+ UNUSED_VARS_NDEBUG(ok);
- /* manage arrays */
- if (group_index_len == group_curr) {
- group_index_len *= 2;
- group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_index_len);
- }
+ /* manage arrays */
+ if (group_index_len == group_curr) {
+ group_index_len *= 2;
+ group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_index_len);
+ }
- group_item = group_index[group_curr];
- group_item[0] = STACK_SIZE(group_array);
- group_item[1] = 0;
+ group_item = group_index[group_curr];
+ group_item[0] = STACK_SIZE(group_array);
+ group_item[1] = 0;
- while ((e = STACK_POP(stack))) {
- BMIter viter;
- BMIter eiter;
- BMVert *v;
+ while ((e = STACK_POP(stack))) {
+ BMIter viter;
+ BMIter eiter;
+ BMVert *v;
- /* add edge */
- STACK_PUSH(group_array, BM_elem_index_get(e));
- tot_touch++;
- group_item[1]++;
- /* done */
+ /* add edge */
+ STACK_PUSH(group_array, BM_elem_index_get(e));
+ tot_touch++;
+ group_item[1]++;
+ /* done */
- /* search for other edges */
- BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) {
- if ((filter_fn == NULL) || filter_fn(v, user_data)) {
- BMEdge *e_other;
- BM_ITER_ELEM (e_other, &eiter, v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(e_other, BM_ELEM_TAG) == false) {
- BM_elem_flag_enable(e_other, BM_ELEM_TAG);
- STACK_PUSH(stack, e_other);
- }
- }
- }
- }
- }
+ /* search for other edges */
+ BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) {
+ if ((filter_fn == NULL) || filter_fn(v, user_data)) {
+ BMEdge *e_other;
+ BM_ITER_ELEM (e_other, &eiter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e_other, BM_ELEM_TAG) == false) {
+ BM_elem_flag_enable(e_other, BM_ELEM_TAG);
+ STACK_PUSH(stack, e_other);
+ }
+ }
+ }
+ }
+ }
- group_curr++;
- }
+ group_curr++;
+ }
- MEM_freeN(stack);
+ MEM_freeN(stack);
- /* reduce alloc to required size */
- group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_curr);
- *r_group_index = group_index;
-
- return group_curr;
+ /* reduce alloc to required size */
+ group_index = MEM_reallocN(group_index, sizeof(*group_index) * group_curr);
+ *r_group_index = group_index;
+
+ return group_curr;
}
float bmesh_subd_falloff_calc(const int falloff, float val)
{
- switch (falloff) {
- case SUBD_FALLOFF_SMOOTH:
- val = 3.0f * val * val - 2.0f * val * val * val;
- break;
- case SUBD_FALLOFF_SPHERE:
- val = sqrtf(2.0f * val - val * val);
- break;
- case SUBD_FALLOFF_ROOT:
- val = sqrtf(val);
- break;
- case SUBD_FALLOFF_SHARP:
- val = val * val;
- break;
- case SUBD_FALLOFF_LIN:
- break;
- case SUBD_FALLOFF_INVSQUARE:
- val = val * (2.0f - val);
- break;
- default:
- BLI_assert(0);
- break;
- }
-
- return val;
+ switch (falloff) {
+ case SUBD_FALLOFF_SMOOTH:
+ val = 3.0f * val * val - 2.0f * val * val * val;
+ break;
+ case SUBD_FALLOFF_SPHERE:
+ val = sqrtf(2.0f * val - val * val);
+ break;
+ case SUBD_FALLOFF_ROOT:
+ val = sqrtf(val);
+ break;
+ case SUBD_FALLOFF_SHARP:
+ val = val * val;
+ break;
+ case SUBD_FALLOFF_LIN:
+ break;
+ case SUBD_FALLOFF_INVSQUARE:
+ val = val * (2.0f - val);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ return val;
}
diff --git a/source/blender/bmesh/intern/bmesh_query.h b/source/blender/bmesh/intern/bmesh_query.h
index c04c7f5e97d..e96984490c0 100644
--- a/source/blender/bmesh/intern/bmesh_query.h
+++ b/source/blender/bmesh/intern/bmesh_query.h
@@ -21,25 +21,33 @@
* \ingroup bmesh
*/
-bool BM_vert_in_face(BMVert *v, BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_verts_in_face_count(BMVert **varr, int len, BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_verts_in_face(BMVert **varr, int len, BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-
-bool BM_edge_in_face(const BMEdge *e, const BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BLI_INLINE bool BM_edge_in_loop(const BMEdge *e, const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-
-BLI_INLINE bool BM_vert_in_edge(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BLI_INLINE bool BM_verts_in_edge(const BMVert *v1, const BMVert *v2, const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-
-float BM_edge_calc_length(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_edge_calc_length_squared(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb) ATTR_NONNULL();
-bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb) ATTR_NONNULL();
-BLI_INLINE BMVert *BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_in_face(BMVert *v, BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_verts_in_face_count(BMVert **varr, int len, BMFace *f) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+bool BM_verts_in_face(BMVert **varr, int len, BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+
+bool BM_edge_in_face(const BMEdge *e, const BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+BLI_INLINE bool BM_edge_in_loop(const BMEdge *e, const BMLoop *l) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+
+BLI_INLINE bool BM_vert_in_edge(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+BLI_INLINE bool BM_verts_in_edge(const BMVert *v1,
+ const BMVert *v2,
+ const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+
+float BM_edge_calc_length(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_edge_calc_length_squared(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb) ATTR_NONNULL();
+bool BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb) ATTR_NONNULL();
+BLI_INLINE BMVert *BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
BMLoop *BM_loop_other_edge_loop(BMLoop *l, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *BM_vert_step_fan_loop(BMLoop *l, BMEdge **e_step) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -47,89 +55,115 @@ BMLoop *BM_vert_find_first_loop(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(
BMLoop *BM_vert_find_first_loop_visible(BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *BM_edge_find_first_loop_visible(BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_vert_pair_share_face_check(
- BMVert *v_a, BMVert *v_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_vert_pair_share_face_check_cb(
- BMVert *v_a, BMVert *v_b,
- bool (*test_fn)(BMFace *f, void *user_data), void *user_data) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3);
-BMFace *BM_vert_pair_share_face_by_len(
- BMVert *v_a, BMVert *v_b,
- BMLoop **r_l_a, BMLoop **r_l_b,
- const bool allow_adjacent) ATTR_NONNULL();
-BMFace *BM_vert_pair_share_face_by_angle(
- BMVert *v_a, BMVert *v_b,
- BMLoop **r_l_a, BMLoop **r_l_b,
- const bool allow_adjacent) ATTR_NONNULL();
-
-BMFace *BM_edge_pair_share_face_by_len(
- BMEdge *e_a, BMEdge *e_b,
- BMLoop **r_l_a, BMLoop **r_l_b,
- const bool allow_adjacent) ATTR_NONNULL();
-
-int BM_vert_edge_count_nonwire(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_pair_share_face_check(BMVert *v_a, BMVert *v_b) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+bool BM_vert_pair_share_face_check_cb(BMVert *v_a,
+ BMVert *v_b,
+ bool (*test_fn)(BMFace *f, void *user_data),
+ void *user_data) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1, 2, 3);
+BMFace *BM_vert_pair_share_face_by_len(BMVert *v_a,
+ BMVert *v_b,
+ BMLoop **r_l_a,
+ BMLoop **r_l_b,
+ const bool allow_adjacent) ATTR_NONNULL();
+BMFace *BM_vert_pair_share_face_by_angle(BMVert *v_a,
+ BMVert *v_b,
+ BMLoop **r_l_a,
+ BMLoop **r_l_b,
+ const bool allow_adjacent) ATTR_NONNULL();
+
+BMFace *BM_edge_pair_share_face_by_len(BMEdge *e_a,
+ BMEdge *e_b,
+ BMLoop **r_l_a,
+ BMLoop **r_l_b,
+ const bool allow_adjacent) ATTR_NONNULL();
+
+int BM_vert_edge_count_nonwire(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
#define BM_vert_edge_count_is_equal(v, n) (BM_vert_edge_count_at_most(v, (n) + 1) == n)
#define BM_vert_edge_count_is_over(v, n) (BM_vert_edge_count_at_most(v, (n) + 1) == (n) + 1)
-int BM_vert_edge_count_at_most(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_vert_edge_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_vert_edge_count_at_most(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+int BM_vert_edge_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
#define BM_edge_face_count_is_equal(e, n) (BM_edge_face_count_at_most(e, (n) + 1) == n)
#define BM_edge_face_count_is_over(e, n) (BM_edge_face_count_at_most(e, (n) + 1) == (n) + 1)
-int BM_edge_face_count_at_most(const BMEdge *e, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_edge_face_count(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_edge_face_count_at_most(const BMEdge *e, const int count_max) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+int BM_edge_face_count(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
#define BM_vert_face_count_is_equal(v, n) (BM_vert_face_count_at_most(v, (n) + 1) == n)
#define BM_vert_face_count_is_over(v, n) (BM_vert_face_count_at_most(v, (n) + 1) == (n) + 1)
-int BM_vert_face_count_at_most(const BMVert *v, int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_vert_face_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_vert_face_count_at_most(const BMVert *v, int count_max) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+int BM_vert_face_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMEdge *BM_vert_other_disk_edge(BMVert *v, BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_vert_is_edge_pair(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_vert_is_edge_pair_manifold(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_vert_edge_pair(BMVert *v, BMEdge **r_e_a, BMEdge **r_e_b);
-bool BM_vert_face_check(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_vert_is_wire(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-
-bool BM_vert_is_manifold(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_vert_is_manifold_region(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BLI_INLINE bool BM_edge_is_manifold(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_vert_is_boundary(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BLI_INLINE bool BM_edge_is_contiguous(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_edge_is_convex(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_edge_is_contiguous_loop_cd(
- const BMEdge *e,
- const int cd_loop_type, const int cd_loop_offset)
- ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-
-int BM_loop_region_loops_count_at_most(BMLoop *l, int *r_loop_total) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
-int BM_loop_region_loops_count(BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
-bool BM_loop_is_convex(const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_loop_point_side_of_loop_test(const BMLoop *l, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_loop_point_side_of_edge_test(const BMLoop *l, const float co[3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_is_edge_pair(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_is_edge_pair_manifold(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_edge_pair(BMVert *v, BMEdge **r_e_a, BMEdge **r_e_b);
+bool BM_vert_face_check(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_is_wire(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+
+bool BM_vert_is_manifold(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_is_manifold_region(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+BLI_INLINE bool BM_edge_is_manifold(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_is_boundary(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+BLI_INLINE bool BM_edge_is_contiguous(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_edge_is_convex(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_edge_is_contiguous_loop_cd(const BMEdge *e,
+ const int cd_loop_type,
+ const int cd_loop_offset) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+
+int BM_loop_region_loops_count_at_most(BMLoop *l, int *r_loop_total) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1);
+int BM_loop_region_loops_count(BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
+bool BM_loop_is_convex(const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+float BM_loop_point_side_of_loop_test(const BMLoop *l, const float co[3]) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+float BM_loop_point_side_of_edge_test(const BMLoop *l, const float co[3]) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
BMLoop *BM_loop_find_prev_nodouble(BMLoop *l, BMLoop *l_stop, const float eps_sq);
BMLoop *BM_loop_find_next_nodouble(BMLoop *l, BMLoop *l_stop, const float eps_sq);
-float BM_loop_calc_face_angle(const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3]) ATTR_NONNULL();
-float BM_loop_calc_face_normal_safe(const BMLoop *l, float r_normal[3]) ATTR_NONNULL();
-float BM_loop_calc_face_normal_safe_ex(const BMLoop *l, const float epsilon, float r_normal[3]) ATTR_NONNULL();
-void BM_loop_calc_face_direction(const BMLoop *l, float r_normal[3]);
-void BM_loop_calc_face_tangent(const BMLoop *l, float r_tangent[3]);
-
-float BM_edge_calc_face_angle_ex(const BMEdge *e, const float fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_edge_calc_face_angle(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_edge_calc_face_angle_signed_ex(const BMEdge *e, const float fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_edge_calc_face_angle_with_imat3_ex(const BMEdge *e, const float imat3[3][3], const float fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_edge_calc_face_angle_with_imat3(const BMEdge *e, const float imat3[3][3]) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_edge_calc_face_angle_signed(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3]) ATTR_NONNULL();
-
-float BM_vert_calc_edge_angle(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_vert_calc_edge_angle_ex(const BMVert *v, const float fallback) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_vert_calc_shell_factor(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_vert_calc_shell_factor_ex(const BMVert *v, const float no[3], const char hflag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-float BM_vert_calc_median_tagged_edge_length(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_loop_calc_face_angle(const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3]) ATTR_NONNULL();
+float BM_loop_calc_face_normal_safe(const BMLoop *l, float r_normal[3]) ATTR_NONNULL();
+float BM_loop_calc_face_normal_safe_ex(const BMLoop *l, const float epsilon, float r_normal[3])
+ ATTR_NONNULL();
+void BM_loop_calc_face_direction(const BMLoop *l, float r_normal[3]);
+void BM_loop_calc_face_tangent(const BMLoop *l, float r_tangent[3]);
+
+float BM_edge_calc_face_angle_ex(const BMEdge *e, const float fallback) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+float BM_edge_calc_face_angle(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_edge_calc_face_angle_signed_ex(const BMEdge *e,
+ const float fallback) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+float BM_edge_calc_face_angle_with_imat3_ex(const BMEdge *e,
+ const float imat3[3][3],
+ const float fallback) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+float BM_edge_calc_face_angle_with_imat3(const BMEdge *e,
+ const float imat3[3][3]) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+float BM_edge_calc_face_angle_signed(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void BM_edge_calc_face_tangent(const BMEdge *e, const BMLoop *e_loop, float r_tangent[3])
+ ATTR_NONNULL();
+
+float BM_vert_calc_edge_angle(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_vert_calc_edge_angle_ex(const BMVert *v, const float fallback) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+float BM_vert_calc_shell_factor(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_vert_calc_shell_factor_ex(const BMVert *v,
+ const float no[3],
+ const char hflag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+float BM_vert_calc_median_tagged_edge_length(const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
BMLoop *BM_face_find_shortest_loop(BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *BM_face_find_longest_loop(BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -140,58 +174,73 @@ BMEdge *BM_edge_find_double(BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMFace *BM_face_exists(BMVert **varr, int len) ATTR_NONNULL(1);
BMFace *BM_face_find_double(BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_face_exists_multi_edge(BMEdge **earr, int len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_face_exists_multi(BMVert **varr, BMEdge **earr, int len) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+bool BM_face_exists_multi_edge(BMEdge **earr, int len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMFace *BM_face_exists_overlap(BMVert **varr, const int len) ATTR_WARN_UNUSED_RESULT;
-bool BM_face_exists_overlap_subset(BMVert **varr, const int len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_face_exists_overlap_subset(BMVert **varr, const int len) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
-int BM_face_share_face_count(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_face_share_edge_count(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_face_share_vert_count(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_face_share_face_count(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_face_share_edge_count(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int BM_face_share_vert_count(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_face_share_face_check(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_face_share_edge_check(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_face_share_vert_check(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_face_share_face_check(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_face_share_edge_check(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_face_share_vert_check(BMFace *f_a, BMFace *f_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_loop_share_edge_check(BMLoop *l_a, BMLoop *l_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_loop_share_edge_check(BMLoop *l_a, BMLoop *l_b) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_edge_share_face_check(BMEdge *e1, BMEdge *e2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_edge_share_quad_check(BMEdge *e1, BMEdge *e2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_edge_share_vert_check(BMEdge *e1, BMEdge *e2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMVert *BM_edge_share_vert(BMEdge *e1, BMEdge *e2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *BM_edge_vert_share_loop(BMLoop *l, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *BM_face_vert_share_loop(BMFace *f, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *BM_face_edge_share_loop(BMFace *f, BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void BM_edge_ordered_verts(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2) ATTR_NONNULL();
-void BM_edge_ordered_verts_ex(
- const BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
- const BMLoop *edge_loop) ATTR_NONNULL();
-
-bool BM_vert_is_all_edge_flag_test(const BMVert *v, const char hflag, const bool respect_hide) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_vert_is_all_face_flag_test(const BMVert *v, const char hflag, const bool respect_hide) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_edge_is_all_face_flag_test(const BMEdge *e, const char hflag, const bool respect_hide) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-
-bool BM_edge_is_any_vert_flag_test(const BMEdge *e, const char hflag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_face_is_any_vert_flag_test(const BMFace *f, const char hflag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool BM_face_is_any_edge_flag_test(const BMFace *f, const char hflag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void BM_edge_ordered_verts(const BMEdge *edge, BMVert **r_v1, BMVert **r_v2) ATTR_NONNULL();
+void BM_edge_ordered_verts_ex(const BMEdge *edge,
+ BMVert **r_v1,
+ BMVert **r_v2,
+ const BMLoop *edge_loop) ATTR_NONNULL();
+
+bool BM_vert_is_all_edge_flag_test(const BMVert *v,
+ const char hflag,
+ const bool respect_hide) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_vert_is_all_face_flag_test(const BMVert *v,
+ const char hflag,
+ const bool respect_hide) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool BM_edge_is_all_face_flag_test(const BMEdge *e,
+ const char hflag,
+ const bool respect_hide) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+
+bool BM_edge_is_any_vert_flag_test(const BMEdge *e, const char hflag) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+bool BM_face_is_any_vert_flag_test(const BMFace *f, const char hflag) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+bool BM_face_is_any_edge_flag_test(const BMFace *f, const char hflag) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
bool BM_face_is_normal_valid(const BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
float BM_mesh_calc_volume(BMesh *bm, bool is_signed) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int BM_mesh_calc_face_groups(
- BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
- BMLoopFilterFunc filter_fn, void *user_data,
- const char hflag_test, const char htype_step)
- ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3);
-int BM_mesh_calc_edge_groups(
- BMesh *bm, int *r_groups_array, int (**r_group_index)[2],
- BMVertFilterFunc filter_fn, void *user_data,
- const char hflag_test)
- ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3);
+int BM_mesh_calc_face_groups(BMesh *bm,
+ int *r_groups_array,
+ int (**r_group_index)[2],
+ BMLoopFilterFunc filter_fn,
+ void *user_data,
+ const char hflag_test,
+ const char htype_step) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3);
+int BM_mesh_calc_edge_groups(BMesh *bm,
+ int *r_groups_array,
+ int (**r_group_index)[2],
+ BMVertFilterFunc filter_fn,
+ void *user_data,
+ const char hflag_test) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3);
/* not really any good place to put this */
float bmesh_subd_falloff_calc(const int falloff, float val) ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/bmesh/intern/bmesh_query_inline.h b/source/blender/bmesh/intern/bmesh_query_inline.h
index 582aa55b600..90919cc361b 100644
--- a/source/blender/bmesh/intern/bmesh_query_inline.h
+++ b/source/blender/bmesh/intern/bmesh_query_inline.h
@@ -18,7 +18,6 @@
* \ingroup bmesh
*/
-
#ifndef __BMESH_QUERY_INLINE_H__
#define __BMESH_QUERY_INLINE_H__
@@ -26,56 +25,54 @@
* Returns whether or not a given vertex is
* is part of a given edge.
*/
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE bool BM_vert_in_edge(const BMEdge *e, const BMVert *v)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
+ bool BM_vert_in_edge(const BMEdge *e, const BMVert *v)
{
- return (ELEM(v, e->v1, e->v2));
+ return (ELEM(v, e->v1, e->v2));
}
/**
* Returns whether or not a given edge is part of a given loop.
*/
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
-BLI_INLINE bool BM_edge_in_loop(const BMEdge *e, const BMLoop *l)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE
+ bool BM_edge_in_loop(const BMEdge *e, const BMLoop *l)
{
- return (l->e == e || l->prev->e == e);
+ return (l->e == e || l->prev->e == e);
}
/**
* Returns whether or not two vertices are in
* a given edge
*/
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3)
-BLI_INLINE bool BM_verts_in_edge(const BMVert *v1, const BMVert *v2, const BMEdge *e)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3) BLI_INLINE
+ bool BM_verts_in_edge(const BMVert *v1, const BMVert *v2, const BMEdge *e)
{
- return ((e->v1 == v1 && e->v2 == v2) ||
- (e->v1 == v2 && e->v2 == v1));
+ return ((e->v1 == v1 && e->v2 == v2) || (e->v1 == v2 && e->v2 == v1));
}
/**
* Given a edge and one of its vertices, returns
* the other vertex.
*/
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
-BLI_INLINE BMVert *BM_edge_other_vert(BMEdge *e, const BMVert *v)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE BMVert *BM_edge_other_vert(BMEdge *e,
+ const BMVert *v)
{
- if (e->v1 == v) {
- return e->v2;
- }
- else if (e->v2 == v) {
- return e->v1;
- }
- return NULL;
+ if (e->v1 == v) {
+ return e->v2;
+ }
+ else if (e->v2 == v) {
+ return e->v1;
+ }
+ return NULL;
}
/**
* Tests whether or not the edge is part of a wire.
* (ie: has no faces attached to it)
*/
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE bool BM_edge_is_wire(const BMEdge *e)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE bool BM_edge_is_wire(const BMEdge *e)
{
- return (e->l == NULL);
+ return (e->l == NULL);
}
/**
@@ -84,17 +81,16 @@ BLI_INLINE bool BM_edge_is_wire(const BMEdge *e)
*/
#if 1 /* fast path for checking manifold */
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE bool BM_edge_is_manifold(const BMEdge *e)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE bool BM_edge_is_manifold(const BMEdge *e)
{
- const BMLoop *l = e->l;
- return (l && (l->radial_next != l) && /* not 0 or 1 face users */
- (l->radial_next->radial_next == l)); /* 2 face users */
+ const BMLoop *l = e->l;
+ return (l && (l->radial_next != l) && /* not 0 or 1 face users */
+ (l->radial_next->radial_next == l)); /* 2 face users */
}
#else
BLI_INLINE int BM_edge_is_manifold(BMEdge *e)
{
- return (BM_edge_face_count(e) == 2);
+ return (BM_edge_face_count(e) == 2);
}
#endif
@@ -102,14 +98,13 @@ BLI_INLINE int BM_edge_is_manifold(BMEdge *e)
* Tests that the edge is manifold and
* that both its faces point the same way.
*/
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE bool BM_edge_is_contiguous(const BMEdge *e)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE bool BM_edge_is_contiguous(const BMEdge *e)
{
- const BMLoop *l = e->l;
- 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));
+ const BMLoop *l = e->l;
+ 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));
}
/**
@@ -118,48 +113,44 @@ BLI_INLINE bool BM_edge_is_contiguous(const BMEdge *e)
*/
#if 1 /* fast path for checking boundary */
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e)
{
- const BMLoop *l = e->l;
- return (l && (l->radial_next == l));
+ const BMLoop *l = e->l;
+ return (l && (l->radial_next == l));
}
#else
BLI_INLINE int BM_edge_is_boundary(BMEdge *e)
{
- return (BM_edge_face_count(e) == 1);
+ return (BM_edge_face_count(e) == 1);
}
#endif
/**
* Tests whether one loop is next to another within the same face.
*/
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
-BLI_INLINE bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE
+ bool BM_loop_is_adjacent(const BMLoop *l_a, const BMLoop *l_b)
{
- BLI_assert(l_a->f == l_b->f);
- BLI_assert(l_a != l_b);
- return (ELEM(l_b, l_a->next, l_a->prev));
+ BLI_assert(l_a->f == l_b->f);
+ BLI_assert(l_a != l_b);
+ return (ELEM(l_b, l_a->next, l_a->prev));
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE bool BM_loop_is_manifold(const BMLoop *l)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE bool BM_loop_is_manifold(const BMLoop *l)
{
- return ((l != l->radial_next) &&
- (l == l->radial_next->radial_next));
+ return ((l != l->radial_next) && (l == l->radial_next->radial_next));
}
/**
* Check if we have a single wire edge user.
*/
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE bool BM_vert_is_wire_endpoint(const BMVert *v)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE bool BM_vert_is_wire_endpoint(const BMVert *v)
{
- const BMEdge *e = v->e;
- if (e && e->l == NULL) {
- return (BM_DISK_EDGE_NEXT(e, v) == e);
- }
- return false;
+ const BMEdge *e = v->e;
+ if (e && e->l == NULL) {
+ return (BM_DISK_EDGE_NEXT(e, v) == e);
+ }
+ return false;
}
#endif /* __BMESH_QUERY_INLINE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c
index a90d0d245d0..d9f68f8aa62 100644
--- a/source/blender/bmesh/intern/bmesh_structure.c
+++ b/source/blender/bmesh/intern/bmesh_structure.c
@@ -34,17 +34,17 @@
void bmesh_disk_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src)
{
- if (e->v1 == v_src) {
- e->v1 = v_dst;
- e->v1_disk_link.next = e->v1_disk_link.prev = NULL;
- }
- else if (e->v2 == v_src) {
- e->v2 = v_dst;
- e->v2_disk_link.next = e->v2_disk_link.prev = NULL;
- }
- else {
- BLI_assert(0);
- }
+ if (e->v1 == v_src) {
+ e->v1 = v_dst;
+ e->v1_disk_link.next = e->v1_disk_link.prev = NULL;
+ }
+ else if (e->v2 == v_src) {
+ e->v2 = v_dst;
+ e->v2_disk_link.next = e->v2_disk_link.prev = NULL;
+ }
+ else {
+ BLI_assert(0);
+ }
}
/**
@@ -54,34 +54,34 @@ void bmesh_disk_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src)
*/
void bmesh_edge_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src)
{
- /* swap out loops */
- if (e->l) {
- BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- if (l_iter->v == v_src) {
- l_iter->v = v_dst;
- }
- else if (l_iter->next->v == v_src) {
- l_iter->next->v = v_dst;
- }
- else {
- BLI_assert(l_iter->prev->v != v_src);
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
-
- /* swap out edges */
- bmesh_disk_vert_replace(e, v_dst, v_src);
+ /* swap out loops */
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ if (l_iter->v == v_src) {
+ l_iter->v = v_dst;
+ }
+ else if (l_iter->next->v == v_src) {
+ l_iter->next->v = v_dst;
+ }
+ else {
+ BLI_assert(l_iter->prev->v != v_src);
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+
+ /* swap out edges */
+ bmesh_disk_vert_replace(e, v_dst, v_src);
}
void bmesh_disk_vert_replace(BMEdge *e, BMVert *v_dst, BMVert *v_src)
{
- BLI_assert(e->v1 == v_src || e->v2 == v_src);
- bmesh_disk_edge_remove(e, v_src); /* remove e from tv's disk cycle */
- bmesh_disk_vert_swap(e, v_dst, v_src); /* swap out tv for v_new in e */
- bmesh_disk_edge_append(e, v_dst); /* add e to v_dst's disk cycle */
- BLI_assert(e->v1 != e->v2);
+ BLI_assert(e->v1 == v_src || e->v2 == v_src);
+ bmesh_disk_edge_remove(e, v_src); /* remove e from tv's disk cycle */
+ bmesh_disk_vert_swap(e, v_dst, v_src); /* swap out tv for v_new in e */
+ bmesh_disk_edge_append(e, v_dst); /* add e to v_dst's disk cycle */
+ BLI_assert(e->v1 != e->v2);
}
/**
@@ -155,116 +155,116 @@ void bmesh_disk_vert_replace(BMEdge *e, BMVert *v_dst, BMVert *v_src)
void bmesh_disk_edge_append(BMEdge *e, BMVert *v)
{
- if (!v->e) {
- BMDiskLink *dl1 = bmesh_disk_edge_link_from_vert(e, v);
-
- v->e = e;
- dl1->next = dl1->prev = e;
- }
- else {
- BMDiskLink *dl1, *dl2, *dl3;
-
- 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;
-
- dl2->prev = e;
- if (dl3) {
- dl3->next = e;
- }
- }
+ if (!v->e) {
+ BMDiskLink *dl1 = bmesh_disk_edge_link_from_vert(e, v);
+
+ v->e = e;
+ dl1->next = dl1->prev = e;
+ }
+ else {
+ BMDiskLink *dl1, *dl2, *dl3;
+
+ 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;
+
+ dl2->prev = e;
+ if (dl3) {
+ dl3->next = e;
+ }
+ }
}
void bmesh_disk_edge_remove(BMEdge *e, BMVert *v)
{
- BMDiskLink *dl1, *dl2;
+ BMDiskLink *dl1, *dl2;
- dl1 = bmesh_disk_edge_link_from_vert(e, v);
- if (dl1->prev) {
- dl2 = bmesh_disk_edge_link_from_vert(dl1->prev, v);
- dl2->next = dl1->next;
- }
+ dl1 = bmesh_disk_edge_link_from_vert(e, v);
+ if (dl1->prev) {
+ dl2 = bmesh_disk_edge_link_from_vert(dl1->prev, v);
+ dl2->next = dl1->next;
+ }
- if (dl1->next) {
- dl2 = bmesh_disk_edge_link_from_vert(dl1->next, v);
- dl2->prev = dl1->prev;
- }
+ if (dl1->next) {
+ dl2 = bmesh_disk_edge_link_from_vert(dl1->next, v);
+ dl2->prev = dl1->prev;
+ }
- if (v->e == e) {
- v->e = (e != dl1->next) ? dl1->next : NULL;
- }
+ if (v->e == e) {
+ v->e = (e != dl1->next) ? dl1->next : NULL;
+ }
- dl1->next = dl1->prev = NULL;
+ dl1->next = dl1->prev = NULL;
}
BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2)
{
- BMEdge *e_iter, *e_first;
+ BMEdge *e_iter, *e_first;
- if (v1->e) {
- e_first = e_iter = v1->e;
+ if (v1->e) {
+ e_first = e_iter = v1->e;
- do {
- if (BM_verts_in_edge(v1, v2, e_iter)) {
- return e_iter;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v1)) != e_first);
- }
+ do {
+ if (BM_verts_in_edge(v1, v2, e_iter)) {
+ return e_iter;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v1)) != e_first);
+ }
- return NULL;
+ return NULL;
}
int bmesh_disk_count(const BMVert *v)
{
- int count = 0;
- if (v->e) {
- BMEdge *e_first, *e_iter;
- e_iter = e_first = v->e;
- do {
- count++;
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- }
- return count;
+ int count = 0;
+ if (v->e) {
+ BMEdge *e_first, *e_iter;
+ e_iter = e_first = v->e;
+ do {
+ count++;
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return count;
}
int bmesh_disk_count_at_most(const BMVert *v, const int count_max)
{
- int count = 0;
- if (v->e) {
- BMEdge *e_first, *e_iter;
- e_iter = e_first = v->e;
- do {
- count++;
- if (count == count_max) {
- break;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- }
- return count;
+ int count = 0;
+ if (v->e) {
+ BMEdge *e_first, *e_iter;
+ e_iter = e_first = v->e;
+ do {
+ count++;
+ if (count == count_max) {
+ break;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return count;
}
bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v)
{
- BMEdge *e_iter;
-
- if (!BM_vert_in_edge(e, v)) {
- return false;
- }
- if (len == 0 || bmesh_disk_count_at_most(v, len + 1) != len) {
- return false;
- }
-
- e_iter = e;
- do {
- if (len != 1 && bmesh_disk_edge_prev(e_iter, v) == e_iter) {
- return false;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
-
- return true;
+ BMEdge *e_iter;
+
+ if (!BM_vert_in_edge(e, v)) {
+ return false;
+ }
+ if (len == 0 || bmesh_disk_count_at_most(v, len + 1) != len) {
+ return false;
+ }
+
+ e_iter = e;
+ do {
+ if (len != 1 && bmesh_disk_edge_prev(e_iter, v) == e_iter) {
+ return false;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
+
+ return true;
}
/**
@@ -277,41 +277,41 @@ bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v)
*/
int bmesh_disk_facevert_count(const BMVert *v)
{
- /* is there an edge on this vert at all */
- int count = 0;
- if (v->e) {
- BMEdge *e_first, *e_iter;
-
- /* first, loop around edge */
- e_first = e_iter = v->e;
- do {
- if (e_iter->l) {
- count += bmesh_radial_facevert_count(e_iter->l, v);
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- }
- return count;
+ /* is there an edge on this vert at all */
+ int count = 0;
+ if (v->e) {
+ BMEdge *e_first, *e_iter;
+
+ /* first, loop around edge */
+ e_first = e_iter = v->e;
+ do {
+ if (e_iter->l) {
+ count += bmesh_radial_facevert_count(e_iter->l, v);
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return count;
}
int bmesh_disk_facevert_count_at_most(const BMVert *v, const int count_max)
{
- /* is there an edge on this vert at all */
- int count = 0;
- if (v->e) {
- BMEdge *e_first, *e_iter;
-
- /* first, loop around edge */
- e_first = e_iter = v->e;
- do {
- if (e_iter->l) {
- count += bmesh_radial_facevert_count_at_most(e_iter->l, v, count_max - count);
- if (count == count_max) {
- break;
- }
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
- }
- return count;
+ /* is there an edge on this vert at all */
+ int count = 0;
+ if (v->e) {
+ BMEdge *e_first, *e_iter;
+
+ /* first, loop around edge */
+ e_first = e_iter = v->e;
+ do {
+ if (e_iter->l) {
+ count += bmesh_radial_facevert_count_at_most(e_iter->l, v, count_max - count);
+ if (count == count_max) {
+ break;
+ }
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first);
+ }
+ return count;
}
/**
@@ -324,13 +324,13 @@ int bmesh_disk_facevert_count_at_most(const BMVert *v, const int count_max)
*/
BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v)
{
- const BMEdge *e_iter = e;
- do {
- if (e_iter->l != NULL) {
- return (BMEdge *)((e_iter->l->v == v) ? e_iter : e_iter->l->next->e);
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
- return NULL;
+ const BMEdge *e_iter = e;
+ do {
+ if (e_iter->l != NULL) {
+ return (BMEdge *)((e_iter->l->v == v) ? e_iter : e_iter->l->next->e);
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
+ return NULL;
}
/**
@@ -340,13 +340,13 @@ BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v)
*/
BMLoop *bmesh_disk_faceloop_find_first(const BMEdge *e, const BMVert *v)
{
- const BMEdge *e_iter = e;
- do {
- if (e_iter->l != NULL) {
- return (e_iter->l->v == v) ? e_iter->l : e_iter->l->next;
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
- return NULL;
+ const BMEdge *e_iter = e;
+ do {
+ if (e_iter->l != NULL) {
+ return (e_iter->l->v == v) ? e_iter->l : e_iter->l->next;
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
+ return NULL;
}
/**
@@ -354,91 +354,91 @@ BMLoop *bmesh_disk_faceloop_find_first(const BMEdge *e, const BMVert *v)
*/
BMLoop *bmesh_disk_faceloop_find_first_visible(const BMEdge *e, const BMVert *v)
{
- const BMEdge *e_iter = e;
- do {
- if (!BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN)) {
- if (e_iter->l != NULL) {
- BMLoop *l_iter, *l_first;
- l_iter = l_first = e_iter->l;
- do {
- if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
- return (l_iter->v == v) ? l_iter : l_iter->next;
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
- }
- } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
- return NULL;
+ const BMEdge *e_iter = e;
+ do {
+ if (!BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN)) {
+ if (e_iter->l != NULL) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e_iter->l;
+ do {
+ if (!BM_elem_flag_test(l_iter->f, BM_ELEM_HIDDEN)) {
+ return (l_iter->v == v) ? l_iter : l_iter->next;
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ }
+ } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e);
+ return NULL;
}
BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v)
{
- BMEdge *e_find;
- e_find = bmesh_disk_edge_next(e, v);
- do {
- if (e_find->l && bmesh_radial_facevert_check(e_find->l, v)) {
- return e_find;
- }
- } while ((e_find = bmesh_disk_edge_next(e_find, v)) != e);
- return (BMEdge *)e;
+ BMEdge *e_find;
+ e_find = bmesh_disk_edge_next(e, v);
+ do {
+ if (e_find->l && bmesh_radial_facevert_check(e_find->l, v)) {
+ return e_find;
+ }
+ } while ((e_find = bmesh_disk_edge_next(e_find, v)) != e);
+ return (BMEdge *)e;
}
/*****radial cycle functions, e.g. loops surrounding edges**** */
bool bmesh_radial_validate(int radlen, BMLoop *l)
{
- BMLoop *l_iter = l;
- int i = 0;
-
- if (bmesh_radial_length(l) != radlen) {
- return false;
- }
-
- do {
- if (UNLIKELY(!l_iter)) {
- BMESH_ASSERT(0);
- return false;
- }
-
- if (l_iter->e != l->e) {
- return false;
- }
- if (l_iter->v != l->e->v1 && l_iter->v != l->e->v2) {
- return false;
- }
-
- if (UNLIKELY(i > BM_LOOP_RADIAL_MAX)) {
- BMESH_ASSERT(0);
- return false;
- }
-
- i++;
- } while ((l_iter = l_iter->radial_next) != l);
-
- return true;
+ BMLoop *l_iter = l;
+ int i = 0;
+
+ if (bmesh_radial_length(l) != radlen) {
+ return false;
+ }
+
+ do {
+ if (UNLIKELY(!l_iter)) {
+ BMESH_ASSERT(0);
+ return false;
+ }
+
+ if (l_iter->e != l->e) {
+ return false;
+ }
+ if (l_iter->v != l->e->v1 && l_iter->v != l->e->v2) {
+ return false;
+ }
+
+ if (UNLIKELY(i > BM_LOOP_RADIAL_MAX)) {
+ BMESH_ASSERT(0);
+ return false;
+ }
+
+ i++;
+ } while ((l_iter = l_iter->radial_next) != l);
+
+ return true;
}
void bmesh_radial_loop_append(BMEdge *e, BMLoop *l)
{
- if (e->l == NULL) {
- e->l = l;
- l->radial_next = l->radial_prev = l;
- }
- else {
- l->radial_prev = e->l;
- l->radial_next = e->l->radial_next;
-
- e->l->radial_next->radial_prev = l;
- e->l->radial_next = l;
-
- e->l = l;
- }
-
- if (UNLIKELY(l->e && l->e != e)) {
- /* l is already in a radial cycle for a different edge */
- BMESH_ASSERT(0);
- }
-
- l->e = e;
+ if (e->l == NULL) {
+ e->l = l;
+ l->radial_next = l->radial_prev = l;
+ }
+ else {
+ l->radial_prev = e->l;
+ l->radial_next = e->l->radial_next;
+
+ e->l->radial_next->radial_prev = l;
+ e->l->radial_next = l;
+
+ e->l = l;
+ }
+
+ if (UNLIKELY(l->e && l->e != e)) {
+ /* l is already in a radial cycle for a different edge */
+ BMESH_ASSERT(0);
+ }
+
+ l->e = e;
}
/**
@@ -451,32 +451,32 @@ void bmesh_radial_loop_append(BMEdge *e, BMLoop *l)
*/
void bmesh_radial_loop_remove(BMEdge *e, BMLoop *l)
{
- /* if e is non-NULL, l must be in the radial cycle of e */
- if (UNLIKELY(e != l->e)) {
- BMESH_ASSERT(0);
- }
-
- if (l->radial_next != l) {
- if (l == e->l) {
- e->l = l->radial_next;
- }
-
- l->radial_next->radial_prev = l->radial_prev;
- l->radial_prev->radial_next = l->radial_next;
- }
- else {
- if (l == e->l) {
- e->l = NULL;
- }
- else {
- BMESH_ASSERT(0);
- }
- }
-
- /* l is no longer in a radial cycle; empty the links
- * to the cycle and the link back to an edge */
- l->radial_next = l->radial_prev = NULL;
- l->e = NULL;
+ /* if e is non-NULL, l must be in the radial cycle of e */
+ if (UNLIKELY(e != l->e)) {
+ BMESH_ASSERT(0);
+ }
+
+ if (l->radial_next != l) {
+ if (l == e->l) {
+ e->l = l->radial_next;
+ }
+
+ l->radial_next->radial_prev = l->radial_prev;
+ l->radial_prev->radial_next = l->radial_next;
+ }
+ else {
+ if (l == e->l) {
+ e->l = NULL;
+ }
+ else {
+ BMESH_ASSERT(0);
+ }
+ }
+
+ /* l is no longer in a radial cycle; empty the links
+ * to the cycle and the link back to an edge */
+ l->radial_next = l->radial_prev = NULL;
+ l->e = NULL;
}
/**
@@ -485,15 +485,15 @@ void bmesh_radial_loop_remove(BMEdge *e, BMLoop *l)
*/
void bmesh_radial_loop_unlink(BMLoop *l)
{
- if (l->radial_next != l) {
- l->radial_next->radial_prev = l->radial_prev;
- l->radial_prev->radial_next = l->radial_next;
- }
-
- /* l is no longer in a radial cycle; empty the links
- * to the cycle and the link back to an edge */
- l->radial_next = l->radial_prev = NULL;
- l->e = NULL;
+ if (l->radial_next != l) {
+ l->radial_next->radial_prev = l->radial_prev;
+ l->radial_prev->radial_next = l->radial_next;
+ }
+
+ /* l is no longer in a radial cycle; empty the links
+ * to the cycle and the link back to an edge */
+ l->radial_next = l->radial_prev = NULL;
+ l->e = NULL;
}
/**
@@ -504,52 +504,52 @@ void bmesh_radial_loop_unlink(BMLoop *l)
*/
BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v)
{
- const BMLoop *l_iter;
- l_iter = l;
- do {
- if (l_iter->v == v) {
- return (BMLoop *)l_iter;
- }
- } while ((l_iter = l_iter->radial_next) != l);
- return NULL;
+ const BMLoop *l_iter;
+ l_iter = l;
+ do {
+ if (l_iter->v == v) {
+ return (BMLoop *)l_iter;
+ }
+ } while ((l_iter = l_iter->radial_next) != l);
+ return NULL;
}
BMLoop *bmesh_radial_faceloop_find_next(const BMLoop *l, const BMVert *v)
{
- BMLoop *l_iter;
- l_iter = l->radial_next;
- do {
- if (l_iter->v == v) {
- return l_iter;
- }
- } while ((l_iter = l_iter->radial_next) != l);
- return (BMLoop *)l;
+ BMLoop *l_iter;
+ l_iter = l->radial_next;
+ do {
+ if (l_iter->v == v) {
+ return l_iter;
+ }
+ } while ((l_iter = l_iter->radial_next) != l);
+ return (BMLoop *)l;
}
int bmesh_radial_length(const BMLoop *l)
{
- const BMLoop *l_iter = l;
- int i = 0;
-
- if (!l) {
- return 0;
- }
-
- do {
- if (UNLIKELY(!l_iter)) {
- /* radial cycle is broken (not a circulat loop) */
- BMESH_ASSERT(0);
- return 0;
- }
-
- i++;
- if (UNLIKELY(i >= BM_LOOP_RADIAL_MAX)) {
- BMESH_ASSERT(0);
- return -1;
- }
- } while ((l_iter = l_iter->radial_next) != l);
-
- return i;
+ const BMLoop *l_iter = l;
+ int i = 0;
+
+ if (!l) {
+ return 0;
+ }
+
+ do {
+ if (UNLIKELY(!l_iter)) {
+ /* radial cycle is broken (not a circulat loop) */
+ BMESH_ASSERT(0);
+ return 0;
+ }
+
+ i++;
+ if (UNLIKELY(i >= BM_LOOP_RADIAL_MAX)) {
+ BMESH_ASSERT(0);
+ return -1;
+ }
+ } while ((l_iter = l_iter->radial_next) != l);
+
+ return i;
}
/**
@@ -560,33 +560,33 @@ int bmesh_radial_length(const BMLoop *l)
*/
int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v)
{
- const BMLoop *l_iter;
- int count = 0;
- l_iter = l;
- do {
- if (l_iter->v == v) {
- count++;
- }
- } while ((l_iter = l_iter->radial_next) != l);
-
- return count;
+ const BMLoop *l_iter;
+ int count = 0;
+ l_iter = l;
+ do {
+ if (l_iter->v == v) {
+ count++;
+ }
+ } while ((l_iter = l_iter->radial_next) != l);
+
+ return count;
}
int bmesh_radial_facevert_count_at_most(const BMLoop *l, const BMVert *v, const int count_max)
{
- const BMLoop *l_iter;
- int count = 0;
- l_iter = l;
- do {
- if (l_iter->v == v) {
- count++;
- if (count == count_max) {
- break;
- }
- }
- } while ((l_iter = l_iter->radial_next) != l);
-
- return count;
+ const BMLoop *l_iter;
+ int count = 0;
+ l_iter = l;
+ do {
+ if (l_iter->v == v) {
+ count++;
+ if (count == count_max) {
+ break;
+ }
+ }
+ } while ((l_iter = l_iter->radial_next) != l);
+
+ return count;
}
/**
@@ -596,51 +596,49 @@ int bmesh_radial_facevert_count_at_most(const BMLoop *l, const BMVert *v, const
*/
bool bmesh_radial_facevert_check(const BMLoop *l, const BMVert *v)
{
- const BMLoop *l_iter;
- l_iter = l;
- do {
- if (l_iter->v == v) {
- return true;
- }
- } while ((l_iter = l_iter->radial_next) != l);
-
- return false;
+ const BMLoop *l_iter;
+ l_iter = l;
+ do {
+ if (l_iter->v == v) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != l);
+
+ return false;
}
/*****loop cycle functions, e.g. loops surrounding a face**** */
bool bmesh_loop_validate(BMFace *f)
{
- int i;
- int len = f->len;
- BMLoop *l_iter, *l_first;
-
- l_first = BM_FACE_FIRST_LOOP(f);
-
- if (l_first == NULL) {
- return false;
- }
-
- /* Validate that the face loop cycle is the length specified by f->len */
- for (i = 1, l_iter = l_first->next; i < len; i++, l_iter = l_iter->next) {
- if ((l_iter->f != f) ||
- (l_iter == l_first))
- {
- return false;
- }
- }
- if (l_iter != l_first) {
- return false;
- }
-
- /* Validate the loop->prev links also form a cycle of length f->len */
- for (i = 1, l_iter = l_first->prev; i < len; i++, l_iter = l_iter->prev) {
- if (l_iter == l_first) {
- return false;
- }
- }
- if (l_iter != l_first) {
- return false;
- }
-
- return true;
+ int i;
+ int len = f->len;
+ BMLoop *l_iter, *l_first;
+
+ l_first = BM_FACE_FIRST_LOOP(f);
+
+ if (l_first == NULL) {
+ return false;
+ }
+
+ /* Validate that the face loop cycle is the length specified by f->len */
+ for (i = 1, l_iter = l_first->next; i < len; i++, l_iter = l_iter->next) {
+ if ((l_iter->f != f) || (l_iter == l_first)) {
+ return false;
+ }
+ }
+ if (l_iter != l_first) {
+ return false;
+ }
+
+ /* Validate the loop->prev links also form a cycle of length f->len */
+ for (i = 1, l_iter = l_first->prev; i < len; i++, l_iter = l_iter->prev) {
+ if (l_iter == l_first) {
+ return false;
+ }
+ }
+ if (l_iter != l_first) {
+ return false;
+ }
+
+ return true;
}
diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h
index 8e3ba7b46c0..7ae55a5fa6f 100644
--- a/source/blender/bmesh/intern/bmesh_structure.h
+++ b/source/blender/bmesh/intern/bmesh_structure.h
@@ -32,44 +32,65 @@
*/
/* LOOP CYCLE MANAGEMENT */
-bool bmesh_loop_validate(BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool bmesh_loop_validate(BMFace *f) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/* DISK CYCLE MANAGMENT */
-void bmesh_disk_edge_append(BMEdge *e, BMVert *v) ATTR_NONNULL();
-void bmesh_disk_edge_remove(BMEdge *e, BMVert *v) ATTR_NONNULL();
-BLI_INLINE BMEdge *bmesh_disk_edge_next_safe(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BLI_INLINE BMEdge *bmesh_disk_edge_prev_safe(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BLI_INLINE BMEdge *bmesh_disk_edge_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BLI_INLINE BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int bmesh_disk_facevert_count_at_most(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int bmesh_disk_facevert_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BMLoop *bmesh_disk_faceloop_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BMLoop *bmesh_disk_faceloop_find_first_visible(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void bmesh_disk_edge_append(BMEdge *e, BMVert *v) ATTR_NONNULL();
+void bmesh_disk_edge_remove(BMEdge *e, BMVert *v) ATTR_NONNULL();
+BLI_INLINE BMEdge *bmesh_disk_edge_next_safe(const BMEdge *e,
+ const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+BLI_INLINE BMEdge *bmesh_disk_edge_prev_safe(const BMEdge *e,
+ const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+BLI_INLINE BMEdge *bmesh_disk_edge_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+BLI_INLINE BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+int bmesh_disk_facevert_count_at_most(const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+int bmesh_disk_facevert_count(const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+BMLoop *bmesh_disk_faceloop_find_first(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+BMLoop *bmesh_disk_faceloop_find_first_visible(const BMEdge *e,
+ const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
/* RADIAL CYCLE MANAGMENT */
-void bmesh_radial_loop_append(BMEdge *e, BMLoop *l) ATTR_NONNULL();
-void bmesh_radial_loop_remove(BMEdge *e, BMLoop *l) ATTR_NONNULL();
-void bmesh_radial_loop_unlink(BMLoop *l) ATTR_NONNULL();
+void bmesh_radial_loop_append(BMEdge *e, BMLoop *l) ATTR_NONNULL();
+void bmesh_radial_loop_remove(BMEdge *e, BMLoop *l) ATTR_NONNULL();
+void bmesh_radial_loop_unlink(BMLoop *l) ATTR_NONNULL();
/* note:
* bmesh_radial_loop_next(BMLoop *l) / prev.
* just use member access l->radial_next, l->radial_prev now */
-int bmesh_radial_facevert_count_at_most(const BMLoop *l, const BMVert *v, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool bmesh_radial_facevert_check(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BMLoop *bmesh_radial_faceloop_find_next(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-BMLoop *bmesh_radial_faceloop_find_vert(const BMFace *f, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool bmesh_radial_validate(int radlen, BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+int bmesh_radial_facevert_count_at_most(const BMLoop *l,
+ const BMVert *v,
+ const int count_max) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+bool bmesh_radial_facevert_check(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+BMLoop *bmesh_radial_faceloop_find_next(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+BMLoop *bmesh_radial_faceloop_find_vert(const BMFace *f, const BMVert *v) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+bool bmesh_radial_validate(int radlen, BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/* EDGE UTILITIES */
-void bmesh_disk_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src) ATTR_NONNULL();
-void bmesh_edge_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src) ATTR_NONNULL();
-void bmesh_disk_vert_replace(BMEdge *e, BMVert *v_dst, BMVert *v_src) ATTR_NONNULL();
-BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void bmesh_disk_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src) ATTR_NONNULL();
+void bmesh_edge_vert_swap(BMEdge *e, BMVert *v_dst, BMVert *v_src) ATTR_NONNULL();
+void bmesh_disk_vert_replace(BMEdge *e, BMVert *v_dst, BMVert *v_src) ATTR_NONNULL();
+BMEdge *bmesh_disk_edge_exists(const BMVert *v1, const BMVert *v2) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL();
+bool bmesh_disk_validate(int len, BMEdge *e, BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
#include "intern/bmesh_structure_inline.h"
diff --git a/source/blender/bmesh/intern/bmesh_structure_inline.h b/source/blender/bmesh/intern/bmesh_structure_inline.h
index 0998d9bd907..26d161693af 100644
--- a/source/blender/bmesh/intern/bmesh_structure_inline.h
+++ b/source/blender/bmesh/intern/bmesh_structure_inline.h
@@ -24,10 +24,10 @@
#define __BMESH_STRUCTURE_INLINE_H__
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
-BLI_INLINE BMDiskLink *bmesh_disk_edge_link_from_vert(const BMEdge *e, const BMVert *v)
+ BLI_INLINE BMDiskLink *bmesh_disk_edge_link_from_vert(const BMEdge *e, const BMVert *v)
{
- BLI_assert(BM_vert_in_edge(e, v));
- return (BMDiskLink *)&(&e->v1_disk_link)[v == e->v2];
+ BLI_assert(BM_vert_in_edge(e, v));
+ return (BMDiskLink *)&(&e->v1_disk_link)[v == e->v2];
}
/**
@@ -38,39 +38,39 @@ BLI_INLINE BMDiskLink *bmesh_disk_edge_link_from_vert(const BMEdge *e, const BMV
* \return Pointer to the next edge in the disk cycle for the vertex v.
*/
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE BMEdge *bmesh_disk_edge_next_safe(const BMEdge *e, const BMVert *v)
+ BLI_INLINE BMEdge *bmesh_disk_edge_next_safe(const BMEdge *e, const BMVert *v)
{
- if (v == e->v1) {
- return e->v1_disk_link.next;
- }
- if (v == e->v2) {
- return e->v2_disk_link.next;
- }
- return NULL;
+ if (v == e->v1) {
+ return e->v1_disk_link.next;
+ }
+ if (v == e->v2) {
+ return e->v2_disk_link.next;
+ }
+ return NULL;
}
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
-BLI_INLINE BMEdge *bmesh_disk_edge_prev_safe(const BMEdge *e, const BMVert *v)
+ BLI_INLINE BMEdge *bmesh_disk_edge_prev_safe(const BMEdge *e, const BMVert *v)
{
- if (v == e->v1) {
- return e->v1_disk_link.prev;
- }
- if (v == e->v2) {
- return e->v2_disk_link.prev;
- }
- return NULL;
+ if (v == e->v1) {
+ return e->v1_disk_link.prev;
+ }
+ if (v == e->v2) {
+ return e->v2_disk_link.prev;
+ }
+ return NULL;
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
-BLI_INLINE BMEdge *bmesh_disk_edge_next(const BMEdge *e, const BMVert *v)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE BMEdge *bmesh_disk_edge_next(const BMEdge *e,
+ const BMVert *v)
{
- return BM_DISK_EDGE_NEXT(e, v);
+ return BM_DISK_EDGE_NEXT(e, v);
}
-ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
-BLI_INLINE BMEdge *bmesh_disk_edge_prev(const BMEdge *e, const BMVert *v)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE BMEdge *bmesh_disk_edge_prev(const BMEdge *e,
+ const BMVert *v)
{
- return BM_DISK_EDGE_PREV(e, v);
+ return BM_DISK_EDGE_PREV(e, v);
}
#endif /* __BMESH_STRUCTURE_INLINE_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_walkers.c b/source/blender/bmesh/intern/bmesh_walkers.c
index 011addc9220..b850c87d5aa 100644
--- a/source/blender/bmesh/intern/bmesh_walkers.c
+++ b/source/blender/bmesh/intern/bmesh_walkers.c
@@ -54,11 +54,11 @@
void *BMW_begin(BMWalker *walker, void *start)
{
- BLI_assert(((BMHeader *)start)->htype & walker->begin_htype);
+ BLI_assert(((BMHeader *)start)->htype & walker->begin_htype);
- walker->begin(walker, start);
+ walker->begin(walker, start);
- return BMW_current_state(walker) ? walker->step(walker) : NULL;
+ return BMW_current_state(walker) ? walker->step(walker) : NULL;
}
/**
@@ -68,53 +68,62 @@ void *BMW_begin(BMWalker *walker, void *start)
* a given type. The elements visited are filtered
* by the bitmask 'searchmask'.
*/
-void BMW_init(
- BMWalker *walker, BMesh *bm, int type,
- short mask_vert, short mask_edge, short mask_face,
- BMWFlag flag,
- int layer)
+void BMW_init(BMWalker *walker,
+ BMesh *bm,
+ int type,
+ short mask_vert,
+ short mask_edge,
+ short mask_face,
+ BMWFlag flag,
+ int layer)
{
- memset(walker, 0, sizeof(BMWalker));
+ memset(walker, 0, sizeof(BMWalker));
- walker->layer = layer;
- walker->flag = flag;
- walker->bm = bm;
+ walker->layer = layer;
+ walker->flag = flag;
+ walker->bm = bm;
- walker->mask_vert = mask_vert;
- walker->mask_edge = mask_edge;
- walker->mask_face = mask_face;
+ walker->mask_vert = mask_vert;
+ walker->mask_edge = mask_edge;
+ walker->mask_face = mask_face;
- walker->visit_set = BLI_gset_ptr_new("bmesh walkers");
- walker->visit_set_alt = BLI_gset_ptr_new("bmesh walkers sec");
+ walker->visit_set = BLI_gset_ptr_new("bmesh walkers");
+ walker->visit_set_alt = BLI_gset_ptr_new("bmesh walkers sec");
- if (UNLIKELY(type >= BMW_MAXWALKERS || type < 0)) {
- fprintf(stderr,
- "%s: Invalid walker type in BMW_init; type: %d, "
- "searchmask: (v:%d, e:%d, f:%d), flag: %u, layer: %d\n",
- __func__, type, mask_vert, mask_edge, mask_face, flag, layer);
- BLI_assert(0);
- return;
- }
+ if (UNLIKELY(type >= BMW_MAXWALKERS || type < 0)) {
+ fprintf(stderr,
+ "%s: Invalid walker type in BMW_init; type: %d, "
+ "searchmask: (v:%d, e:%d, f:%d), flag: %u, layer: %d\n",
+ __func__,
+ type,
+ mask_vert,
+ mask_edge,
+ mask_face,
+ flag,
+ layer);
+ BLI_assert(0);
+ return;
+ }
- if (type != BMW_CUSTOM) {
- walker->begin_htype = bm_walker_types[type]->begin_htype;
- walker->begin = bm_walker_types[type]->begin;
- walker->yield = bm_walker_types[type]->yield;
- walker->step = bm_walker_types[type]->step;
- walker->structsize = bm_walker_types[type]->structsize;
- walker->order = bm_walker_types[type]->order;
- walker->valid_mask = bm_walker_types[type]->valid_mask;
+ if (type != BMW_CUSTOM) {
+ walker->begin_htype = bm_walker_types[type]->begin_htype;
+ walker->begin = bm_walker_types[type]->begin;
+ walker->yield = bm_walker_types[type]->yield;
+ walker->step = bm_walker_types[type]->step;
+ walker->structsize = bm_walker_types[type]->structsize;
+ walker->order = bm_walker_types[type]->order;
+ walker->valid_mask = bm_walker_types[type]->valid_mask;
- /* safety checks */
- /* if this raises an error either the caller is wrong or
- * 'bm_walker_types' needs updating */
- BLI_assert(mask_vert == 0 || (walker->valid_mask & BM_VERT));
- BLI_assert(mask_edge == 0 || (walker->valid_mask & BM_EDGE));
- BLI_assert(mask_face == 0 || (walker->valid_mask & BM_FACE));
- }
+ /* safety checks */
+ /* if this raises an error either the caller is wrong or
+ * 'bm_walker_types' needs updating */
+ BLI_assert(mask_vert == 0 || (walker->valid_mask & BM_VERT));
+ BLI_assert(mask_edge == 0 || (walker->valid_mask & BM_EDGE));
+ BLI_assert(mask_face == 0 || (walker->valid_mask & BM_FACE));
+ }
- walker->worklist = BLI_mempool_create(walker->structsize, 0, 128, BLI_MEMPOOL_NOP);
- BLI_listbase_clear(&walker->states);
+ walker->worklist = BLI_mempool_create(walker->structsize, 0, 128, BLI_MEMPOOL_NOP);
+ BLI_listbase_clear(&walker->states);
}
/**
@@ -124,22 +133,21 @@ void BMW_init(
*/
void BMW_end(BMWalker *walker)
{
- BLI_mempool_destroy(walker->worklist);
- BLI_gset_free(walker->visit_set, NULL);
- BLI_gset_free(walker->visit_set_alt, NULL);
+ BLI_mempool_destroy(walker->worklist);
+ BLI_gset_free(walker->visit_set, NULL);
+ BLI_gset_free(walker->visit_set_alt, NULL);
}
-
/**
* \brief Step Walker
*/
void *BMW_step(BMWalker *walker)
{
- BMHeader *head;
+ BMHeader *head;
- head = BMW_walk(walker);
+ head = BMW_walk(walker);
- return head;
+ return head;
}
/**
@@ -150,7 +158,7 @@ void *BMW_step(BMWalker *walker)
int BMW_current_depth(BMWalker *walker)
{
- return walker->depth;
+ return walker->depth;
}
/**
@@ -160,15 +168,15 @@ int BMW_current_depth(BMWalker *walker)
*/
void *BMW_walk(BMWalker *walker)
{
- void *current = NULL;
+ void *current = NULL;
- while (BMW_current_state(walker)) {
- current = walker->step(walker);
- if (current) {
- return current;
- }
- }
- return NULL;
+ while (BMW_current_state(walker)) {
+ current = walker->step(walker);
+ if (current) {
+ return current;
+ }
+ }
+ return NULL;
}
/**
@@ -180,21 +188,21 @@ void *BMW_walk(BMWalker *walker)
*/
void *BMW_current_state(BMWalker *walker)
{
- BMwGenericWalker *currentstate = walker->states.first;
- if (currentstate) {
- /* Automatic update of depth. For most walkers that
- * follow the standard "Step" pattern of:
- * - read current state
- * - remove current state
- * - push new states
- * - return walk result from just-removed current state
- * this simple automatic update should keep track of depth
- * just fine. Walkers that deviate from that pattern may
- * need to manually update the depth if they care about
- * keeping it correct. */
- walker->depth = currentstate->depth + 1;
- }
- return currentstate;
+ BMwGenericWalker *currentstate = walker->states.first;
+ if (currentstate) {
+ /* Automatic update of depth. For most walkers that
+ * follow the standard "Step" pattern of:
+ * - read current state
+ * - remove current state
+ * - push new states
+ * - return walk result from just-removed current state
+ * this simple automatic update should keep track of depth
+ * just fine. Walkers that deviate from that pattern may
+ * need to manually update the depth if they care about
+ * keeping it correct. */
+ walker->depth = currentstate->depth + 1;
+ }
+ return currentstate;
}
/**
@@ -205,10 +213,10 @@ void *BMW_current_state(BMWalker *walker)
*/
void BMW_state_remove(BMWalker *walker)
{
- void *oldstate;
- oldstate = BMW_current_state(walker);
- BLI_remlink(&walker->states, oldstate);
- BLI_mempool_free(walker->worklist, oldstate);
+ void *oldstate;
+ oldstate = BMW_current_state(walker);
+ BLI_remlink(&walker->states, oldstate);
+ BLI_mempool_free(walker->worklist, oldstate);
}
/**
@@ -222,21 +230,21 @@ void BMW_state_remove(BMWalker *walker)
*/
void *BMW_state_add(BMWalker *walker)
{
- BMwGenericWalker *newstate;
- newstate = BLI_mempool_alloc(walker->worklist);
- newstate->depth = walker->depth;
- switch (walker->order) {
- case BMW_DEPTH_FIRST:
- BLI_addhead(&walker->states, newstate);
- break;
- case BMW_BREADTH_FIRST:
- BLI_addtail(&walker->states, newstate);
- break;
- default:
- BLI_assert(0);
- break;
- }
- return newstate;
+ BMwGenericWalker *newstate;
+ newstate = BLI_mempool_alloc(walker->worklist);
+ newstate->depth = walker->depth;
+ switch (walker->order) {
+ case BMW_DEPTH_FIRST:
+ BLI_addhead(&walker->states, newstate);
+ break;
+ case BMW_BREADTH_FIRST:
+ BLI_addtail(&walker->states, newstate);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+ return newstate;
}
/**
@@ -247,10 +255,10 @@ void *BMW_state_add(BMWalker *walker)
*/
void BMW_reset(BMWalker *walker)
{
- while (BMW_current_state(walker)) {
- BMW_state_remove(walker);
- }
- walker->depth = 0;
- BLI_gset_clear(walker->visit_set, NULL);
- BLI_gset_clear(walker->visit_set_alt, NULL);
+ while (BMW_current_state(walker)) {
+ BMW_state_remove(walker);
+ }
+ walker->depth = 0;
+ BLI_gset_clear(walker->visit_set, NULL);
+ BLI_gset_clear(walker->visit_set_alt, NULL);
}
diff --git a/source/blender/bmesh/intern/bmesh_walkers.h b/source/blender/bmesh/intern/bmesh_walkers.h
index 3de7d6d2c90..54cfccb9ed8 100644
--- a/source/blender/bmesh/intern/bmesh_walkers.h
+++ b/source/blender/bmesh/intern/bmesh_walkers.h
@@ -26,43 +26,43 @@
*/
typedef enum {
- BMW_DEPTH_FIRST,
- BMW_BREADTH_FIRST,
+ BMW_DEPTH_FIRST,
+ BMW_BREADTH_FIRST,
} BMWOrder;
typedef enum {
- BMW_FLAG_NOP = 0,
- BMW_FLAG_TEST_HIDDEN = (1 << 0),
+ BMW_FLAG_NOP = 0,
+ BMW_FLAG_TEST_HIDDEN = (1 << 0),
} BMWFlag;
/*Walkers*/
typedef struct BMWalker {
- char begin_htype; /* only for validating input */
- void (*begin) (struct BMWalker *walker, void *start);
- void *(*step) (struct BMWalker *walker);
- void *(*yield) (struct BMWalker *walker);
- int structsize;
- BMWOrder order;
- int valid_mask;
-
- /* runtime */
- int layer;
-
- BMesh *bm;
- BLI_mempool *worklist;
- ListBase states;
-
- /* these masks are to be tested against elements BMO_elem_flag_test(),
- * should never be accessed directly only through BMW_init() and bmw_mask_check_*() functions */
- short mask_vert;
- short mask_edge;
- short mask_face;
-
- BMWFlag flag;
-
- struct GSet *visit_set;
- struct GSet *visit_set_alt;
- int depth;
+ char begin_htype; /* only for validating input */
+ void (*begin)(struct BMWalker *walker, void *start);
+ void *(*step)(struct BMWalker *walker);
+ void *(*yield)(struct BMWalker *walker);
+ int structsize;
+ BMWOrder order;
+ int valid_mask;
+
+ /* runtime */
+ int layer;
+
+ BMesh *bm;
+ BLI_mempool *worklist;
+ ListBase states;
+
+ /* these masks are to be tested against elements BMO_elem_flag_test(),
+ * should never be accessed directly only through BMW_init() and bmw_mask_check_*() functions */
+ short mask_vert;
+ short mask_edge;
+ short mask_face;
+
+ BMWFlag flag;
+
+ struct GSet *visit_set;
+ struct GSet *visit_set_alt;
+ int depth;
} BMWalker;
/* define to make BMW_init more clear */
@@ -70,27 +70,29 @@ typedef struct BMWalker {
/* initialize a walker. searchmask restricts some (not all) walkers to
* elements with a specific tool flag set. flags is specific to each walker.*/
-void BMW_init(
- struct BMWalker *walker, BMesh *bm, int type,
- short mask_vert, short mask_edge, short mask_face,
- BMWFlag flag,
- int layer);
+void BMW_init(struct BMWalker *walker,
+ BMesh *bm,
+ int type,
+ short mask_vert,
+ short mask_edge,
+ short mask_face,
+ BMWFlag flag,
+ int layer);
void *BMW_begin(BMWalker *walker, void *start);
void *BMW_step(struct BMWalker *walker);
-void BMW_end(struct BMWalker *walker);
-int BMW_current_depth(BMWalker *walker);
+void BMW_end(struct BMWalker *walker);
+int BMW_current_depth(BMWalker *walker);
/*these are used by custom walkers*/
void *BMW_current_state(BMWalker *walker);
void *BMW_state_add(BMWalker *walker);
-void BMW_state_remove(BMWalker *walker);
+void BMW_state_remove(BMWalker *walker);
void *BMW_walk(BMWalker *walker);
-void BMW_reset(BMWalker *walker);
+void BMW_reset(BMWalker *walker);
#define BMW_ITER(ele, walker, data) \
- for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMW_begin(walker, (BM_CHECK_TYPE_ELEM(data), data)); \
- ele; \
- BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMW_step(walker))
+ for (BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMW_begin(walker, (BM_CHECK_TYPE_ELEM(data), data)); ele; \
+ BM_CHECK_TYPE_ELEM_ASSIGN(ele) = BMW_step(walker))
/*
* example of usage, walking over an island of tool flagged faces:
@@ -107,28 +109,28 @@ void BMW_reset(BMWalker *walker);
*/
enum {
- BMW_VERT_SHELL,
- BMW_LOOP_SHELL,
- BMW_LOOP_SHELL_WIRE,
- BMW_FACE_SHELL,
- BMW_EDGELOOP,
- BMW_FACELOOP,
- BMW_EDGERING,
- BMW_EDGEBOUNDARY,
- /* BMW_RING, */
- BMW_LOOPDATA_ISLAND,
- BMW_ISLANDBOUND,
- BMW_ISLAND,
- BMW_ISLAND_MANIFOLD,
- BMW_CONNECTED_VERTEX,
- /* end of array index enum vals */
-
- /* do not intitialze function pointers and struct size in BMW_init */
- BMW_CUSTOM,
- BMW_MAXWALKERS,
+ BMW_VERT_SHELL,
+ BMW_LOOP_SHELL,
+ BMW_LOOP_SHELL_WIRE,
+ BMW_FACE_SHELL,
+ BMW_EDGELOOP,
+ BMW_FACELOOP,
+ BMW_EDGERING,
+ BMW_EDGEBOUNDARY,
+ /* BMW_RING, */
+ BMW_LOOPDATA_ISLAND,
+ BMW_ISLANDBOUND,
+ BMW_ISLAND,
+ BMW_ISLAND_MANIFOLD,
+ BMW_CONNECTED_VERTEX,
+ /* end of array index enum vals */
+
+ /* do not intitialze function pointers and struct size in BMW_init */
+ BMW_CUSTOM,
+ BMW_MAXWALKERS,
};
/* use with BMW_init, so as not to confuse with restrict flags */
-#define BMW_NIL_LAY 0
+#define BMW_NIL_LAY 0
#endif /* __BMESH_WALKERS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c
index 0ac9b958c11..c327c10226f 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_impl.c
+++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c
@@ -30,56 +30,57 @@
#include "intern/bmesh_walkers_private.h"
/* pop into stack memory (common operation) */
-#define BMW_state_remove_r(walker, owalk) { \
- memcpy(owalk, BMW_current_state(walker), sizeof(*(owalk))); \
- BMW_state_remove(walker); \
-} (void)0
+#define BMW_state_remove_r(walker, owalk) \
+ { \
+ memcpy(owalk, BMW_current_state(walker), sizeof(*(owalk))); \
+ BMW_state_remove(walker); \
+ } \
+ (void)0
/** \name Mask Flag Checks
* \{ */
static bool bmw_mask_check_vert(BMWalker *walker, BMVert *v)
{
- if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- return false;
- }
- else if (walker->mask_vert && !BMO_vert_flag_test(walker->bm, v, walker->mask_vert)) {
- return false;
- }
- else {
- return true;
- }
+ if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
+ return false;
+ }
+ else if (walker->mask_vert && !BMO_vert_flag_test(walker->bm, v, walker->mask_vert)) {
+ return false;
+ }
+ else {
+ return true;
+ }
}
static bool bmw_mask_check_edge(BMWalker *walker, BMEdge *e)
{
- if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
- return false;
- }
- else if (walker->mask_edge && !BMO_edge_flag_test(walker->bm, e, walker->mask_edge)) {
- return false;
- }
- else {
- return true;
- }
+ if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(e, BM_ELEM_HIDDEN)) {
+ return false;
+ }
+ else if (walker->mask_edge && !BMO_edge_flag_test(walker->bm, e, walker->mask_edge)) {
+ return false;
+ }
+ else {
+ return true;
+ }
}
static bool bmw_mask_check_face(BMWalker *walker, BMFace *f)
{
- if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
- return false;
- }
- else if (walker->mask_face && !BMO_face_flag_test(walker->bm, f, walker->mask_face)) {
- return false;
- }
- else {
- return true;
- }
+ if ((walker->flag & BMW_FLAG_TEST_HIDDEN) && BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
+ return false;
+ }
+ else if (walker->mask_face && !BMO_face_flag_test(walker->bm, f, walker->mask_face)) {
+ return false;
+ }
+ else {
+ return true;
+ }
}
/** \} */
-
/** \name BMesh Queries (modified to check walker flags)
* \{ */
@@ -88,22 +89,21 @@ static bool bmw_mask_check_face(BMWalker *walker, BMFace *f)
*/
static bool bmw_edge_is_wire(const BMWalker *walker, const BMEdge *e)
{
- if (walker->flag & BMW_FLAG_TEST_HIDDEN) {
- /* check if this is a wire edge, ignoring hidden faces */
- if (BM_edge_is_wire(e)) {
- return true;
- }
- else {
- return BM_edge_is_all_face_flag_test(e, BM_ELEM_HIDDEN, false);
- }
- }
- else {
- return BM_edge_is_wire(e);
- }
+ if (walker->flag & BMW_FLAG_TEST_HIDDEN) {
+ /* check if this is a wire edge, ignoring hidden faces */
+ if (BM_edge_is_wire(e)) {
+ return true;
+ }
+ else {
+ return BM_edge_is_all_face_flag_test(e, BM_ELEM_HIDDEN, false);
+ }
+ }
+ else {
+ return BM_edge_is_wire(e);
+ }
}
/** \} */
-
/** \name Shell Walker
* \{
*
@@ -117,125 +117,123 @@ static bool bmw_edge_is_wire(const BMWalker *walker, const BMEdge *e)
*/
static void bmw_VertShellWalker_visitEdge(BMWalker *walker, BMEdge *e)
{
- BMwShellWalker *shellWalk = NULL;
+ BMwShellWalker *shellWalk = NULL;
- if (BLI_gset_haskey(walker->visit_set, e)) {
- return;
- }
+ if (BLI_gset_haskey(walker->visit_set, e)) {
+ return;
+ }
- if (!bmw_mask_check_edge(walker, e)) {
- return;
- }
+ if (!bmw_mask_check_edge(walker, e)) {
+ return;
+ }
- shellWalk = BMW_state_add(walker);
- shellWalk->curedge = e;
- BLI_gset_insert(walker->visit_set, e);
+ shellWalk = BMW_state_add(walker);
+ shellWalk->curedge = e;
+ BLI_gset_insert(walker->visit_set, e);
}
static void bmw_VertShellWalker_begin(BMWalker *walker, void *data)
{
- BMIter eiter;
- BMHeader *h = data;
- BMEdge *e;
- BMVert *v;
-
- if (UNLIKELY(h == NULL)) {
- return;
- }
-
- switch (h->htype) {
- case BM_VERT:
- {
- /* starting the walk at a vert, add all the edges
- * to the worklist */
- v = (BMVert *)h;
- BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- bmw_VertShellWalker_visitEdge(walker, e);
- }
- break;
- }
-
- case BM_EDGE:
- {
- /* starting the walk at an edge, add the single edge
- * to the worklist */
- e = (BMEdge *)h;
- bmw_VertShellWalker_visitEdge(walker, e);
- break;
- }
- default:
- BLI_assert(0);
- }
+ BMIter eiter;
+ BMHeader *h = data;
+ BMEdge *e;
+ BMVert *v;
+
+ if (UNLIKELY(h == NULL)) {
+ return;
+ }
+
+ switch (h->htype) {
+ case BM_VERT: {
+ /* starting the walk at a vert, add all the edges
+ * to the worklist */
+ v = (BMVert *)h;
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ bmw_VertShellWalker_visitEdge(walker, e);
+ }
+ break;
+ }
+
+ case BM_EDGE: {
+ /* starting the walk at an edge, add the single edge
+ * to the worklist */
+ e = (BMEdge *)h;
+ bmw_VertShellWalker_visitEdge(walker, e);
+ break;
+ }
+ default:
+ BLI_assert(0);
+ }
}
static void *bmw_VertShellWalker_yield(BMWalker *walker)
{
- BMwShellWalker *shellWalk = BMW_current_state(walker);
- return shellWalk->curedge;
+ BMwShellWalker *shellWalk = BMW_current_state(walker);
+ return shellWalk->curedge;
}
static void *bmw_VertShellWalker_step(BMWalker *walker)
{
- BMwShellWalker *swalk, owalk;
- BMEdge *e, *e2;
- BMVert *v;
- BMIter iter;
- int i;
+ BMwShellWalker *swalk, owalk;
+ BMEdge *e, *e2;
+ BMVert *v;
+ BMIter iter;
+ int i;
- BMW_state_remove_r(walker, &owalk);
- swalk = &owalk;
+ BMW_state_remove_r(walker, &owalk);
+ swalk = &owalk;
- e = swalk->curedge;
+ e = swalk->curedge;
- for (i = 0; i < 2; i++) {
- v = i ? e->v2 : e->v1;
- BM_ITER_ELEM (e2, &iter, v, BM_EDGES_OF_VERT) {
- bmw_VertShellWalker_visitEdge(walker, e2);
- }
- }
+ for (i = 0; i < 2; i++) {
+ v = i ? e->v2 : e->v1;
+ BM_ITER_ELEM (e2, &iter, v, BM_EDGES_OF_VERT) {
+ bmw_VertShellWalker_visitEdge(walker, e2);
+ }
+ }
- return e;
+ return e;
}
#if 0
static void *bmw_VertShellWalker_step(BMWalker *walker)
{
- BMEdge *curedge, *next = NULL;
- BMVert *v_old = NULL;
- bool restrictpass = true;
- BMwShellWalker shellWalk = *((BMwShellWalker *)BMW_current_state(walker));
+ BMEdge *curedge, *next = NULL;
+ BMVert *v_old = NULL;
+ bool restrictpass = true;
+ BMwShellWalker shellWalk = *((BMwShellWalker *)BMW_current_state(walker));
- if (!BLI_gset_haskey(walker->visit_set, shellWalk.base)) {
- BLI_gset_insert(walker->visit_set, shellWalk.base);
- }
+ if (!BLI_gset_haskey(walker->visit_set, shellWalk.base)) {
+ BLI_gset_insert(walker->visit_set, shellWalk.base);
+ }
- BMW_state_remove(walker);
+ BMW_state_remove(walker);
- /* find the next edge whose other vertex has not been visite */
- curedge = shellWalk.curedge;
- do {
- if (!BLI_gset_haskey(walker->visit_set, curedge)) {
- if (!walker->restrictflag ||
- (walker->restrictflag && BMO_edge_flag_test(walker->bm, curedge, walker->restrictflag)))
- {
- BMwShellWalker *newstate;
+ /* find the next edge whose other vertex has not been visite */
+ curedge = shellWalk.curedge;
+ do {
+ if (!BLI_gset_haskey(walker->visit_set, curedge)) {
+ if (!walker->restrictflag ||
+ (walker->restrictflag && BMO_edge_flag_test(walker->bm, curedge, walker->restrictflag)))
+ {
+ BMwShellWalker *newstate;
- v_old = 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);
- BLI_gset_insert(walker->visit_set, curedge);
+ /* push a new state onto the stac */
+ newState = BMW_state_add(walker);
+ BLI_gset_insert(walker->visit_set, curedge);
- /* populate the new stat */
+ /* populate the new stat */
- newState->base = v_old;
- newState->curedge = curedge;
- }
- }
- } while ((curedge = bmesh_disk_edge_next(curedge, shellWalk.base)) != shellWalk.curedge);
+ newState->base = v_old;
+ newState->curedge = curedge;
+ }
+ }
+ } while ((curedge = bmesh_disk_edge_next(curedge, shellWalk.base)) != shellWalk.curedge);
- return shellWalk.curedge;
+ return shellWalk.curedge;
}
#endif
@@ -251,120 +249,116 @@ static void *bmw_VertShellWalker_step(BMWalker *walker)
*/
static void bmw_LoopShellWalker_visitLoop(BMWalker *walker, BMLoop *l)
{
- BMwLoopShellWalker *shellWalk = NULL;
+ BMwLoopShellWalker *shellWalk = NULL;
- if (BLI_gset_haskey(walker->visit_set, l)) {
- return;
- }
+ if (BLI_gset_haskey(walker->visit_set, l)) {
+ return;
+ }
- if (!bmw_mask_check_face(walker, l->f)) {
- return;
- }
+ if (!bmw_mask_check_face(walker, l->f)) {
+ return;
+ }
- shellWalk = BMW_state_add(walker);
- shellWalk->curloop = l;
- BLI_gset_insert(walker->visit_set, l);
+ shellWalk = BMW_state_add(walker);
+ shellWalk->curloop = l;
+ BLI_gset_insert(walker->visit_set, l);
}
static void bmw_LoopShellWalker_begin(BMWalker *walker, void *data)
{
- BMIter iter;
- BMHeader *h = data;
-
- if (UNLIKELY(h == NULL)) {
- return;
- }
-
- switch (h->htype) {
- case BM_LOOP:
- {
- /* starting the walk at a vert, add all the edges
- * to the worklist */
- BMLoop *l = (BMLoop *)h;
- bmw_LoopShellWalker_visitLoop(walker, l);
- break;
- }
-
- case BM_VERT:
- {
- BMVert *v = (BMVert *)h;
- BMLoop *l;
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- bmw_LoopShellWalker_visitLoop(walker, l);
- }
- break;
- }
- case BM_EDGE:
- {
- BMEdge *e = (BMEdge *)h;
- BMLoop *l;
- BM_ITER_ELEM (l, &iter, e, BM_LOOPS_OF_EDGE) {
- bmw_LoopShellWalker_visitLoop(walker, l);
- }
- break;
- }
- case BM_FACE:
- {
- BMFace *f = (BMFace *)h;
- BMLoop *l = BM_FACE_FIRST_LOOP(f);
- /* walker will handle other loops within the face */
- bmw_LoopShellWalker_visitLoop(walker, l);
- break;
- }
- default:
- BLI_assert(0);
- }
+ BMIter iter;
+ BMHeader *h = data;
+
+ if (UNLIKELY(h == NULL)) {
+ return;
+ }
+
+ switch (h->htype) {
+ case BM_LOOP: {
+ /* starting the walk at a vert, add all the edges
+ * to the worklist */
+ BMLoop *l = (BMLoop *)h;
+ bmw_LoopShellWalker_visitLoop(walker, l);
+ break;
+ }
+
+ case BM_VERT: {
+ BMVert *v = (BMVert *)h;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+ bmw_LoopShellWalker_visitLoop(walker, l);
+ }
+ break;
+ }
+ case BM_EDGE: {
+ BMEdge *e = (BMEdge *)h;
+ BMLoop *l;
+ BM_ITER_ELEM (l, &iter, e, BM_LOOPS_OF_EDGE) {
+ bmw_LoopShellWalker_visitLoop(walker, l);
+ }
+ break;
+ }
+ case BM_FACE: {
+ BMFace *f = (BMFace *)h;
+ BMLoop *l = BM_FACE_FIRST_LOOP(f);
+ /* walker will handle other loops within the face */
+ bmw_LoopShellWalker_visitLoop(walker, l);
+ break;
+ }
+ default:
+ BLI_assert(0);
+ }
}
static void *bmw_LoopShellWalker_yield(BMWalker *walker)
{
- BMwLoopShellWalker *shellWalk = BMW_current_state(walker);
- return shellWalk->curloop;
+ BMwLoopShellWalker *shellWalk = BMW_current_state(walker);
+ return shellWalk->curloop;
}
static void bmw_LoopShellWalker_step_impl(BMWalker *walker, BMLoop *l)
{
- BMEdge *e_edj_pair[2];
- int i;
-
- /* seems paranoid, but one caller also walks edges */
- BLI_assert(l->head.htype == BM_LOOP);
-
- bmw_LoopShellWalker_visitLoop(walker, l->next);
- bmw_LoopShellWalker_visitLoop(walker, l->prev);
-
- e_edj_pair[0] = l->e;
- e_edj_pair[1] = l->prev->e;
-
- for (i = 0; i < 2; i++) {
- BMEdge *e = e_edj_pair[i];
- if (bmw_mask_check_edge(walker, e)) {
- BMLoop *l_iter, *l_first;
-
- l_iter = l_first = e->l;
- do {
- BMLoop *l_radial = (l_iter->v == l->v) ? l_iter : l_iter->next;
- BLI_assert(l_radial->v == l->v);
- if (l != l_radial) {
- bmw_LoopShellWalker_visitLoop(walker, l_radial);
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
- }
+ BMEdge *e_edj_pair[2];
+ int i;
+
+ /* seems paranoid, but one caller also walks edges */
+ BLI_assert(l->head.htype == BM_LOOP);
+
+ bmw_LoopShellWalker_visitLoop(walker, l->next);
+ bmw_LoopShellWalker_visitLoop(walker, l->prev);
+
+ e_edj_pair[0] = l->e;
+ e_edj_pair[1] = l->prev->e;
+
+ for (i = 0; i < 2; i++) {
+ BMEdge *e = e_edj_pair[i];
+ if (bmw_mask_check_edge(walker, e)) {
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = e->l;
+ do {
+ BMLoop *l_radial = (l_iter->v == l->v) ? l_iter : l_iter->next;
+ BLI_assert(l_radial->v == l->v);
+ if (l != l_radial) {
+ bmw_LoopShellWalker_visitLoop(walker, l_radial);
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ }
}
static void *bmw_LoopShellWalker_step(BMWalker *walker)
{
- BMwLoopShellWalker *swalk, owalk;
- BMLoop *l;
+ BMwLoopShellWalker *swalk, owalk;
+ BMLoop *l;
- BMW_state_remove_r(walker, &owalk);
- swalk = &owalk;
+ BMW_state_remove_r(walker, &owalk);
+ swalk = &owalk;
- l = swalk->curloop;
- bmw_LoopShellWalker_step_impl(walker, l);
+ l = swalk->curloop;
+ bmw_LoopShellWalker_step_impl(walker, l);
- return l;
+ return l;
}
/** \} */
@@ -384,149 +378,144 @@ static void *bmw_LoopShellWalker_step(BMWalker *walker)
static void bmw_LoopShellWalker_visitEdgeWire(BMWalker *walker, BMEdge *e)
{
- BMwLoopShellWireWalker *shellWalk = NULL;
+ BMwLoopShellWireWalker *shellWalk = NULL;
- BLI_assert(bmw_edge_is_wire(walker, e));
+ BLI_assert(bmw_edge_is_wire(walker, e));
- if (BLI_gset_haskey(walker->visit_set_alt, e)) {
- return;
- }
+ if (BLI_gset_haskey(walker->visit_set_alt, e)) {
+ return;
+ }
- if (!bmw_mask_check_edge(walker, e)) {
- return;
- }
+ if (!bmw_mask_check_edge(walker, e)) {
+ return;
+ }
- shellWalk = BMW_state_add(walker);
- shellWalk->curelem = (BMElem *)e;
- BLI_gset_insert(walker->visit_set_alt, e);
+ shellWalk = BMW_state_add(walker);
+ shellWalk->curelem = (BMElem *)e;
+ BLI_gset_insert(walker->visit_set_alt, e);
}
static void bmw_LoopShellWireWalker_visitVert(BMWalker *walker, BMVert *v, const BMEdge *e_from)
{
- BMEdge *e;
+ BMEdge *e;
- BLI_assert(v->head.htype == BM_VERT);
+ BLI_assert(v->head.htype == BM_VERT);
- if (BLI_gset_haskey(walker->visit_set_alt, v)) {
- return;
- }
+ if (BLI_gset_haskey(walker->visit_set_alt, v)) {
+ return;
+ }
- if (!bmw_mask_check_vert(walker, v)) {
- return;
- }
+ if (!bmw_mask_check_vert(walker, v)) {
+ return;
+ }
- e = v->e;
- do {
- if (bmw_edge_is_wire(walker, e) && (e != e_from)) {
- BMVert *v_other;
- BMIter iter;
- BMLoop *l;
+ e = v->e;
+ do {
+ if (bmw_edge_is_wire(walker, e) && (e != e_from)) {
+ BMVert *v_other;
+ BMIter iter;
+ BMLoop *l;
- bmw_LoopShellWalker_visitEdgeWire(walker, e);
+ bmw_LoopShellWalker_visitEdgeWire(walker, e);
- /* check if we step onto a non-wire vertex */
- v_other = BM_edge_other_vert(e, v);
- BM_ITER_ELEM (l, &iter, v_other, BM_LOOPS_OF_VERT) {
+ /* check if we step onto a non-wire vertex */
+ v_other = BM_edge_other_vert(e, v);
+ BM_ITER_ELEM (l, &iter, v_other, BM_LOOPS_OF_VERT) {
- bmw_LoopShellWalker_visitLoop(walker, l);
- }
- }
- } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
+ bmw_LoopShellWalker_visitLoop(walker, l);
+ }
+ }
+ } while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
- BLI_gset_insert(walker->visit_set_alt, v);
+ BLI_gset_insert(walker->visit_set_alt, v);
}
static void bmw_LoopShellWireWalker_begin(BMWalker *walker, void *data)
{
- BMHeader *h = data;
-
- if (UNLIKELY(h == NULL)) {
- return;
- }
-
- bmw_LoopShellWalker_begin(walker, data);
-
- switch (h->htype) {
- case BM_LOOP:
- {
- BMLoop *l = (BMLoop *)h;
- bmw_LoopShellWireWalker_visitVert(walker, l->v, NULL);
- break;
- }
-
- case BM_VERT:
- {
- BMVert *v = (BMVert *)h;
- if (v->e) {
- bmw_LoopShellWireWalker_visitVert(walker, v, NULL);
- }
- break;
- }
- case BM_EDGE:
- {
- BMEdge *e = (BMEdge *)h;
- if (bmw_mask_check_edge(walker, e)) {
- bmw_LoopShellWireWalker_visitVert(walker, e->v1, NULL);
- bmw_LoopShellWireWalker_visitVert(walker, e->v2, NULL);
- }
- else if (e->l) {
- BMLoop *l_iter, *l_first;
-
- l_iter = l_first = e->l;
- do {
- bmw_LoopShellWalker_visitLoop(walker, l_iter);
- bmw_LoopShellWalker_visitLoop(walker, l_iter->next);
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
- break;
- }
- case BM_FACE:
- {
- /* wire verts will be walked over */
- break;
- }
- default:
- BLI_assert(0);
- }
+ BMHeader *h = data;
+
+ if (UNLIKELY(h == NULL)) {
+ return;
+ }
+
+ bmw_LoopShellWalker_begin(walker, data);
+
+ switch (h->htype) {
+ case BM_LOOP: {
+ BMLoop *l = (BMLoop *)h;
+ bmw_LoopShellWireWalker_visitVert(walker, l->v, NULL);
+ break;
+ }
+
+ case BM_VERT: {
+ BMVert *v = (BMVert *)h;
+ if (v->e) {
+ bmw_LoopShellWireWalker_visitVert(walker, v, NULL);
+ }
+ break;
+ }
+ case BM_EDGE: {
+ BMEdge *e = (BMEdge *)h;
+ if (bmw_mask_check_edge(walker, e)) {
+ bmw_LoopShellWireWalker_visitVert(walker, e->v1, NULL);
+ bmw_LoopShellWireWalker_visitVert(walker, e->v2, NULL);
+ }
+ else if (e->l) {
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = e->l;
+ do {
+ bmw_LoopShellWalker_visitLoop(walker, l_iter);
+ bmw_LoopShellWalker_visitLoop(walker, l_iter->next);
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
+ break;
+ }
+ case BM_FACE: {
+ /* wire verts will be walked over */
+ break;
+ }
+ default:
+ BLI_assert(0);
+ }
}
static void *bmw_LoopShellWireWalker_yield(BMWalker *walker)
{
- BMwLoopShellWireWalker *shellWalk = BMW_current_state(walker);
- return shellWalk->curelem;
+ BMwLoopShellWireWalker *shellWalk = BMW_current_state(walker);
+ return shellWalk->curelem;
}
static void *bmw_LoopShellWireWalker_step(BMWalker *walker)
{
- BMwLoopShellWireWalker *swalk, owalk;
+ BMwLoopShellWireWalker *swalk, owalk;
- BMW_state_remove_r(walker, &owalk);
- swalk = &owalk;
+ BMW_state_remove_r(walker, &owalk);
+ swalk = &owalk;
- if (swalk->curelem->head.htype == BM_LOOP) {
- BMLoop *l = (BMLoop *)swalk->curelem;
+ if (swalk->curelem->head.htype == BM_LOOP) {
+ BMLoop *l = (BMLoop *)swalk->curelem;
- bmw_LoopShellWalker_step_impl(walker, l);
+ bmw_LoopShellWalker_step_impl(walker, l);
- bmw_LoopShellWireWalker_visitVert(walker, l->v, NULL);
+ bmw_LoopShellWireWalker_visitVert(walker, l->v, NULL);
- return l;
- }
- else {
- BMEdge *e = (BMEdge *)swalk->curelem;
+ return l;
+ }
+ else {
+ BMEdge *e = (BMEdge *)swalk->curelem;
- BLI_assert(e->head.htype == BM_EDGE);
+ BLI_assert(e->head.htype == BM_EDGE);
- bmw_LoopShellWireWalker_visitVert(walker, e->v1, e);
- bmw_LoopShellWireWalker_visitVert(walker, e->v2, e);
+ bmw_LoopShellWireWalker_visitVert(walker, e->v1, e);
+ bmw_LoopShellWireWalker_visitVert(walker, e->v2, e);
- return e;
- }
+ return e;
+ }
}
/** \} */
-
/** \name FaceShell Walker
* \{
*
@@ -535,62 +524,61 @@ static void *bmw_LoopShellWireWalker_step(BMWalker *walker)
*/
static void bmw_FaceShellWalker_visitEdge(BMWalker *walker, BMEdge *e)
{
- BMwShellWalker *shellWalk = NULL;
+ BMwShellWalker *shellWalk = NULL;
- if (BLI_gset_haskey(walker->visit_set, e)) {
- return;
- }
+ if (BLI_gset_haskey(walker->visit_set, e)) {
+ return;
+ }
- if (!bmw_mask_check_edge(walker, e)) {
- return;
- }
+ if (!bmw_mask_check_edge(walker, e)) {
+ return;
+ }
- shellWalk = BMW_state_add(walker);
- shellWalk->curedge = e;
- BLI_gset_insert(walker->visit_set, e);
+ shellWalk = BMW_state_add(walker);
+ shellWalk->curedge = e;
+ BLI_gset_insert(walker->visit_set, e);
}
static void bmw_FaceShellWalker_begin(BMWalker *walker, void *data)
{
- BMEdge *e = data;
- bmw_FaceShellWalker_visitEdge(walker, e);
+ BMEdge *e = data;
+ bmw_FaceShellWalker_visitEdge(walker, e);
}
static void *bmw_FaceShellWalker_yield(BMWalker *walker)
{
- BMwShellWalker *shellWalk = BMW_current_state(walker);
- return shellWalk->curedge;
+ BMwShellWalker *shellWalk = BMW_current_state(walker);
+ return shellWalk->curedge;
}
static void *bmw_FaceShellWalker_step(BMWalker *walker)
{
- BMwShellWalker *swalk, owalk;
- BMEdge *e, *e2;
- BMIter iter;
+ BMwShellWalker *swalk, owalk;
+ BMEdge *e, *e2;
+ BMIter iter;
- BMW_state_remove_r(walker, &owalk);
- swalk = &owalk;
+ BMW_state_remove_r(walker, &owalk);
+ swalk = &owalk;
- e = swalk->curedge;
+ e = swalk->curedge;
- if (e->l) {
- BMLoop *l_iter, *l_first;
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
- l_iter = l_first = e->l;
- do {
- BM_ITER_ELEM (e2, &iter, l_iter->f, BM_EDGES_OF_FACE) {
- if (e2 != e) {
- bmw_FaceShellWalker_visitEdge(walker, e2);
- }
- }
- } while ((l_iter = l_iter->radial_next) != l_first);
- }
+ l_iter = l_first = e->l;
+ do {
+ BM_ITER_ELEM (e2, &iter, l_iter->f, BM_EDGES_OF_FACE) {
+ if (e2 != e) {
+ bmw_FaceShellWalker_visitEdge(walker, e2);
+ }
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
+ }
- return e;
+ return e;
}
/** \} */
-
/** \name Connected Vertex Walker
* \{
*
@@ -600,60 +588,59 @@ static void *bmw_FaceShellWalker_step(BMWalker *walker)
*/
static void bmw_ConnectedVertexWalker_visitVertex(BMWalker *walker, BMVert *v)
{
- BMwConnectedVertexWalker *vwalk;
+ BMwConnectedVertexWalker *vwalk;
- if (BLI_gset_haskey(walker->visit_set, v)) {
- /* already visited */
- return;
- }
+ if (BLI_gset_haskey(walker->visit_set, v)) {
+ /* already visited */
+ return;
+ }
- if (!bmw_mask_check_vert(walker, v)) {
- /* not flagged for walk */
- return;
- }
+ if (!bmw_mask_check_vert(walker, v)) {
+ /* not flagged for walk */
+ return;
+ }
- vwalk = BMW_state_add(walker);
- vwalk->curvert = v;
- BLI_gset_insert(walker->visit_set, v);
+ vwalk = BMW_state_add(walker);
+ vwalk->curvert = v;
+ BLI_gset_insert(walker->visit_set, v);
}
static void bmw_ConnectedVertexWalker_begin(BMWalker *walker, void *data)
{
- BMVert *v = data;
- bmw_ConnectedVertexWalker_visitVertex(walker, v);
+ BMVert *v = data;
+ bmw_ConnectedVertexWalker_visitVertex(walker, v);
}
static void *bmw_ConnectedVertexWalker_yield(BMWalker *walker)
{
- BMwConnectedVertexWalker *vwalk = BMW_current_state(walker);
- return vwalk->curvert;
+ BMwConnectedVertexWalker *vwalk = BMW_current_state(walker);
+ return vwalk->curvert;
}
static void *bmw_ConnectedVertexWalker_step(BMWalker *walker)
{
- BMwConnectedVertexWalker *vwalk, owalk;
- BMVert *v, *v2;
- BMEdge *e;
- BMIter iter;
+ BMwConnectedVertexWalker *vwalk, owalk;
+ BMVert *v, *v2;
+ BMEdge *e;
+ BMIter iter;
- BMW_state_remove_r(walker, &owalk);
- vwalk = &owalk;
+ BMW_state_remove_r(walker, &owalk);
+ vwalk = &owalk;
- v = vwalk->curvert;
+ v = vwalk->curvert;
- BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
- v2 = BM_edge_other_vert(e, v);
- if (!BLI_gset_haskey(walker->visit_set, v2)) {
- bmw_ConnectedVertexWalker_visitVertex(walker, v2);
- }
- }
+ BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
+ v2 = BM_edge_other_vert(e, v);
+ if (!BLI_gset_haskey(walker->visit_set, v2)) {
+ bmw_ConnectedVertexWalker_visitVertex(walker, v2);
+ }
+ }
- return v;
+ return v;
}
/** \} */
-
/** \name Island Boundary Walker
* \{
*
@@ -668,88 +655,86 @@ static void *bmw_ConnectedVertexWalker_step(BMWalker *walker)
*/
static void bmw_IslandboundWalker_begin(BMWalker *walker, void *data)
{
- BMLoop *l = data;
- BMwIslandboundWalker *iwalk = NULL;
-
- iwalk = BMW_state_add(walker);
+ BMLoop *l = data;
+ BMwIslandboundWalker *iwalk = NULL;
- iwalk->base = iwalk->curloop = l;
- iwalk->lastv = l->v;
+ iwalk = BMW_state_add(walker);
- BLI_gset_insert(walker->visit_set, data);
+ iwalk->base = iwalk->curloop = l;
+ iwalk->lastv = l->v;
+ BLI_gset_insert(walker->visit_set, data);
}
static void *bmw_IslandboundWalker_yield(BMWalker *walker)
{
- BMwIslandboundWalker *iwalk = BMW_current_state(walker);
+ BMwIslandboundWalker *iwalk = BMW_current_state(walker);
- return iwalk->curloop;
+ return iwalk->curloop;
}
static void *bmw_IslandboundWalker_step(BMWalker *walker)
{
- BMwIslandboundWalker *iwalk, owalk;
- BMVert *v;
- BMEdge *e;
- BMFace *f;
- BMLoop *l;
- /* int found = 0; */
-
- memcpy(&owalk, BMW_current_state(walker), sizeof(owalk));
- /* normally we'd remove here, but delay until after error checking */
- iwalk = &owalk;
-
- l = iwalk->curloop;
- e = l->e;
-
- v = BM_edge_other_vert(e, iwalk->lastv);
-
- /* pop off current state */
- BMW_state_remove(walker);
-
- f = l->f;
-
- while (1) {
- l = BM_loop_other_edge_loop(l, v);
- if (BM_loop_is_manifold(l)) {
- l = l->radial_next;
- f = l->f;
- e = l->e;
-
- if (!bmw_mask_check_face(walker, f)) {
- l = l->radial_next;
- break;
- }
- }
- else {
- /* treat non-manifold edges as boundaries */
- f = l->f;
- e = l->e;
- break;
- }
- }
-
- if (l == owalk.curloop) {
- return NULL;
- }
- else if (BLI_gset_haskey(walker->visit_set, l)) {
- return owalk.curloop;
- }
-
- BLI_gset_insert(walker->visit_set, l);
- iwalk = BMW_state_add(walker);
- iwalk->base = owalk.base;
-
- //if (!BMO_face_flag_test(walker->bm, l->f, walker->restrictflag))
- // iwalk->curloop = l->radial_next;
- iwalk->curloop = l; //else iwalk->curloop = l;
- iwalk->lastv = v;
-
- return owalk.curloop;
+ BMwIslandboundWalker *iwalk, owalk;
+ BMVert *v;
+ BMEdge *e;
+ BMFace *f;
+ BMLoop *l;
+ /* int found = 0; */
+
+ memcpy(&owalk, BMW_current_state(walker), sizeof(owalk));
+ /* normally we'd remove here, but delay until after error checking */
+ iwalk = &owalk;
+
+ l = iwalk->curloop;
+ e = l->e;
+
+ v = BM_edge_other_vert(e, iwalk->lastv);
+
+ /* pop off current state */
+ BMW_state_remove(walker);
+
+ f = l->f;
+
+ while (1) {
+ l = BM_loop_other_edge_loop(l, v);
+ if (BM_loop_is_manifold(l)) {
+ l = l->radial_next;
+ f = l->f;
+ e = l->e;
+
+ if (!bmw_mask_check_face(walker, f)) {
+ l = l->radial_next;
+ break;
+ }
+ }
+ else {
+ /* treat non-manifold edges as boundaries */
+ f = l->f;
+ e = l->e;
+ break;
+ }
+ }
+
+ if (l == owalk.curloop) {
+ return NULL;
+ }
+ else if (BLI_gset_haskey(walker->visit_set, l)) {
+ return owalk.curloop;
+ }
+
+ BLI_gset_insert(walker->visit_set, l);
+ iwalk = BMW_state_add(walker);
+ iwalk->base = owalk.base;
+
+ //if (!BMO_face_flag_test(walker->bm, l->f, walker->restrictflag))
+ // iwalk->curloop = l->radial_next;
+ iwalk->curloop = l; //else iwalk->curloop = l;
+ iwalk->lastv = v;
+
+ return owalk.curloop;
}
-
/** \name Island Walker
* \{
*
@@ -759,90 +744,90 @@ static void *bmw_IslandboundWalker_step(BMWalker *walker)
*/
static void bmw_IslandWalker_begin(BMWalker *walker, void *data)
{
- BMwIslandWalker *iwalk = NULL;
+ BMwIslandWalker *iwalk = NULL;
- if (!bmw_mask_check_face(walker, data)) {
- return;
- }
+ if (!bmw_mask_check_face(walker, data)) {
+ return;
+ }
- iwalk = BMW_state_add(walker);
- BLI_gset_insert(walker->visit_set, data);
+ iwalk = BMW_state_add(walker);
+ BLI_gset_insert(walker->visit_set, data);
- iwalk->cur = data;
+ iwalk->cur = data;
}
static void *bmw_IslandWalker_yield(BMWalker *walker)
{
- BMwIslandWalker *iwalk = BMW_current_state(walker);
+ BMwIslandWalker *iwalk = BMW_current_state(walker);
- return iwalk->cur;
+ return iwalk->cur;
}
static void *bmw_IslandWalker_step_ex(BMWalker *walker, bool only_manifold)
{
- BMwIslandWalker *iwalk, owalk;
- BMLoop *l_iter, *l_first;
-
- BMW_state_remove_r(walker, &owalk);
- iwalk = &owalk;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(iwalk->cur);
- do {
- /* could skip loop here too, but don't add unless we need it */
- if (!bmw_mask_check_edge(walker, l_iter->e)) {
- continue;
- }
-
- BMLoop *l_radial_iter;
-
- if (only_manifold && (l_iter->radial_next != l_iter)) {
- int face_count = 1;
- /* check other faces (not this one), ensure only one other can be walked onto. */
- l_radial_iter = l_iter->radial_next;
- do {
- if (bmw_mask_check_face(walker, l_radial_iter->f)) {
- face_count++;
- if (face_count == 3) {
- break;
- }
- }
- } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter);
-
- if (face_count != 2) {
- continue;
- }
- }
-
- l_radial_iter = l_iter;
- while ((l_radial_iter = l_radial_iter->radial_next) != l_iter) {
- BMFace *f = l_radial_iter->f;
-
- if (!bmw_mask_check_face(walker, f)) {
- continue;
- }
-
- /* saves checking BLI_gset_haskey below (manifold edges theres a 50% chance) */
- if (f == iwalk->cur) {
- continue;
- }
-
- if (BLI_gset_haskey(walker->visit_set, f)) {
- continue;
- }
-
- iwalk = BMW_state_add(walker);
- iwalk->cur = f;
- BLI_gset_insert(walker->visit_set, f);
- break;
- }
- } while ((l_iter = l_iter->next) != l_first);
-
- return owalk.cur;
+ BMwIslandWalker *iwalk, owalk;
+ BMLoop *l_iter, *l_first;
+
+ BMW_state_remove_r(walker, &owalk);
+ iwalk = &owalk;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(iwalk->cur);
+ do {
+ /* could skip loop here too, but don't add unless we need it */
+ if (!bmw_mask_check_edge(walker, l_iter->e)) {
+ continue;
+ }
+
+ BMLoop *l_radial_iter;
+
+ if (only_manifold && (l_iter->radial_next != l_iter)) {
+ int face_count = 1;
+ /* check other faces (not this one), ensure only one other can be walked onto. */
+ l_radial_iter = l_iter->radial_next;
+ do {
+ if (bmw_mask_check_face(walker, l_radial_iter->f)) {
+ face_count++;
+ if (face_count == 3) {
+ break;
+ }
+ }
+ } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter);
+
+ if (face_count != 2) {
+ continue;
+ }
+ }
+
+ l_radial_iter = l_iter;
+ while ((l_radial_iter = l_radial_iter->radial_next) != l_iter) {
+ BMFace *f = l_radial_iter->f;
+
+ if (!bmw_mask_check_face(walker, f)) {
+ continue;
+ }
+
+ /* saves checking BLI_gset_haskey below (manifold edges theres a 50% chance) */
+ if (f == iwalk->cur) {
+ continue;
+ }
+
+ if (BLI_gset_haskey(walker->visit_set, f)) {
+ continue;
+ }
+
+ iwalk = BMW_state_add(walker);
+ iwalk->cur = f;
+ BLI_gset_insert(walker->visit_set, f);
+ break;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+
+ return owalk.cur;
}
static void *bmw_IslandWalker_step(BMWalker *walker)
{
- return bmw_IslandWalker_step_ex(walker, false);
+ return bmw_IslandWalker_step_ex(walker, false);
}
/**
@@ -850,12 +835,11 @@ static void *bmw_IslandWalker_step(BMWalker *walker)
*/
static void *bmw_IslandManifoldWalker_step(BMWalker *walker)
{
- return bmw_IslandWalker_step_ex(walker, true);
+ return bmw_IslandWalker_step_ex(walker, true);
}
/** \} */
-
/** \name Edge Loop Walker
* \{
*
@@ -865,251 +849,238 @@ static void *bmw_IslandManifoldWalker_step(BMWalker *walker)
/* utility function to see if an edge is apart of an ngon boundary */
static bool bm_edge_is_single(BMEdge *e)
{
- return ((BM_edge_is_boundary(e)) &&
- (e->l->f->len > 4) &&
- (BM_edge_is_boundary(e->l->next->e) || BM_edge_is_boundary(e->l->prev->e)));
+ return ((BM_edge_is_boundary(e)) && (e->l->f->len > 4) &&
+ (BM_edge_is_boundary(e->l->next->e) || BM_edge_is_boundary(e->l->prev->e)));
}
static void bmw_EdgeLoopWalker_begin(BMWalker *walker, void *data)
{
- BMwEdgeLoopWalker *lwalk = NULL, owalk, *owalk_pt;
- BMEdge *e = data;
- BMVert *v;
- const int vert_edge_count[2] = {
- BM_vert_edge_count_nonwire(e->v1),
- BM_vert_edge_count_nonwire(e->v2),
- };
-
- v = e->v1;
-
- lwalk = BMW_state_add(walker);
- BLI_gset_insert(walker->visit_set, e);
-
- lwalk->cur = lwalk->start = e;
- lwalk->lastv = lwalk->startv = v;
- lwalk->is_boundary = BM_edge_is_boundary(e);
- lwalk->is_single = (lwalk->is_boundary && bm_edge_is_single(e));
-
- /* could also check that vertex*/
- if ((lwalk->is_boundary == false) &&
- (vert_edge_count[0] == 3 || vert_edge_count[1] == 3))
- {
- BMIter iter;
- BMFace *f_iter;
- BMFace *f_best = NULL;
-
- BM_ITER_ELEM (f_iter, &iter, e, BM_FACES_OF_EDGE) {
- if (f_best == NULL || f_best->len < f_iter->len) {
- f_best = f_iter;
- }
- }
-
- if (f_best) {
- /* only use hub selection for 5+ sides else this could
- * conflict with normal edge loop selection. */
- lwalk->f_hub = f_best->len > 4 ? f_best : NULL;
- }
- else {
- /* edge doesn't have any faces connected to it */
- lwalk->f_hub = NULL;
- }
- }
- else {
- lwalk->f_hub = NULL;
- }
-
- /* rewind */
- while ((owalk_pt = BMW_current_state(walker))) {
- owalk = *((BMwEdgeLoopWalker *)owalk_pt);
- BMW_walk(walker);
- }
-
- lwalk = BMW_state_add(walker);
- *lwalk = owalk;
-
- lwalk->lastv = lwalk->startv = BM_edge_other_vert(owalk.cur, lwalk->lastv);
-
- BLI_gset_clear(walker->visit_set, NULL);
- BLI_gset_insert(walker->visit_set, owalk.cur);
+ BMwEdgeLoopWalker *lwalk = NULL, owalk, *owalk_pt;
+ BMEdge *e = data;
+ BMVert *v;
+ const int vert_edge_count[2] = {
+ BM_vert_edge_count_nonwire(e->v1),
+ BM_vert_edge_count_nonwire(e->v2),
+ };
+
+ v = e->v1;
+
+ lwalk = BMW_state_add(walker);
+ BLI_gset_insert(walker->visit_set, e);
+
+ lwalk->cur = lwalk->start = e;
+ lwalk->lastv = lwalk->startv = v;
+ lwalk->is_boundary = BM_edge_is_boundary(e);
+ lwalk->is_single = (lwalk->is_boundary && bm_edge_is_single(e));
+
+ /* could also check that vertex*/
+ if ((lwalk->is_boundary == false) && (vert_edge_count[0] == 3 || vert_edge_count[1] == 3)) {
+ BMIter iter;
+ BMFace *f_iter;
+ BMFace *f_best = NULL;
+
+ BM_ITER_ELEM (f_iter, &iter, e, BM_FACES_OF_EDGE) {
+ if (f_best == NULL || f_best->len < f_iter->len) {
+ f_best = f_iter;
+ }
+ }
+
+ if (f_best) {
+ /* only use hub selection for 5+ sides else this could
+ * conflict with normal edge loop selection. */
+ lwalk->f_hub = f_best->len > 4 ? f_best : NULL;
+ }
+ else {
+ /* edge doesn't have any faces connected to it */
+ lwalk->f_hub = NULL;
+ }
+ }
+ else {
+ lwalk->f_hub = NULL;
+ }
+
+ /* rewind */
+ while ((owalk_pt = BMW_current_state(walker))) {
+ owalk = *((BMwEdgeLoopWalker *)owalk_pt);
+ BMW_walk(walker);
+ }
+
+ lwalk = BMW_state_add(walker);
+ *lwalk = owalk;
+
+ lwalk->lastv = lwalk->startv = BM_edge_other_vert(owalk.cur, lwalk->lastv);
+
+ BLI_gset_clear(walker->visit_set, NULL);
+ BLI_gset_insert(walker->visit_set, owalk.cur);
}
static void *bmw_EdgeLoopWalker_yield(BMWalker *walker)
{
- BMwEdgeLoopWalker *lwalk = BMW_current_state(walker);
+ BMwEdgeLoopWalker *lwalk = BMW_current_state(walker);
- return lwalk->cur;
+ return lwalk->cur;
}
static void *bmw_EdgeLoopWalker_step(BMWalker *walker)
{
- BMwEdgeLoopWalker *lwalk, owalk;
- BMEdge *e, *nexte = NULL;
- BMLoop *l;
- BMVert *v;
-
- BMW_state_remove_r(walker, &owalk);
- lwalk = &owalk;
-
- e = lwalk->cur;
- l = e->l;
-
- if (owalk.f_hub) { /* NGON EDGE */
- int vert_edge_tot;
-
- v = BM_edge_other_vert(e, lwalk->lastv);
-
- vert_edge_tot = BM_vert_edge_count_nonwire(v);
-
- if (vert_edge_tot == 3) {
- l = BM_face_other_vert_loop(owalk.f_hub, lwalk->lastv, v);
- nexte = BM_edge_exists(v, l->v);
-
- if (bmw_mask_check_edge(walker, nexte) &&
- !BLI_gset_haskey(walker->visit_set, nexte) &&
- /* never step onto a boundary edge, this gives odd-results */
- (BM_edge_is_boundary(nexte) == false))
- {
- lwalk = BMW_state_add(walker);
- lwalk->cur = nexte;
- lwalk->lastv = v;
-
- lwalk->is_boundary = owalk.is_boundary;
- lwalk->is_single = owalk.is_single;
- lwalk->f_hub = owalk.f_hub;
-
- BLI_gset_insert(walker->visit_set, nexte);
- }
- }
- }
- else if (l == NULL) { /* WIRE EDGE */
- BMIter eiter;
-
- /* match trunk: mark all connected wire edges */
- for (int i = 0; i < 2; i++) {
- v = i ? e->v2 : e->v1;
-
- BM_ITER_ELEM (nexte, &eiter, v, BM_EDGES_OF_VERT) {
- if ((nexte->l == NULL) &&
- bmw_mask_check_edge(walker, nexte) &&
- !BLI_gset_haskey(walker->visit_set, nexte))
- {
- lwalk = BMW_state_add(walker);
- lwalk->cur = nexte;
- lwalk->lastv = v;
-
- lwalk->is_boundary = owalk.is_boundary;
- lwalk->is_single = owalk.is_single;
- lwalk->f_hub = owalk.f_hub;
-
- BLI_gset_insert(walker->visit_set, nexte);
- }
- }
- }
- }
- else if (owalk.is_boundary == false) { /* NORMAL EDGE WITH FACES */
- int vert_edge_tot;
-
- v = BM_edge_other_vert(e, lwalk->lastv);
-
- vert_edge_tot = BM_vert_edge_count_nonwire(v);
-
- /* typical loopiong over edges in the middle of a mesh */
- /* however, why use 2 here at all? I guess for internal ngon loops it can be useful. Antony R. */
- if (vert_edge_tot == 4 || vert_edge_tot == 2) {
- int i_opposite = vert_edge_tot / 2;
- int i = 0;
- do {
- l = BM_loop_other_edge_loop(l, v);
- if (BM_edge_is_manifold(l->e)) {
- l = l->radial_next;
- }
- else {
- l = NULL;
- break;
- }
- } while ((++i != i_opposite));
- }
- else {
- l = NULL;
- }
-
- if (l != NULL) {
- if (l != e->l &&
- bmw_mask_check_edge(walker, l->e) &&
- !BLI_gset_haskey(walker->visit_set, l->e))
- {
- lwalk = BMW_state_add(walker);
- lwalk->cur = l->e;
- lwalk->lastv = v;
-
- lwalk->is_boundary = owalk.is_boundary;
- lwalk->is_single = owalk.is_single;
- lwalk->f_hub = owalk.f_hub;
-
- BLI_gset_insert(walker->visit_set, l->e);
- }
- }
- }
- else if (owalk.is_boundary == true) { /* BOUNDARY EDGE WITH FACES */
- int vert_edge_tot;
-
- v = BM_edge_other_vert(e, lwalk->lastv);
-
- vert_edge_tot = BM_vert_edge_count_nonwire(v);
-
- /* check if we should step, this is fairly involved */
- if (
- /* walk over boundary of faces but stop at corners */
- (owalk.is_single == false && vert_edge_tot > 2) ||
-
- /* initial edge was a boundary, so is this edge and vertex is only apart of this face
- * this lets us walk over the boundary of an ngon which is handy */
- (owalk.is_single == true && vert_edge_tot == 2 && BM_edge_is_boundary(e)))
- {
- /* find next boundary edge in the fan */
- do {
- l = BM_loop_other_edge_loop(l, v);
- if (BM_edge_is_manifold(l->e)) {
- l = l->radial_next;
- }
- else if (BM_edge_is_boundary(l->e)) {
- break;
- }
- else {
- l = NULL;
- break;
- }
- } while (true);
- }
-
- if (owalk.is_single == false && l && bm_edge_is_single(l->e)) {
- l = NULL;
- }
-
- if (l != NULL) {
- if (l != e->l &&
- bmw_mask_check_edge(walker, l->e) &&
- !BLI_gset_haskey(walker->visit_set, l->e))
- {
- lwalk = BMW_state_add(walker);
- lwalk->cur = l->e;
- lwalk->lastv = v;
-
- lwalk->is_boundary = owalk.is_boundary;
- lwalk->is_single = owalk.is_single;
- lwalk->f_hub = owalk.f_hub;
-
- BLI_gset_insert(walker->visit_set, l->e);
- }
- }
- }
-
- return owalk.cur;
+ BMwEdgeLoopWalker *lwalk, owalk;
+ BMEdge *e, *nexte = NULL;
+ BMLoop *l;
+ BMVert *v;
+
+ BMW_state_remove_r(walker, &owalk);
+ lwalk = &owalk;
+
+ e = lwalk->cur;
+ l = e->l;
+
+ if (owalk.f_hub) { /* NGON EDGE */
+ int vert_edge_tot;
+
+ v = BM_edge_other_vert(e, lwalk->lastv);
+
+ vert_edge_tot = BM_vert_edge_count_nonwire(v);
+
+ if (vert_edge_tot == 3) {
+ l = BM_face_other_vert_loop(owalk.f_hub, lwalk->lastv, v);
+ nexte = BM_edge_exists(v, l->v);
+
+ if (bmw_mask_check_edge(walker, nexte) && !BLI_gset_haskey(walker->visit_set, nexte) &&
+ /* never step onto a boundary edge, this gives odd-results */
+ (BM_edge_is_boundary(nexte) == false)) {
+ lwalk = BMW_state_add(walker);
+ lwalk->cur = nexte;
+ lwalk->lastv = v;
+
+ lwalk->is_boundary = owalk.is_boundary;
+ lwalk->is_single = owalk.is_single;
+ lwalk->f_hub = owalk.f_hub;
+
+ BLI_gset_insert(walker->visit_set, nexte);
+ }
+ }
+ }
+ else if (l == NULL) { /* WIRE EDGE */
+ BMIter eiter;
+
+ /* match trunk: mark all connected wire edges */
+ for (int i = 0; i < 2; i++) {
+ v = i ? e->v2 : e->v1;
+
+ BM_ITER_ELEM (nexte, &eiter, v, BM_EDGES_OF_VERT) {
+ if ((nexte->l == NULL) && bmw_mask_check_edge(walker, nexte) &&
+ !BLI_gset_haskey(walker->visit_set, nexte)) {
+ lwalk = BMW_state_add(walker);
+ lwalk->cur = nexte;
+ lwalk->lastv = v;
+
+ lwalk->is_boundary = owalk.is_boundary;
+ lwalk->is_single = owalk.is_single;
+ lwalk->f_hub = owalk.f_hub;
+
+ BLI_gset_insert(walker->visit_set, nexte);
+ }
+ }
+ }
+ }
+ else if (owalk.is_boundary == false) { /* NORMAL EDGE WITH FACES */
+ int vert_edge_tot;
+
+ v = BM_edge_other_vert(e, lwalk->lastv);
+
+ vert_edge_tot = BM_vert_edge_count_nonwire(v);
+
+ /* typical loopiong over edges in the middle of a mesh */
+ /* however, why use 2 here at all? I guess for internal ngon loops it can be useful. Antony R. */
+ if (vert_edge_tot == 4 || vert_edge_tot == 2) {
+ int i_opposite = vert_edge_tot / 2;
+ int i = 0;
+ do {
+ l = BM_loop_other_edge_loop(l, v);
+ if (BM_edge_is_manifold(l->e)) {
+ l = l->radial_next;
+ }
+ else {
+ l = NULL;
+ break;
+ }
+ } while ((++i != i_opposite));
+ }
+ else {
+ l = NULL;
+ }
+
+ if (l != NULL) {
+ if (l != e->l && bmw_mask_check_edge(walker, l->e) &&
+ !BLI_gset_haskey(walker->visit_set, l->e)) {
+ lwalk = BMW_state_add(walker);
+ lwalk->cur = l->e;
+ lwalk->lastv = v;
+
+ lwalk->is_boundary = owalk.is_boundary;
+ lwalk->is_single = owalk.is_single;
+ lwalk->f_hub = owalk.f_hub;
+
+ BLI_gset_insert(walker->visit_set, l->e);
+ }
+ }
+ }
+ else if (owalk.is_boundary == true) { /* BOUNDARY EDGE WITH FACES */
+ int vert_edge_tot;
+
+ v = BM_edge_other_vert(e, lwalk->lastv);
+
+ vert_edge_tot = BM_vert_edge_count_nonwire(v);
+
+ /* check if we should step, this is fairly involved */
+ if (
+ /* walk over boundary of faces but stop at corners */
+ (owalk.is_single == false && vert_edge_tot > 2) ||
+
+ /* initial edge was a boundary, so is this edge and vertex is only apart of this face
+ * this lets us walk over the boundary of an ngon which is handy */
+ (owalk.is_single == true && vert_edge_tot == 2 && BM_edge_is_boundary(e))) {
+ /* find next boundary edge in the fan */
+ do {
+ l = BM_loop_other_edge_loop(l, v);
+ if (BM_edge_is_manifold(l->e)) {
+ l = l->radial_next;
+ }
+ else if (BM_edge_is_boundary(l->e)) {
+ break;
+ }
+ else {
+ l = NULL;
+ break;
+ }
+ } while (true);
+ }
+
+ if (owalk.is_single == false && l && bm_edge_is_single(l->e)) {
+ l = NULL;
+ }
+
+ if (l != NULL) {
+ if (l != e->l && bmw_mask_check_edge(walker, l->e) &&
+ !BLI_gset_haskey(walker->visit_set, l->e)) {
+ lwalk = BMW_state_add(walker);
+ lwalk->cur = l->e;
+ lwalk->lastv = v;
+
+ lwalk->is_boundary = owalk.is_boundary;
+ lwalk->is_single = owalk.is_single;
+ lwalk->f_hub = owalk.f_hub;
+
+ BLI_gset_insert(walker->visit_set, l->e);
+ }
+ }
+ }
+
+ return owalk.cur;
}
/** \} */
-
/** \name Face Loop Walker
* \{
*
@@ -1122,139 +1093,138 @@ static void *bmw_EdgeLoopWalker_step(BMWalker *walker)
* by the given BMLoop */
static bool bmw_FaceLoopWalker_include_face(BMWalker *walker, BMLoop *l)
{
- /* face must have degree 4 */
- if (l->f->len != 4) {
- return false;
- }
+ /* face must have degree 4 */
+ if (l->f->len != 4) {
+ return false;
+ }
- if (!bmw_mask_check_face(walker, l->f)) {
- return false;
- }
+ if (!bmw_mask_check_face(walker, l->f)) {
+ return false;
+ }
- /* the face must not have been already visited */
- if (BLI_gset_haskey(walker->visit_set, l->f) && BLI_gset_haskey(walker->visit_set_alt, l->e)) {
- return false;
- }
+ /* the face must not have been already visited */
+ if (BLI_gset_haskey(walker->visit_set, l->f) && BLI_gset_haskey(walker->visit_set_alt, l->e)) {
+ return false;
+ }
- return true;
+ return true;
}
/* Check whether the face loop can start from the given edge */
static bool bmw_FaceLoopWalker_edge_begins_loop(BMWalker *walker, BMEdge *e)
{
- /* There is no face loop starting from a wire edge */
- if (BM_edge_is_wire(e)) {
- return false;
- }
-
- /* Don't start a loop from a boundary edge if it cannot
- * be extended to cover any faces */
- if (BM_edge_is_boundary(e)) {
- if (!bmw_FaceLoopWalker_include_face(walker, e->l)) {
- return false;
- }
- }
-
- /* Don't start a face loop from non-manifold edges */
- if (!BM_edge_is_manifold(e)) {
- return false;
- }
-
- return true;
+ /* There is no face loop starting from a wire edge */
+ if (BM_edge_is_wire(e)) {
+ return false;
+ }
+
+ /* Don't start a loop from a boundary edge if it cannot
+ * be extended to cover any faces */
+ if (BM_edge_is_boundary(e)) {
+ if (!bmw_FaceLoopWalker_include_face(walker, e->l)) {
+ return false;
+ }
+ }
+
+ /* Don't start a face loop from non-manifold edges */
+ if (!BM_edge_is_manifold(e)) {
+ return false;
+ }
+
+ return true;
}
static void bmw_FaceLoopWalker_begin(BMWalker *walker, void *data)
{
- BMwFaceLoopWalker *lwalk, owalk, *owalk_pt;
- BMEdge *e = data;
- /* BMesh *bm = walker->bm; */ /* UNUSED */
- /* int fcount = BM_edge_face_count(e); */ /* UNUSED */
-
- if (!bmw_FaceLoopWalker_edge_begins_loop(walker, e)) {
- return;
- }
-
- lwalk = BMW_state_add(walker);
- lwalk->l = e->l;
- lwalk->no_calc = false;
- BLI_gset_insert(walker->visit_set, lwalk->l->f);
-
- /* rewind */
- while ((owalk_pt = BMW_current_state(walker))) {
- owalk = *((BMwFaceLoopWalker *)owalk_pt);
- BMW_walk(walker);
- }
-
- lwalk = BMW_state_add(walker);
- *lwalk = owalk;
- lwalk->no_calc = false;
-
- BLI_gset_clear(walker->visit_set_alt, NULL);
- BLI_gset_insert(walker->visit_set_alt, lwalk->l->e);
-
- BLI_gset_clear(walker->visit_set, NULL);
- BLI_gset_insert(walker->visit_set, lwalk->l->f);
+ BMwFaceLoopWalker *lwalk, owalk, *owalk_pt;
+ BMEdge *e = data;
+ /* BMesh *bm = walker->bm; */ /* UNUSED */
+ /* int fcount = BM_edge_face_count(e); */ /* UNUSED */
+
+ if (!bmw_FaceLoopWalker_edge_begins_loop(walker, e)) {
+ return;
+ }
+
+ lwalk = BMW_state_add(walker);
+ lwalk->l = e->l;
+ lwalk->no_calc = false;
+ BLI_gset_insert(walker->visit_set, lwalk->l->f);
+
+ /* rewind */
+ while ((owalk_pt = BMW_current_state(walker))) {
+ owalk = *((BMwFaceLoopWalker *)owalk_pt);
+ BMW_walk(walker);
+ }
+
+ lwalk = BMW_state_add(walker);
+ *lwalk = owalk;
+ lwalk->no_calc = false;
+
+ BLI_gset_clear(walker->visit_set_alt, NULL);
+ BLI_gset_insert(walker->visit_set_alt, lwalk->l->e);
+
+ BLI_gset_clear(walker->visit_set, NULL);
+ BLI_gset_insert(walker->visit_set, lwalk->l->f);
}
static void *bmw_FaceLoopWalker_yield(BMWalker *walker)
{
- BMwFaceLoopWalker *lwalk = BMW_current_state(walker);
+ BMwFaceLoopWalker *lwalk = BMW_current_state(walker);
- if (!lwalk) {
- return NULL;
- }
+ if (!lwalk) {
+ return NULL;
+ }
- return lwalk->l->f;
+ return lwalk->l->f;
}
static void *bmw_FaceLoopWalker_step(BMWalker *walker)
{
- BMwFaceLoopWalker *lwalk, owalk;
- BMFace *f;
- BMLoop *l;
-
- BMW_state_remove_r(walker, &owalk);
- lwalk = &owalk;
-
- f = lwalk->l->f;
- l = lwalk->l->radial_next;
-
- if (lwalk->no_calc) {
- return f;
- }
-
- if (!bmw_FaceLoopWalker_include_face(walker, l)) {
- l = lwalk->l;
- l = l->next->next;
- if (!BM_edge_is_manifold(l->e)) {
- l = l->prev->prev;
- }
- l = l->radial_next;
- }
-
- if (bmw_FaceLoopWalker_include_face(walker, l)) {
- lwalk = BMW_state_add(walker);
- lwalk->l = l;
-
- if (l->f->len != 4) {
- lwalk->no_calc = true;
- lwalk->l = owalk.l;
- }
- else {
- lwalk->no_calc = false;
- }
-
- /* both may already exist */
- BLI_gset_add(walker->visit_set_alt, l->e);
- BLI_gset_add(walker->visit_set, l->f);
- }
-
- return f;
+ BMwFaceLoopWalker *lwalk, owalk;
+ BMFace *f;
+ BMLoop *l;
+
+ BMW_state_remove_r(walker, &owalk);
+ lwalk = &owalk;
+
+ f = lwalk->l->f;
+ l = lwalk->l->radial_next;
+
+ if (lwalk->no_calc) {
+ return f;
+ }
+
+ if (!bmw_FaceLoopWalker_include_face(walker, l)) {
+ l = lwalk->l;
+ l = l->next->next;
+ if (!BM_edge_is_manifold(l->e)) {
+ l = l->prev->prev;
+ }
+ l = l->radial_next;
+ }
+
+ if (bmw_FaceLoopWalker_include_face(walker, l)) {
+ lwalk = BMW_state_add(walker);
+ lwalk->l = l;
+
+ if (l->f->len != 4) {
+ lwalk->no_calc = true;
+ lwalk->l = owalk.l;
+ }
+ else {
+ lwalk->no_calc = false;
+ }
+
+ /* both may already exist */
+ BLI_gset_add(walker->visit_set_alt, l->e);
+ BLI_gset_add(walker->visit_set, l->f);
+ }
+
+ return f;
}
/** \} */
-
// #define BMW_EDGERING_NGON
/** \name Edge Ring Walker
@@ -1266,210 +1236,205 @@ static void *bmw_FaceLoopWalker_step(BMWalker *walker)
*/
static void bmw_EdgeringWalker_begin(BMWalker *walker, void *data)
{
- BMwEdgeringWalker *lwalk, owalk, *owalk_pt;
- BMEdge *e = data;
+ BMwEdgeringWalker *lwalk, owalk, *owalk_pt;
+ BMEdge *e = data;
- lwalk = BMW_state_add(walker);
- lwalk->l = e->l;
+ lwalk = BMW_state_add(walker);
+ lwalk->l = e->l;
- if (!lwalk->l) {
- lwalk->wireedge = e;
- return;
- }
- else {
- lwalk->wireedge = NULL;
- }
+ if (!lwalk->l) {
+ lwalk->wireedge = e;
+ return;
+ }
+ else {
+ lwalk->wireedge = NULL;
+ }
- BLI_gset_insert(walker->visit_set, lwalk->l->e);
+ BLI_gset_insert(walker->visit_set, lwalk->l->e);
- /* rewind */
- while ((owalk_pt = BMW_current_state(walker))) {
- owalk = *((BMwEdgeringWalker *)owalk_pt);
- BMW_walk(walker);
- }
+ /* rewind */
+ while ((owalk_pt = BMW_current_state(walker))) {
+ owalk = *((BMwEdgeringWalker *)owalk_pt);
+ BMW_walk(walker);
+ }
- lwalk = BMW_state_add(walker);
- *lwalk = owalk;
+ lwalk = BMW_state_add(walker);
+ *lwalk = owalk;
#ifdef BMW_EDGERING_NGON
- if (lwalk->l->f->len % 2 != 0)
+ if (lwalk->l->f->len % 2 != 0)
#else
- if (lwalk->l->f->len != 4)
+ if (lwalk->l->f->len != 4)
#endif
- {
- lwalk->l = lwalk->l->radial_next;
- }
+ {
+ lwalk->l = lwalk->l->radial_next;
+ }
- BLI_gset_clear(walker->visit_set, NULL);
- BLI_gset_insert(walker->visit_set, lwalk->l->e);
+ BLI_gset_clear(walker->visit_set, NULL);
+ BLI_gset_insert(walker->visit_set, lwalk->l->e);
}
static void *bmw_EdgeringWalker_yield(BMWalker *walker)
{
- BMwEdgeringWalker *lwalk = BMW_current_state(walker);
-
- if (!lwalk) {
- return NULL;
- }
-
- if (lwalk->l) {
- return lwalk->l->e;
- }
- else {
- return lwalk->wireedge;
- }
+ BMwEdgeringWalker *lwalk = BMW_current_state(walker);
+
+ if (!lwalk) {
+ return NULL;
+ }
+
+ if (lwalk->l) {
+ return lwalk->l->e;
+ }
+ else {
+ return lwalk->wireedge;
+ }
}
static void *bmw_EdgeringWalker_step(BMWalker *walker)
{
- BMwEdgeringWalker *lwalk, owalk;
- BMEdge *e;
- BMLoop *l;
+ BMwEdgeringWalker *lwalk, owalk;
+ BMEdge *e;
+ BMLoop *l;
#ifdef BMW_EDGERING_NGON
- int i, len;
+ int i, len;
#endif
-#define EDGE_CHECK(e) (bmw_mask_check_edge(walker, e) && (BM_edge_is_boundary(e) || BM_edge_is_manifold(e)))
+#define EDGE_CHECK(e) \
+ (bmw_mask_check_edge(walker, e) && (BM_edge_is_boundary(e) || BM_edge_is_manifold(e)))
- BMW_state_remove_r(walker, &owalk);
- lwalk = &owalk;
+ BMW_state_remove_r(walker, &owalk);
+ lwalk = &owalk;
- l = lwalk->l;
- if (!l) {
- return lwalk->wireedge;
- }
+ l = lwalk->l;
+ if (!l) {
+ return lwalk->wireedge;
+ }
- e = l->e;
- if (!EDGE_CHECK(e)) {
- /* walker won't traverse to a non-manifold edge, but may
- * be started on one, and should not traverse *away* from
- * a non-manifold edge (non-manifold edges are never in an
- * edge ring with manifold edges */
- return e;
- }
+ e = l->e;
+ if (!EDGE_CHECK(e)) {
+ /* walker won't traverse to a non-manifold edge, but may
+ * be started on one, and should not traverse *away* from
+ * a non-manifold edge (non-manifold edges are never in an
+ * edge ring with manifold edges */
+ return e;
+ }
#ifdef BMW_EDGERING_NGON
- l = l->radial_next;
-
- i = len = l->f->len;
- while (i > 0) {
- l = l->next;
- i -= 2;
- }
-
- if ((len <= 0) || (len % 2 != 0) || !EDGE_CHECK(l->e) ||
- !bmw_mask_check_face(walker, l->f))
- {
- l = owalk.l;
- i = len;
- while (i > 0) {
- l = l->next;
- i -= 2;
- }
- }
- /* only walk to manifold edge */
- if ((l->f->len % 2 == 0) && EDGE_CHECK(l->e) &&
- !BLI_gset_haskey(walker->visit_set, l->e))
+ l = l->radial_next;
+
+ i = len = l->f->len;
+ while (i > 0) {
+ l = l->next;
+ i -= 2;
+ }
+
+ if ((len <= 0) || (len % 2 != 0) || !EDGE_CHECK(l->e) || !bmw_mask_check_face(walker, l->f)) {
+ l = owalk.l;
+ i = len;
+ while (i > 0) {
+ l = l->next;
+ i -= 2;
+ }
+ }
+ /* only walk to manifold edge */
+ if ((l->f->len % 2 == 0) && EDGE_CHECK(l->e) && !BLI_gset_haskey(walker->visit_set, l->e))
#else
- l = l->radial_next;
- l = l->next->next;
+ l = l->radial_next;
+ l = l->next->next;
- if ((l->f->len != 4) || !EDGE_CHECK(l->e) || !bmw_mask_check_face(walker, l->f)) {
- l = owalk.l->next->next;
- }
- /* only walk to manifold edge */
- if ((l->f->len == 4) && EDGE_CHECK(l->e) &&
- !BLI_gset_haskey(walker->visit_set, l->e))
+ if ((l->f->len != 4) || !EDGE_CHECK(l->e) || !bmw_mask_check_face(walker, l->f)) {
+ l = owalk.l->next->next;
+ }
+ /* only walk to manifold edge */
+ if ((l->f->len == 4) && EDGE_CHECK(l->e) && !BLI_gset_haskey(walker->visit_set, l->e))
#endif
- {
- lwalk = BMW_state_add(walker);
- lwalk->l = l;
- lwalk->wireedge = NULL;
+ {
+ lwalk = BMW_state_add(walker);
+ lwalk->l = l;
+ lwalk->wireedge = NULL;
- BLI_gset_insert(walker->visit_set, l->e);
- }
+ BLI_gset_insert(walker->visit_set, l->e);
+ }
- return e;
+ return e;
#undef EDGE_CHECK
}
/** \} */
-
/** \name Boundary Edge Walker
* \{ */
static void bmw_EdgeboundaryWalker_begin(BMWalker *walker, void *data)
{
- BMwEdgeboundaryWalker *lwalk;
- BMEdge *e = data;
+ BMwEdgeboundaryWalker *lwalk;
+ BMEdge *e = data;
- BLI_assert(BM_edge_is_boundary(e));
+ BLI_assert(BM_edge_is_boundary(e));
- if (BLI_gset_haskey(walker->visit_set, e)) {
- return;
- }
+ if (BLI_gset_haskey(walker->visit_set, e)) {
+ return;
+ }
- lwalk = BMW_state_add(walker);
- lwalk->e = e;
- BLI_gset_insert(walker->visit_set, e);
+ lwalk = BMW_state_add(walker);
+ lwalk->e = e;
+ BLI_gset_insert(walker->visit_set, e);
}
static void *bmw_EdgeboundaryWalker_yield(BMWalker *walker)
{
- BMwEdgeboundaryWalker *lwalk = BMW_current_state(walker);
+ BMwEdgeboundaryWalker *lwalk = BMW_current_state(walker);
- if (!lwalk) {
- return NULL;
- }
+ if (!lwalk) {
+ return NULL;
+ }
- return lwalk->e;
+ return lwalk->e;
}
static void *bmw_EdgeboundaryWalker_step(BMWalker *walker)
{
- BMwEdgeboundaryWalker *lwalk, owalk;
- BMEdge *e, *e_other;
- BMVert *v;
- BMIter eiter;
- BMIter viter;
+ BMwEdgeboundaryWalker *lwalk, owalk;
+ BMEdge *e, *e_other;
+ BMVert *v;
+ BMIter eiter;
+ BMIter viter;
- BMW_state_remove_r(walker, &owalk);
- lwalk = &owalk;
+ BMW_state_remove_r(walker, &owalk);
+ lwalk = &owalk;
- e = lwalk->e;
+ e = lwalk->e;
- if (!bmw_mask_check_edge(walker, e)) {
- return e;
- }
+ if (!bmw_mask_check_edge(walker, e)) {
+ return e;
+ }
- BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) {
- BM_ITER_ELEM (e_other, &eiter, v, BM_EDGES_OF_VERT) {
- if (e != e_other && BM_edge_is_boundary(e_other)) {
- if (BLI_gset_haskey(walker->visit_set, e_other)) {
- continue;
- }
+ BM_ITER_ELEM (v, &viter, e, BM_VERTS_OF_EDGE) {
+ BM_ITER_ELEM (e_other, &eiter, v, BM_EDGES_OF_VERT) {
+ if (e != e_other && BM_edge_is_boundary(e_other)) {
+ if (BLI_gset_haskey(walker->visit_set, e_other)) {
+ continue;
+ }
- if (!bmw_mask_check_edge(walker, e_other)) {
- continue;
- }
+ if (!bmw_mask_check_edge(walker, e_other)) {
+ continue;
+ }
- lwalk = BMW_state_add(walker);
- BLI_gset_insert(walker->visit_set, e_other);
+ lwalk = BMW_state_add(walker);
+ BLI_gset_insert(walker->visit_set, e_other);
- lwalk->e = e_other;
- }
- }
- }
+ lwalk->e = e_other;
+ }
+ }
+ }
- return e;
+ return e;
}
/** \} */
-
/** \name UV Edge Walker
*
* walk over uv islands; takes a loop as input. restrict flag
@@ -1482,238 +1447,239 @@ static void *bmw_EdgeboundaryWalker_step(BMWalker *walker)
static void bmw_UVEdgeWalker_begin(BMWalker *walker, void *data)
{
- BMwUVEdgeWalker *lwalk;
- BMLoop *l = data;
+ BMwUVEdgeWalker *lwalk;
+ BMLoop *l = data;
- if (BLI_gset_haskey(walker->visit_set, l)) {
- return;
- }
+ if (BLI_gset_haskey(walker->visit_set, l)) {
+ return;
+ }
- lwalk = BMW_state_add(walker);
- lwalk->l = l;
- BLI_gset_insert(walker->visit_set, l);
+ lwalk = BMW_state_add(walker);
+ lwalk->l = l;
+ BLI_gset_insert(walker->visit_set, l);
}
static void *bmw_UVEdgeWalker_yield(BMWalker *walker)
{
- BMwUVEdgeWalker *lwalk = BMW_current_state(walker);
+ BMwUVEdgeWalker *lwalk = BMW_current_state(walker);
- if (!lwalk) {
- return NULL;
- }
+ if (!lwalk) {
+ return NULL;
+ }
- return lwalk->l;
+ return lwalk->l;
}
static void *bmw_UVEdgeWalker_step(BMWalker *walker)
{
- const int type = walker->bm->ldata.layers[walker->layer].type;
- const int offset = walker->bm->ldata.layers[walker->layer].offset;
+ const int type = walker->bm->ldata.layers[walker->layer].type;
+ const int offset = walker->bm->ldata.layers[walker->layer].offset;
- BMwUVEdgeWalker *lwalk, owalk;
- BMLoop *l;
- int i;
+ BMwUVEdgeWalker *lwalk, owalk;
+ BMLoop *l;
+ int i;
- BMW_state_remove_r(walker, &owalk);
- lwalk = &owalk;
+ BMW_state_remove_r(walker, &owalk);
+ lwalk = &owalk;
- l = lwalk->l;
+ l = lwalk->l;
- if (!bmw_mask_check_edge(walker, l->e)) {
- return l;
- }
+ if (!bmw_mask_check_edge(walker, l->e)) {
+ return l;
+ }
- /* go over loops around l->v and nl->v and see which ones share l and nl's
- * mloopuv's coordinates. in addition, push on l->next if necessary */
- for (i = 0; i < 2; i++) {
- BMIter liter;
- BMLoop *l_pivot, *l_radial;
+ /* go over loops around l->v and nl->v and see which ones share l and nl's
+ * mloopuv's coordinates. in addition, push on l->next if necessary */
+ for (i = 0; i < 2; i++) {
+ BMIter liter;
+ BMLoop *l_pivot, *l_radial;
- l_pivot = i ? l->next : l;
- BM_ITER_ELEM (l_radial, &liter, l_pivot->v, BM_LOOPS_OF_VERT) {
- BMLoop *l_radial_first = l_radial;
- void *data_pivot = BM_ELEM_CD_GET_VOID_P(l_pivot, offset);
+ l_pivot = i ? l->next : l;
+ BM_ITER_ELEM (l_radial, &liter, l_pivot->v, BM_LOOPS_OF_VERT) {
+ BMLoop *l_radial_first = l_radial;
+ void *data_pivot = BM_ELEM_CD_GET_VOID_P(l_pivot, offset);
- do {
- BMLoop *l_other;
- void *data_other;
+ do {
+ BMLoop *l_other;
+ void *data_other;
- if (BLI_gset_haskey(walker->visit_set, l_radial)) {
- continue;
- }
+ if (BLI_gset_haskey(walker->visit_set, l_radial)) {
+ continue;
+ }
- if (l_radial->v != l_pivot->v) {
- if (!bmw_mask_check_edge(walker, l_radial->e)) {
- continue;
- }
- }
+ if (l_radial->v != l_pivot->v) {
+ if (!bmw_mask_check_edge(walker, l_radial->e)) {
+ continue;
+ }
+ }
- l_other = (l_radial->v != l_pivot->v) ? l_radial->next : l_radial;
- data_other = BM_ELEM_CD_GET_VOID_P(l_other, offset);
+ l_other = (l_radial->v != l_pivot->v) ? l_radial->next : l_radial;
+ data_other = BM_ELEM_CD_GET_VOID_P(l_other, offset);
- if (!CustomData_data_equals(type, data_pivot, data_other)) {
- continue;
- }
+ if (!CustomData_data_equals(type, data_pivot, data_other)) {
+ continue;
+ }
- lwalk = BMW_state_add(walker);
- BLI_gset_insert(walker->visit_set, l_radial);
+ lwalk = BMW_state_add(walker);
+ BLI_gset_insert(walker->visit_set, l_radial);
- lwalk->l = l_radial;
+ lwalk->l = l_radial;
- } while ((l_radial = l_radial->radial_next) != l_radial_first);
- }
- }
+ } while ((l_radial = l_radial->radial_next) != l_radial_first);
+ }
+ }
- return l;
+ return l;
}
/** \} */
-
static BMWalker bmw_VertShellWalker_Type = {
- BM_VERT | BM_EDGE,
- bmw_VertShellWalker_begin,
- bmw_VertShellWalker_step,
- bmw_VertShellWalker_yield,
- sizeof(BMwShellWalker),
- BMW_BREADTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_VERT | BM_EDGE,
+ bmw_VertShellWalker_begin,
+ bmw_VertShellWalker_step,
+ bmw_VertShellWalker_yield,
+ sizeof(BMwShellWalker),
+ BMW_BREADTH_FIRST,
+ BM_EDGE, /* valid restrict masks */
};
static BMWalker bmw_LoopShellWalker_Type = {
- BM_FACE | BM_LOOP | BM_EDGE | BM_VERT,
- bmw_LoopShellWalker_begin,
- bmw_LoopShellWalker_step,
- bmw_LoopShellWalker_yield,
- sizeof(BMwLoopShellWalker),
- BMW_BREADTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_FACE | BM_LOOP | BM_EDGE | BM_VERT,
+ bmw_LoopShellWalker_begin,
+ bmw_LoopShellWalker_step,
+ bmw_LoopShellWalker_yield,
+ sizeof(BMwLoopShellWalker),
+ BMW_BREADTH_FIRST,
+ BM_EDGE, /* valid restrict masks */
};
static BMWalker bmw_LoopShellWireWalker_Type = {
- BM_FACE | BM_LOOP | BM_EDGE | BM_VERT,
- bmw_LoopShellWireWalker_begin,
- bmw_LoopShellWireWalker_step,
- bmw_LoopShellWireWalker_yield,
- sizeof(BMwLoopShellWireWalker),
- BMW_BREADTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_FACE | BM_LOOP | BM_EDGE | BM_VERT,
+ bmw_LoopShellWireWalker_begin,
+ bmw_LoopShellWireWalker_step,
+ bmw_LoopShellWireWalker_yield,
+ sizeof(BMwLoopShellWireWalker),
+ BMW_BREADTH_FIRST,
+ BM_EDGE, /* valid restrict masks */
};
static BMWalker bmw_FaceShellWalker_Type = {
- BM_EDGE,
- bmw_FaceShellWalker_begin,
- bmw_FaceShellWalker_step,
- bmw_FaceShellWalker_yield,
- sizeof(BMwShellWalker),
- BMW_BREADTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_EDGE,
+ bmw_FaceShellWalker_begin,
+ bmw_FaceShellWalker_step,
+ bmw_FaceShellWalker_yield,
+ sizeof(BMwShellWalker),
+ BMW_BREADTH_FIRST,
+ BM_EDGE, /* valid restrict masks */
};
static BMWalker bmw_IslandboundWalker_Type = {
- BM_LOOP,
- bmw_IslandboundWalker_begin,
- bmw_IslandboundWalker_step,
- bmw_IslandboundWalker_yield,
- sizeof(BMwIslandboundWalker),
- BMW_DEPTH_FIRST,
- BM_FACE, /* valid restrict masks */
+ BM_LOOP,
+ bmw_IslandboundWalker_begin,
+ bmw_IslandboundWalker_step,
+ bmw_IslandboundWalker_yield,
+ sizeof(BMwIslandboundWalker),
+ BMW_DEPTH_FIRST,
+ BM_FACE, /* valid restrict masks */
};
static BMWalker bmw_IslandWalker_Type = {
- BM_FACE,
- bmw_IslandWalker_begin,
- bmw_IslandWalker_step,
- bmw_IslandWalker_yield,
- sizeof(BMwIslandWalker),
- BMW_BREADTH_FIRST,
- BM_EDGE | BM_FACE, /* valid restrict masks */
+ BM_FACE,
+ bmw_IslandWalker_begin,
+ bmw_IslandWalker_step,
+ bmw_IslandWalker_yield,
+ sizeof(BMwIslandWalker),
+ BMW_BREADTH_FIRST,
+ BM_EDGE | BM_FACE, /* valid restrict masks */
};
static BMWalker bmw_IslandManifoldWalker_Type = {
- BM_FACE,
- bmw_IslandWalker_begin,
- bmw_IslandManifoldWalker_step, /* only difference with BMW_ISLAND */
- bmw_IslandWalker_yield,
- sizeof(BMwIslandWalker),
- BMW_BREADTH_FIRST,
- BM_EDGE | BM_FACE, /* valid restrict masks */
+ BM_FACE,
+ bmw_IslandWalker_begin,
+ bmw_IslandManifoldWalker_step, /* only difference with BMW_ISLAND */
+ bmw_IslandWalker_yield,
+ sizeof(BMwIslandWalker),
+ BMW_BREADTH_FIRST,
+ BM_EDGE | BM_FACE, /* valid restrict masks */
};
static BMWalker bmw_EdgeLoopWalker_Type = {
- BM_EDGE,
- bmw_EdgeLoopWalker_begin,
- bmw_EdgeLoopWalker_step,
- bmw_EdgeLoopWalker_yield,
- sizeof(BMwEdgeLoopWalker),
- BMW_DEPTH_FIRST,
- 0, /* valid restrict masks */ /* could add flags here but so far none are used */
+ BM_EDGE,
+ bmw_EdgeLoopWalker_begin,
+ bmw_EdgeLoopWalker_step,
+ bmw_EdgeLoopWalker_yield,
+ sizeof(BMwEdgeLoopWalker),
+ BMW_DEPTH_FIRST,
+ 0,
+ /* valid restrict masks */ /* could add flags here but so far none are used */
};
static BMWalker bmw_FaceLoopWalker_Type = {
- BM_EDGE,
- bmw_FaceLoopWalker_begin,
- bmw_FaceLoopWalker_step,
- bmw_FaceLoopWalker_yield,
- sizeof(BMwFaceLoopWalker),
- BMW_DEPTH_FIRST,
- 0, /* valid restrict masks */ /* could add flags here but so far none are used */
+ BM_EDGE,
+ bmw_FaceLoopWalker_begin,
+ bmw_FaceLoopWalker_step,
+ bmw_FaceLoopWalker_yield,
+ sizeof(BMwFaceLoopWalker),
+ BMW_DEPTH_FIRST,
+ 0,
+ /* valid restrict masks */ /* could add flags here but so far none are used */
};
static BMWalker bmw_EdgeringWalker_Type = {
- BM_EDGE,
- bmw_EdgeringWalker_begin,
- bmw_EdgeringWalker_step,
- bmw_EdgeringWalker_yield,
- sizeof(BMwEdgeringWalker),
- BMW_DEPTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_EDGE,
+ bmw_EdgeringWalker_begin,
+ bmw_EdgeringWalker_step,
+ bmw_EdgeringWalker_yield,
+ sizeof(BMwEdgeringWalker),
+ BMW_DEPTH_FIRST,
+ BM_EDGE, /* valid restrict masks */
};
static BMWalker bmw_EdgeboundaryWalker_Type = {
- BM_EDGE,
- bmw_EdgeboundaryWalker_begin,
- bmw_EdgeboundaryWalker_step,
- bmw_EdgeboundaryWalker_yield,
- sizeof(BMwEdgeboundaryWalker),
- BMW_DEPTH_FIRST,
- 0,
+ BM_EDGE,
+ bmw_EdgeboundaryWalker_begin,
+ bmw_EdgeboundaryWalker_step,
+ bmw_EdgeboundaryWalker_yield,
+ sizeof(BMwEdgeboundaryWalker),
+ BMW_DEPTH_FIRST,
+ 0,
};
static BMWalker bmw_UVEdgeWalker_Type = {
- BM_LOOP,
- bmw_UVEdgeWalker_begin,
- bmw_UVEdgeWalker_step,
- bmw_UVEdgeWalker_yield,
- sizeof(BMwUVEdgeWalker),
- BMW_DEPTH_FIRST,
- BM_EDGE, /* valid restrict masks */
+ BM_LOOP,
+ bmw_UVEdgeWalker_begin,
+ bmw_UVEdgeWalker_step,
+ bmw_UVEdgeWalker_yield,
+ sizeof(BMwUVEdgeWalker),
+ BMW_DEPTH_FIRST,
+ BM_EDGE, /* valid restrict masks */
};
static BMWalker bmw_ConnectedVertexWalker_Type = {
- BM_VERT,
- bmw_ConnectedVertexWalker_begin,
- bmw_ConnectedVertexWalker_step,
- bmw_ConnectedVertexWalker_yield,
- sizeof(BMwConnectedVertexWalker),
- BMW_BREADTH_FIRST,
- BM_VERT, /* valid restrict masks */
+ BM_VERT,
+ bmw_ConnectedVertexWalker_begin,
+ bmw_ConnectedVertexWalker_step,
+ bmw_ConnectedVertexWalker_yield,
+ sizeof(BMwConnectedVertexWalker),
+ BMW_BREADTH_FIRST,
+ BM_VERT, /* valid restrict masks */
};
BMWalker *bm_walker_types[] = {
- &bmw_VertShellWalker_Type, /* BMW_VERT_SHELL */
- &bmw_LoopShellWalker_Type, /* BMW_LOOP_SHELL */
- &bmw_LoopShellWireWalker_Type, /* BMW_LOOP_SHELL_WIRE */
- &bmw_FaceShellWalker_Type, /* BMW_FACE_SHELL */
- &bmw_EdgeLoopWalker_Type, /* BMW_EDGELOOP */
- &bmw_FaceLoopWalker_Type, /* BMW_FACELOOP */
- &bmw_EdgeringWalker_Type, /* BMW_EDGERING */
- &bmw_EdgeboundaryWalker_Type, /* BMW_EDGEBOUNDARY */
- &bmw_UVEdgeWalker_Type, /* BMW_LOOPDATA_ISLAND */
- &bmw_IslandboundWalker_Type, /* BMW_ISLANDBOUND */
- &bmw_IslandWalker_Type, /* BMW_ISLAND */
- &bmw_IslandManifoldWalker_Type, /* BMW_ISLAND_MANIFOLD */
- &bmw_ConnectedVertexWalker_Type, /* BMW_CONNECTED_VERTEX */
+ &bmw_VertShellWalker_Type, /* BMW_VERT_SHELL */
+ &bmw_LoopShellWalker_Type, /* BMW_LOOP_SHELL */
+ &bmw_LoopShellWireWalker_Type, /* BMW_LOOP_SHELL_WIRE */
+ &bmw_FaceShellWalker_Type, /* BMW_FACE_SHELL */
+ &bmw_EdgeLoopWalker_Type, /* BMW_EDGELOOP */
+ &bmw_FaceLoopWalker_Type, /* BMW_FACELOOP */
+ &bmw_EdgeringWalker_Type, /* BMW_EDGERING */
+ &bmw_EdgeboundaryWalker_Type, /* BMW_EDGEBOUNDARY */
+ &bmw_UVEdgeWalker_Type, /* BMW_LOOPDATA_ISLAND */
+ &bmw_IslandboundWalker_Type, /* BMW_ISLANDBOUND */
+ &bmw_IslandWalker_Type, /* BMW_ISLAND */
+ &bmw_IslandManifoldWalker_Type, /* BMW_ISLAND_MANIFOLD */
+ &bmw_ConnectedVertexWalker_Type, /* BMW_CONNECTED_VERTEX */
};
const int bm_totwalkers = ARRAY_SIZE(bm_walker_types);
diff --git a/source/blender/bmesh/intern/bmesh_walkers_private.h b/source/blender/bmesh/intern/bmesh_walkers_private.h
index 185c18d6777..3457a2b9187 100644
--- a/source/blender/bmesh/intern/bmesh_walkers_private.h
+++ b/source/blender/bmesh/intern/bmesh_walkers_private.h
@@ -26,75 +26,73 @@
extern BMWalker *bm_walker_types[];
extern const int bm_totwalkers;
-
/* Pointer hiding */
typedef struct BMwGenericWalker {
- Link link;
- int depth;
+ Link link;
+ int depth;
} BMwGenericWalker;
-
typedef struct BMwShellWalker {
- BMwGenericWalker header;
- BMEdge *curedge;
+ BMwGenericWalker header;
+ BMEdge *curedge;
} BMwShellWalker;
typedef struct BMwLoopShellWalker {
- BMwGenericWalker header;
- BMLoop *curloop;
+ BMwGenericWalker header;
+ BMLoop *curloop;
} BMwLoopShellWalker;
typedef struct BMwLoopShellWireWalker {
- BMwGenericWalker header;
- BMElem *curelem;
+ BMwGenericWalker header;
+ BMElem *curelem;
} BMwLoopShellWireWalker;
typedef struct BMwIslandboundWalker {
- BMwGenericWalker header;
- BMLoop *base;
- BMVert *lastv;
- BMLoop *curloop;
+ BMwGenericWalker header;
+ BMLoop *base;
+ BMVert *lastv;
+ BMLoop *curloop;
} BMwIslandboundWalker;
typedef struct BMwIslandWalker {
- BMwGenericWalker header;
- BMFace *cur;
+ BMwGenericWalker header;
+ BMFace *cur;
} BMwIslandWalker;
typedef struct BMwEdgeLoopWalker {
- BMwGenericWalker header;
- BMEdge *cur, *start;
- BMVert *lastv, *startv;
- BMFace *f_hub;
- bool is_boundary; /* boundary looping changes behavior */
- bool is_single; /* single means the edge verts are only connected to 1 face */
+ BMwGenericWalker header;
+ BMEdge *cur, *start;
+ BMVert *lastv, *startv;
+ BMFace *f_hub;
+ bool is_boundary; /* boundary looping changes behavior */
+ bool is_single; /* single means the edge verts are only connected to 1 face */
} BMwEdgeLoopWalker;
typedef struct BMwFaceLoopWalker {
- BMwGenericWalker header;
- BMLoop *l;
- bool no_calc;
+ BMwGenericWalker header;
+ BMLoop *l;
+ bool no_calc;
} BMwFaceLoopWalker;
typedef struct BMwEdgeringWalker {
- BMwGenericWalker header;
- BMLoop *l;
- BMEdge *wireedge;
+ BMwGenericWalker header;
+ BMLoop *l;
+ BMEdge *wireedge;
} BMwEdgeringWalker;
typedef struct BMwEdgeboundaryWalker {
- BMwGenericWalker header;
- BMEdge *e;
+ BMwGenericWalker header;
+ BMEdge *e;
} BMwEdgeboundaryWalker;
typedef struct BMwUVEdgeWalker {
- BMwGenericWalker header;
- BMLoop *l;
+ BMwGenericWalker header;
+ BMLoop *l;
} BMwUVEdgeWalker;
typedef struct BMwConnectedVertexWalker {
- BMwGenericWalker header;
- BMVert *curvert;
+ BMwGenericWalker header;
+ BMVert *curvert;
} BMwConnectedVertexWalker;
#endif /* __BMESH_WALKERS_PRIVATE_H__ */