optimize bmesh operations that use triangle BMFace's (dyn-topo and mesh conversion).
This commit is contained in:
@@ -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;
|
||||
|
@@ -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]);
|
||||
|
@@ -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);
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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__ */
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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 */
|
||||
|
Reference in New Issue
Block a user