diff options
Diffstat (limited to 'source/blender/bmesh/intern/bmesh_construct.c')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_construct.c | 114 |
1 files changed, 70 insertions, 44 deletions
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c index e12110b31ca..fddb7b4bf2c 100644 --- a/source/blender/bmesh/intern/bmesh_construct.c +++ b/source/blender/bmesh/intern/bmesh_construct.c @@ -53,7 +53,7 @@ static void bm_loop_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, * \brief Make Quad/Triangle * * Creates a new quad or triangle from a list of 3 or 4 vertices. - * If \a nodouble is TRUE, then a check is done to see if a face + * If \a no_double is true, then a check is done to see if a face * with these vertices already exists and returns it instead. * * If a pointer to an example face is provided, it's custom data @@ -65,16 +65,16 @@ static void bm_loop_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, BMFace *BM_face_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4, - const BMFace *example, const int nodouble) + const BMFace *example, const bool no_double) { BMVert *vtar[4] = {v1, v2, v3, v4}; - return BM_face_create_quad_tri_v(bm, vtar, v4 ? 4 : 3, example, nodouble); + return BM_face_create_quad_tri_v(bm, vtar, v4 ? 4 : 3, example, no_double); } -BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFace *example, const int nodouble) +BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFace *example, const bool no_double) { BMFace *f = NULL; - int is_overlap = FALSE; + bool is_overlap = false; /* sanity check - debug mode only */ if (len == 3) { @@ -97,7 +97,7 @@ BMFace *BM_face_create_quad_tri_v(BMesh *bm, BMVert **verts, int len, const BMFa } - if (nodouble) { + if (no_double) { /* check if face exists or overlaps */ is_overlap = BM_face_exists(verts, len, &f); } @@ -173,15 +173,16 @@ void BM_face_copy_shared(BMesh *bm, BMFace *f) */ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, const int create_flag) { - BMEdge **edges2 = BLI_array_alloca_and_count(edges2, len); - BMVert **verts = BLI_array_alloca_and_count(verts, len + 1); - int e2_index = 0; - int v_index = 0; + BMEdge **edges_sort = BLI_array_alloca(edges_sort, len); + BMVert **verts_sort = BLI_array_alloca(verts_sort, len + 1); + int esort_index = 0; + int vsort_index = 0; BMFace *f = NULL; BMEdge *e; BMVert *v, *ev1, *ev2; - int i, /* j, */ v1found, reverse; + int i; + bool is_v1_found, is_reverse; /* this code is hideous, yeek. I'll have to think about ways of @@ -189,10 +190,7 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i * _and_ the old bmesh_mf functions, so its kindof smashed together * - joeedh */ - if (!len || !v1 || !v2 || !edges || !bm) { - BLI_assert(0); - return NULL; - } + BLI_assert(len && v1 && v2 && edges && bm); /* put edges in correct order */ for (i = 0; i < len; i++) { @@ -209,14 +207,19 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i SWAP(BMVert *, ev1, ev2); } - verts[v_index++] = ev1; + verts_sort[vsort_index++] = ev1; v = ev2; e = edges[0]; do { BMEdge *e2 = e; - verts[v_index++] = v; - edges2[e2_index++] = e; + /* vertex array is (len + 1) */ + if (UNLIKELY(vsort_index > len)) { + goto err; /* vertex in loop twice */ + } + + verts_sort[vsort_index++] = v; + edges_sort[esort_index++] = e; /* we only flag the verts to check if they are in the face more then once */ BM_ELEM_API_FLAG_ENABLE(v, _FLAG_MV); @@ -229,66 +232,67 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i } } while (e2 != e); - if (e2 == e) + if (UNLIKELY(e2 == e)) { goto err; /* the edges do not form a closed loop */ + } e = e2; } while (e != edges[0]); - if (BLI_array_count(edges2) != len) { + if (UNLIKELY(esort_index != len)) { goto err; /* we didn't use all edges in forming the boundary loop */ } /* ok, edges are in correct order, now ensure they are going * in the correct direction */ - v1found = reverse = FALSE; + is_v1_found = is_reverse = false; for (i = 0; i < len; i++) { - if (BM_vert_in_edge(edges2[i], v1)) { + if (BM_vert_in_edge(edges_sort[i], v1)) { /* see if v1 and v2 are in the same edge */ - if (BM_vert_in_edge(edges2[i], v2)) { + if (BM_vert_in_edge(edges_sort[i], v2)) { /* if v1 is shared by the *next* edge, then the winding * is incorrect */ - if (BM_vert_in_edge(edges2[(i + 1) % len], v1)) { - reverse = TRUE; + if (BM_vert_in_edge(edges_sort[(i + 1) % len], v1)) { + is_reverse = true; break; } } - v1found = TRUE; + is_v1_found = true; } - if ((v1found == FALSE) && BM_vert_in_edge(edges2[i], v2)) { - reverse = TRUE; + if ((is_v1_found == false) && BM_vert_in_edge(edges_sort[i], v2)) { + is_reverse = true; break; } } - if (reverse) { + if (is_reverse) { for (i = 0; i < len / 2; i++) { - v = verts[i]; - verts[i] = verts[len - i - 1]; - verts[len - i - 1] = v; + v = verts_sort[i]; + verts_sort[i] = verts_sort[len - i - 1]; + verts_sort[len - i - 1] = v; } } for (i = 0; i < len; i++) { - edges2[i] = BM_edge_exists(verts[i], verts[(i + 1) % len]); - if (!edges2[i]) { + edges_sort[i] = BM_edge_exists(verts_sort[i], verts_sort[(i + 1) % len]); + if (UNLIKELY(edges_sort[i] == NULL)) { goto err; } /* check if vert is in face more then once. if the flag is disabled. we've already visited */ - if (!BM_ELEM_API_FLAG_TEST(verts[i], _FLAG_MV)) { + if (UNLIKELY(!BM_ELEM_API_FLAG_TEST(verts_sort[i], _FLAG_MV))) { goto err; } - BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV); + BM_ELEM_API_FLAG_DISABLE(verts_sort[i], _FLAG_MV); } - f = BM_face_create(bm, verts, edges2, len, create_flag); + f = BM_face_create(bm, verts_sort, edges_sort, len, create_flag); /* clean up flags */ for (i = 0; i < len; i++) { - BM_ELEM_API_FLAG_DISABLE(edges2[i], _FLAG_MF); + BM_ELEM_API_FLAG_DISABLE(edges_sort[i], _FLAG_MF); } return f; @@ -296,10 +300,9 @@ BMFace *BM_face_create_ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, i err: for (i = 0; i < len; i++) { BM_ELEM_API_FLAG_DISABLE(edges[i], _FLAG_MF); - /* vert count may != len */ - if (i < BLI_array_count(verts)) { - BM_ELEM_API_FLAG_DISABLE(verts[i], _FLAG_MV); - } + } + for (i = 0; i < vsort_index; i++) { + BM_ELEM_API_FLAG_DISABLE(verts_sort[i], _FLAG_MV); } return NULL; @@ -790,7 +793,7 @@ void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *sour /* First we copy select */ if (BM_elem_flag_test((BMElem *)sheader, BM_ELEM_SELECT)) { - BM_elem_select_set(target_mesh, (BMElem *)target, TRUE); + BM_elem_select_set(target_mesh, (BMElem *)target, true); } /* Now we copy flags */ @@ -817,6 +820,8 @@ void BM_elem_attrs_copy(BMesh *source_mesh, BMesh *target_mesh, const void *sour BMesh *BM_mesh_copy(BMesh *bm_old) { +#define USE_FAST_FACE_COPY + BMesh *bm_new; BMVert *v, *v2, **vtable = NULL; BMEdge *e, *e2, **edges = NULL, **etable = NULL; @@ -824,6 +829,10 @@ BMesh *BM_mesh_copy(BMesh *bm_old) BLI_array_declare(edges); BMLoop *l, /* *l2, */ **loops = NULL; BLI_array_declare(loops); +#ifdef USE_FAST_FACE_COPY + BMVert **verts = NULL; + BLI_array_declare(verts); +#endif BMFace *f, *f2, **ftable = NULL; BMEditSelection *ese; BMIter iter, liter; @@ -891,12 +900,24 @@ BMesh *BM_mesh_copy(BMesh *bm_old) BLI_array_grow_items(loops, f->len); BLI_array_grow_items(edges, f->len); +#ifdef USE_FAST_FACE_COPY + BLI_array_empty(verts); + BLI_array_grow_items(verts, f->len); +#endif + l = BM_iter_new(&liter, bm_old, BM_LOOPS_OF_FACE, f); for (j = 0; j < f->len; j++, l = BM_iter_step(&liter)) { loops[j] = l; edges[j] = etable[BM_elem_index_get(l->e)]; + +#ifdef USE_FAST_FACE_COPY + verts[j] = vtable[BM_elem_index_get(l->v)]; +#endif } +#ifdef USE_FAST_FACE_COPY + f2 = BM_face_create(bm_new, verts, edges, f->len, BM_CREATE_SKIP_CD); +#else v = vtable[BM_elem_index_get(loops[0]->v)]; v2 = vtable[BM_elem_index_get(loops[1]->v)]; @@ -906,6 +927,8 @@ BMesh *BM_mesh_copy(BMesh *bm_old) } f2 = BM_face_create_ngon(bm_new, v, v2, edges, f->len, BM_CREATE_SKIP_CD); +#endif + if (UNLIKELY(f2 == NULL)) { continue; } @@ -961,9 +984,12 @@ BMesh *BM_mesh_copy(BMesh *bm_old) MEM_freeN(vtable); MEM_freeN(ftable); +#ifdef USE_FAST_FACE_COPY + BLI_array_free(verts); +#endif + BLI_array_free(loops); BLI_array_free(edges); - return bm_new; } |