diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-01-17 01:09:54 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-01-17 01:09:54 +0400 |
commit | 5ddc7d64a85d6e01e7eae1ed904bda635478a24e (patch) | |
tree | 50d1481f1eaf8ffba354ffebe9ac89c5f42ade55 /source/blender | |
parent | 7f513023d4fc730c63a26a445b5523498f554710 (diff) |
optimize bmesh operations that use triangle BMFace's (dyn-topo and mesh conversion).
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/intern/pbvh_bmesh.c | 85 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_log.c | 3 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_marking.c | 9 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh_conv.c | 13 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.c | 34 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_polygon.h | 3 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 36 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_skin.c | 16 |
8 files changed, 141 insertions, 58 deletions
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c index bb22175e2ad..639a7e3691f 100644 --- a/source/blender/blenkernel/intern/pbvh_bmesh.c +++ b/source/blender/blenkernel/intern/pbvh_bmesh.c @@ -53,7 +53,8 @@ static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index) GHASH_ITER (gh_iter, n->bm_faces) { BMFace *f = BLI_ghashIterator_getKey(&gh_iter); - BMIter bm_iter; + BMLoop *l_iter; + BMLoop *l_first; BMVert *v; void *node_val = SET_INT_IN_POINTER(node_index); @@ -61,7 +62,9 @@ static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index) BLI_ghash_insert(bvh->bm_face_to_node, f, node_val); /* Update vertices */ - BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) { + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + v = l_iter->v; if (!BLI_ghash_haskey(n->bm_unique_verts, v)) { if (BLI_ghash_haskey(bvh->bm_vert_to_node, v)) { if (!BLI_ghash_haskey(n->bm_other_verts, v)) @@ -74,7 +77,7 @@ static void pbvh_bmesh_node_finalize(PBVH *bvh, int node_index) } /* Update node bounding box */ BB_expand(&n->vb, v->co); - } + } while ((l_iter = l_iter->next) != l_first); } BLI_assert(n->vb.bmin[0] <= n->vb.bmax[0] && @@ -233,15 +236,16 @@ static int pbvh_bmesh_node_limit_ensure(PBVH *bvh, int node_index) prim_bbc = BLI_ghash_ptr_new("prim_bbc"); GHASH_ITER (gh_iter, bvh->nodes[node_index].bm_faces) { - BMIter bm_iter; - BMVert *v; BMFace *f = BLI_ghashIterator_getKey(&gh_iter); BBC *bbc = MEM_callocN(sizeof(BBC), "BBC"); + BMLoop *l_iter; + BMLoop *l_first; BB_reset((BB *)bbc); - BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) { - BB_expand((BB *)bbc, v->co); - } + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + BB_expand((BB *)bbc, l_iter->v->co); + } while ((l_iter = l_iter->next) != l_first); BBC_update_centroid(bbc); BLI_ghash_insert(prim_bbc, f, bbc); @@ -394,14 +398,18 @@ static void pbvh_bmesh_vert_remove(PBVH *bvh, BMVert *v) static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f) { PBVHNode *f_node; - BMIter bm_iter; BMVert *v; + BMLoop *l_iter; + BMLoop *l_first; + f_node = pbvh_bmesh_node_lookup(bvh, bvh->bm_face_to_node, f); /* Check if any of this face's vertices need to be removed * from the node */ - BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) { + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + v = l_iter->v; if (pbvh_bmesh_node_vert_use_count(bvh, f_node, v) == 1) { if (BLI_ghash_lookup(f_node->bm_unique_verts, v)) { /* Find a different node that uses 'v' */ @@ -419,7 +427,7 @@ static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f) BLI_ghash_remove(f_node->bm_other_verts, v, NULL, NULL); } } - } + } while ((l_iter = l_iter->next) != l_first); /* Remove face from node and top level */ BLI_ghash_remove(f_node->bm_faces, f, NULL, NULL); @@ -436,18 +444,21 @@ static BMVert *bm_triangle_other_vert_find(BMFace *triangle, const BMVert *v1, BLI_assert(v1 != v2); if (triangle->len == 3) { - BMIter iter; + BMLoop *l_iter; + BMLoop *l_first; BMVert *v, *other = NULL; - int found_v1 = FALSE, found_v2 = FALSE; + bool found_v1 = false, found_v2 = false; - BM_ITER_ELEM (v, &iter, triangle, BM_VERTS_OF_FACE) { + l_iter = l_first = BM_FACE_FIRST_LOOP(triangle); + do { + v = l_iter->v; if (v == v1) - found_v1 = TRUE; + found_v1 = true; else if (v == v2) - found_v2 = TRUE; + found_v2 = true; else other = v; - } + } while ((l_iter = l_iter->next) != l_first); if (found_v1 && found_v2) return other; @@ -508,7 +519,9 @@ static int edge_queue_tri_in_sphere(const EdgeQueue *q, BMFace *f) float c[3]; /* Get closest point in triangle to sphere center */ - BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3); + // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3); + BM_face_as_array_vert_tri(f, v); + closest_on_tri_to_point_v3(c, q->center, v[0]->co, v[1]->co, v[2]->co); /* Check if triangle intersects the sphere */ @@ -810,7 +823,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BMVert *v1, int ni; /* Get vertices, replace use of v2 with v1 */ - BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3); + // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3); + BM_face_as_array_vert_tri(f, v); for (i = 0; i < 3; i++) { if (v[i] == v2) v[i] = v1; @@ -845,7 +859,8 @@ static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BMVert *v1, BMVert *v[3]; int j; - BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f_del, (void **)v, 3); + // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f_del, (void **)v, 3); + BM_face_as_array_vert_tri(f_del, v); /* Check if any of the face's vertices are now unused, if so remove them from the PBVH */ @@ -965,12 +980,13 @@ int pbvh_bmesh_node_raycast(PBVHNode *node, const float ray_start[3], if (f->len == 3) { BMVert *v[3]; - BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3); + // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3); + BM_face_as_array_vert_tri(f, v); hit |= ray_face_intersection(ray_start, ray_normal, - v[0]->co, - v[1]->co, - v[2]->co, - NULL, dist); + v[0]->co, + v[1]->co, + v[2]->co, + NULL, dist); } } } @@ -1083,6 +1099,17 @@ int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode, return modified; } +BLI_INLINE void bm_face_as_array_index_tri(BMFace *f, int r_index[3]) +{ + BMLoop *l = BM_FACE_FIRST_LOOP(f); + + BLI_assert(f->len == 3); + + r_index[0] = BM_elem_index_get(l->v); l = l->next; + r_index[1] = BM_elem_index_get(l->v); l = l->next; + r_index[2] = BM_elem_index_get(l->v); +} + /* In order to perform operations on the original node coordinates * (such as raycast), store the node's triangles and vertices.*/ void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node) @@ -1120,15 +1147,19 @@ void BKE_pbvh_bmesh_node_save_orig(PBVHNode *node) /* Copy the triangles */ i = 0; GHASH_ITER (gh_iter, node->bm_faces) { - BMIter bm_iter; BMFace *f = BLI_ghashIterator_getKey(&gh_iter); + +#if 0 + BMIter bm_iter; BMVert *v; int j = 0; - BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) { node->bm_ortri[i][j] = BM_elem_index_get(v); j++; } +#else + bm_face_as_array_index_tri(f, node->bm_ortri[i]); +#endif i++; } node->bm_tot_ortri = i; diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index afcca88d7e4..2ad65bead07 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -215,7 +215,8 @@ static BMLogFace *bm_log_face_alloc(BMLog *log, BMFace *f) BLI_assert(f->len == 3); - BM_iter_as_array(NULL, BM_VERTS_OF_FACE, f, (void **)v, 3); + // 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]); diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 66a89c30e92..4e29756104a 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -710,12 +710,13 @@ void BM_editselection_plane(BMEditSelection *ese, float r_plane[3]) cross_v3_v3v3(r_plane, efa->no, vec); } else { - BMVert *verts[4] = {NULL}; - - BM_iter_as_array(NULL, BM_VERTS_OF_FACE, efa, (void **)verts, 4); - if (efa->len == 4) { + BMVert *verts[4] = {NULL}; float vecA[3], vecB[3]; + + // BM_iter_as_array(NULL, BM_VERTS_OF_FACE, efa, (void **)verts, 4); + BM_face_as_array_vert_quad(efa, verts); + sub_v3_v3v3(vecA, verts[3]->co, verts[2]->co); sub_v3_v3v3(vecB, verts[0]->co, verts[1]->co); add_v3_v3v3(r_plane, vecA, vecB); diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.c b/source/blender/bmesh/intern/bmesh_mesh_conv.c index d92526fbed2..c1664f97944 100644 --- a/source/blender/bmesh/intern/bmesh_mesh_conv.c +++ b/source/blender/bmesh/intern/bmesh_mesh_conv.c @@ -174,7 +174,6 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, bool set_key, int act_key_nr) BMVert *v, **vt = NULL, **verts = NULL; BMEdge *e, **fedges = NULL, **et = NULL; BMFace *f; - BMLoop *l; BLI_array_declare(fedges); float (*keyco)[3] = NULL; int *keyi; @@ -343,7 +342,8 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, bool set_key, int act_key_nr) mpoly = me->mpoly; for (i = 0; i < me->totpoly; i++, mpoly++) { - BMIter iter; + BMLoop *l_iter; + BMLoop *l_first; BLI_array_empty(fedges); BLI_array_empty(verts); @@ -401,11 +401,12 @@ void BM_mesh_bm_from_me(BMesh *bm, Mesh *me, bool set_key, int act_key_nr) f->mat_nr = mpoly->mat_nr; if (i == me->act_face) bm->act_face = f; - j = 0; - BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, j) { + j = mpoly->loopstart; + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { /* Save index of correspsonding MLoop */ - CustomData_to_bmesh_block(&me->ldata, &bm->ldata, mpoly->loopstart + j, &l->head.data, true); - } + 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); diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c index 19b7de6c550..f7dc143104c 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.c +++ b/source/blender/bmesh/intern/bmesh_polygon.c @@ -1080,3 +1080,37 @@ void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len) } } } + + +/** + * Small utility functions for fast access + * + * faster alternative to: + * BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 3); + */ +void BM_face_as_array_vert_tri(BMFace *f, BMVert *r_verts[3]) +{ + BMLoop *l = BM_FACE_FIRST_LOOP(f); + + 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; +} + +/** + * faster alternative to: + * BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 4); + */ +void BM_face_as_array_vert_quad(BMFace *f, BMVert *r_verts[4]) +{ + BMLoop *l = BM_FACE_FIRST_LOOP(f); + + 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; +} diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h index 0b888a3efd1..a0c6ac5eeaa 100644 --- a/source/blender/bmesh/intern/bmesh_polygon.h +++ b/source/blender/bmesh/intern/bmesh_polygon.h @@ -50,4 +50,7 @@ void BM_face_triangulate(BMesh *bm, BMFace *f, float (*projectverts)[3], void BM_face_legal_splits(BMesh *bm, BMFace *f, BMLoop *(*loops)[2], int len); +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]); + #endif /* __BMESH_POLYGON_H__ */ diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 5f9f68e9c99..c1eb7bdbbac 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1925,15 +1925,17 @@ static int gpu_bmesh_vert_visible_count(GHash *bm_unique_verts, /* Return TRUE if all vertices in the face are visible, FALSE otherwise */ static int gpu_bmesh_face_visible(BMFace *f) { - BMIter bm_iter; - BMVert *v; + BMLoop *l_iter; + BMLoop *l_first; - BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) { - if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) - return FALSE; - } + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + if (BM_elem_flag_test(l_iter->v, BM_ELEM_HIDDEN)) { + return false; + } + } while ((l_iter = l_iter->next) != l_first); - return TRUE; + return true; } /* Return the total number of visible faces */ @@ -2017,19 +2019,20 @@ void GPU_update_bmesh_buffers(GPU_Buffers *buffers, float fmask = 0; int i; - BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 3); + // BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void**)v, 3); + BM_face_as_array_vert_tri(f, v); /* Average mask value */ for (i = 0; i < 3; i++) { fmask += *((float*)CustomData_bmesh_get(&bm->vdata, - v[i]->head.data, - CD_PAINT_MASK)); + v[i]->head.data, + CD_PAINT_MASK)); } fmask /= 3.0f; for (i = 0; i < 3; i++) { gpu_bmesh_vert_to_buffer_copy(v[i], bm, vert_data, - &v_index, f->no, &fmask); + &v_index, f->no, &fmask); } } } @@ -2063,12 +2066,15 @@ void GPU_update_bmesh_buffers(GPU_Buffers *buffers, GHashIterator gh_iter; GHASH_ITER (gh_iter, bm_faces) { - BMIter bm_iter; BMFace *f = BLI_ghashIterator_getKey(&gh_iter); - BMVert *v; if (gpu_bmesh_face_visible(f)) { - BM_ITER_ELEM (v, &bm_iter, f, BM_VERTS_OF_FACE) { + BMLoop *l_iter; + BMLoop *l_first; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + BMVert *v = l_iter->v; if (use_short) { unsigned short *elem = tri_data; (*elem) = BM_elem_index_get(v); @@ -2081,7 +2087,7 @@ void GPU_update_bmesh_buffers(GPU_Buffers *buffers, elem++; tri_data = elem; } - } + } while ((l_iter = l_iter->next) != l_first); } } diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index a73d52a0a63..81c53185825 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -1278,7 +1278,8 @@ static void skin_fix_hole_no_good_verts(BMesh *bm, Frame *frame, BMFace *split_f return; /* Get split face's verts */ - BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)verts, 4); + // BM_iter_as_array(bm, BM_VERTS_OF_FACE, split_face, (void **)verts, 4); + BM_face_as_array_vert_quad(split_face, verts); skin_choose_quad_bridge_order(verts, frame->verts, best_order); /* Delete split face and merge */ @@ -1314,16 +1315,21 @@ static void skin_hole_detach_partially_attached_frame(BMesh *bm, Frame *frame) } -static void quad_from_tris(BMesh *bm, BMEdge *e, BMFace *adj[2], BMVert *ndx[4]) +static void quad_from_tris(BMEdge *e, BMFace *adj[2], BMVert *ndx[4]) { BMVert *tri[2][3]; BMVert *opp = NULL; int i, j; BLI_assert(adj[0]->len == 3 && adj[1]->len == 3); - + +#if 0 BM_iter_as_array(bm, BM_VERTS_OF_FACE, adj[0], (void **)tri[0], 3); BM_iter_as_array(bm, BM_VERTS_OF_FACE, adj[1], (void **)tri[1], 3); +#else + BM_face_as_array_vert_tri(adj[0], tri[0]); + BM_face_as_array_vert_tri(adj[1], tri[1]); +#endif /* Find what the second tri has that the first doesn't */ for (i = 0; i < 3; i++) { @@ -1354,7 +1360,7 @@ static void add_quad_from_tris(SkinOutput *so, BMEdge *e, BMFace *adj[2]) { BMVert *quad[4]; - quad_from_tris(so->bm, e, adj, quad); + quad_from_tris(e, adj, quad); add_poly(so, quad[0], quad[1], quad[2], quad[3]); } @@ -1381,7 +1387,7 @@ static void hull_merge_triangles(SkinOutput *so, const SkinModifierData *smd) /* Construct quad using the two triangles adjacent to * the edge */ - quad_from_tris(so->bm, e, adj, quad); + quad_from_tris(e, adj, quad); /* Calculate a score for the quad, higher score for * triangles being closer to coplanar */ |