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>2013-01-17 02:56:08 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-01-17 02:56:08 +0400
commit458533628596497c8f15175812932ebf986f5d0f (patch)
treef7bc5ef26db1fd0d70c5f1d4f1dd488b1cec4bbc /source/blender/blenkernel/intern/pbvh_bmesh.c
parent9e7b954ed02ca54a0225924eab207945b296bed0 (diff)
speed-up dyn-topo by storing the edge-loops rather then edge-faces.
- no need for bm_triangle_other_vert_find(), the other vert is known relative to the loop. - no need for bm_face_edge_backwards(), the verts are in order in the loop.
Diffstat (limited to 'source/blender/blenkernel/intern/pbvh_bmesh.c')
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c116
1 files changed, 33 insertions, 83 deletions
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 639a7e3691f..46324b4207b 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -437,60 +437,10 @@ static void pbvh_bmesh_face_remove(PBVH *bvh, BMFace *f)
BM_log_face_removed(bvh->bm_log, f);
}
-static BMVert *bm_triangle_other_vert_find(BMFace *triangle, const BMVert *v1,
- const BMVert *v2)
-{
- BLI_assert(triangle->len == 3);
- BLI_assert(v1 != v2);
-
- if (triangle->len == 3) {
- BMLoop *l_iter;
- BMLoop *l_first;
- BMVert *v, *other = NULL;
- bool found_v1 = false, found_v2 = false;
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(triangle);
- do {
- v = l_iter->v;
- if (v == v1)
- found_v1 = true;
- else if (v == v2)
- found_v2 = true;
- else
- other = v;
- } while ((l_iter = l_iter->next) != l_first);
-
- if (found_v1 && found_v2)
- return other;
- }
-
- BLI_assert(0);
- return NULL;
-}
-
-static void pbvh_bmesh_edge_faces(BLI_Buffer *buf, BMEdge *e)
+static void pbvh_bmesh_edge_loops(BLI_Buffer *buf, BMEdge *e)
{
BLI_buffer_resize(buf, BM_edge_face_count(e));
- BM_iter_as_array(NULL, BM_FACES_OF_EDGE, e, buf->data, buf->count);
-}
-
-/* TODO: maybe a better way to do this, if not then this should go to
- * bmesh_queries */
-static int bm_face_edge_backwards(BMFace *f, BMEdge *e)
-{
- BMIter bm_iter;
- BMLoop *l, *l1 = NULL, *l2 = NULL;
-
- BM_ITER_ELEM (l, &bm_iter, f, BM_LOOPS_OF_FACE) {
- if (l->v == e->v1)
- l1 = l;
- else if (l->v == e->v2)
- l2 = l;
- }
-
- BLI_assert(l1 && l2);
- BLI_assert(l1->next == l2 || l2->next == l1);
- return l2->next == l1;
+ BM_iter_as_array(NULL, BM_LOOPS_OF_EDGE, e, buf->data, buf->count);
}
static void pbvh_bmesh_node_drop_orig(PBVHNode *node)
@@ -668,25 +618,26 @@ static void short_edge_queue_create(EdgeQueue *q, BLI_mempool *pool,
/*************************** Topology update **************************/
static void pbvh_bmesh_split_edge(PBVH *bvh, EdgeQueue *q, BLI_mempool *pool,
- BMEdge *e, BLI_Buffer *edge_faces)
+ BMEdge *e, BLI_Buffer *edge_loops)
{
BMVert *v_new;
float mid[3];
int i, node_index;
/* Get all faces adjacent to the edge */
- pbvh_bmesh_edge_faces(edge_faces, e);
+ pbvh_bmesh_edge_loops(edge_loops, e);
/* Create a new vertex in current node at the edge's midpoint */
mid_v3_v3v3(mid, e->v1->co, e->v2->co);
node_index = GET_INT_FROM_POINTER(BLI_ghash_lookup(bvh->bm_vert_to_node,
- e->v1));
+ e->v1));
v_new = pbvh_bmesh_vert_create(bvh, node_index, mid, e->v1);
/* For each face, add two new triangles and delete the original */
- for (i = 0; i < edge_faces->count; i++) {
- BMFace *f_adj = BLI_buffer_at(edge_faces, BMFace *, i);
+ for (i = 0; i < edge_loops->count; i++) {
+ BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i);
+ BMFace *f_adj = l_adj->f;
BMFace *f_new;
BMVert *opp, *v1, *v2;
void *nip;
@@ -700,15 +651,13 @@ static void pbvh_bmesh_split_edge(PBVH *bvh, EdgeQueue *q, BLI_mempool *pool,
bvh->nodes[ni].flag |= PBVH_UpdateDrawBuffers;
/* Find the vertex not in the edge */
- opp = bm_triangle_other_vert_find(f_adj, e->v1, e->v2);
+ opp = l_adj->prev->v;
/* Get e->v1 and e->v2 in the order they appear in the
* existing face so that the new faces' winding orders
* match */
- v1 = e->v1;
- v2 = e->v2;
- if (bm_face_edge_backwards(f_adj, e))
- SWAP(BMVert *, v1, v2);
+ v1 = l_adj->v;
+ v2 = l_adj->next->v;
if (ni != node_index && i == 0)
pbvh_bmesh_vert_ownership_transfer(bvh, &bvh->nodes[ni], v_new);
@@ -744,8 +693,8 @@ static void pbvh_bmesh_split_edge(PBVH *bvh, EdgeQueue *q, BLI_mempool *pool,
}
static int pbvh_bmesh_subdivide_long_edges(PBVH *bvh, EdgeQueue *q,
- BLI_mempool *pool,
- BLI_Buffer *edge_faces)
+ BLI_mempool *pool,
+ BLI_Buffer *edge_loops)
{
int any_subdivided = FALSE;
@@ -777,30 +726,31 @@ static int pbvh_bmesh_subdivide_long_edges(PBVH *bvh, EdgeQueue *q,
any_subdivided = TRUE;
- pbvh_bmesh_split_edge(bvh, q, pool, e, edge_faces);
+ pbvh_bmesh_split_edge(bvh, q, pool, e, edge_loops);
}
return any_subdivided;
}
static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BMVert *v1,
- BMVert *v2, GHash *deleted_verts,
- BLI_Buffer *edge_faces,
- BLI_Buffer *deleted_faces)
+ BMVert *v2, GHash *deleted_verts,
+ BLI_Buffer *edge_loops,
+ BLI_Buffer *deleted_faces)
{
BMIter bm_iter;
BMFace *f;
int i;
/* Get all faces adjacent to the edge */
- pbvh_bmesh_edge_faces(edge_faces, e);
+ pbvh_bmesh_edge_loops(edge_loops, e);
/* Remove the merge vertex from the PBVH */
pbvh_bmesh_vert_remove(bvh, v2);
/* Remove all faces adjacent to the edge */
- for (i = 0; i < edge_faces->count; i++) {
- BMFace *f_adj = BLI_buffer_at(edge_faces, BMFace *, i);
+ for (i = 0; i < edge_loops->count; i++) {
+ BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i);
+ BMFace *f_adj = l_adj->f;
pbvh_bmesh_face_remove(bvh, f_adj);
BM_face_kill(bvh->bm, f_adj);
@@ -899,9 +849,9 @@ static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e, BMVert *v1,
}
static int pbvh_bmesh_collapse_short_edges(PBVH *bvh, EdgeQueue *q,
- BLI_mempool *pool,
- BLI_Buffer *edge_faces,
- BLI_Buffer *deleted_faces)
+ BLI_mempool *pool,
+ BLI_Buffer *edge_loops,
+ BLI_Buffer *deleted_faces)
{
float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
GHash *deleted_verts;
@@ -943,8 +893,8 @@ static int pbvh_bmesh_collapse_short_edges(PBVH *bvh, EdgeQueue *q,
any_collapsed = TRUE;
pbvh_bmesh_collapse_edge(bvh, e, v1, v2,
- deleted_verts, edge_faces,
- deleted_faces);
+ deleted_verts, edge_loops,
+ deleted_faces);
}
BLI_ghash_free(deleted_verts, NULL, NULL);
@@ -1056,7 +1006,7 @@ void BKE_pbvh_build_bmesh(PBVH *bvh, BMesh *bm, int smooth_shading,
int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
const float center[3], float radius)
{
- BLI_buffer_declare_static(BMFace *, edge_faces, BLI_BUFFER_NOP, 8);
+ BLI_buffer_declare_static(BMFace *, edge_loops, BLI_BUFFER_NOP, 8);
BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
int modified = FALSE;
@@ -1065,10 +1015,10 @@ int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
if (mode & PBVH_Collapse) {
EdgeQueue q;
BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert) * 2,
- 128, 128, 0);
+ 128, 128, 0);
short_edge_queue_create(&q, queue_pool, bvh, center, radius);
- pbvh_bmesh_collapse_short_edges(bvh, &q, queue_pool, &edge_faces,
- &deleted_faces);
+ pbvh_bmesh_collapse_short_edges(bvh, &q, queue_pool, &edge_loops,
+ &deleted_faces);
BLI_heap_free(q.heap, NULL);
BLI_mempool_destroy(queue_pool);
}
@@ -1076,9 +1026,9 @@ int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
if (mode & PBVH_Subdivide) {
EdgeQueue q;
BLI_mempool *queue_pool = BLI_mempool_create(sizeof(BMVert) * 2,
- 128, 128, 0);
+ 128, 128, 0);
long_edge_queue_create(&q, queue_pool, bvh, center, radius);
- pbvh_bmesh_subdivide_long_edges(bvh, &q, queue_pool, &edge_faces);
+ pbvh_bmesh_subdivide_long_edges(bvh, &q, queue_pool, &edge_loops);
BLI_heap_free(q.heap, NULL);
BLI_mempool_destroy(queue_pool);
}
@@ -1093,7 +1043,7 @@ int BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
node->flag &= ~PBVH_UpdateTopology;
}
}
- BLI_buffer_free(&edge_faces);
+ BLI_buffer_free(&edge_loops);
BLI_buffer_free(&deleted_faces);
return modified;