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:
authorNicholas Bishop <nicholasbishop@gmail.com>2012-12-30 22:28:36 +0400
committerNicholas Bishop <nicholasbishop@gmail.com>2012-12-30 22:28:36 +0400
commit2e69b0cd0b26fb1e641536de5a81a02f4478065c (patch)
treead22e485234da0adb49fb114d70ef00b47235c23 /source/blender/blenkernel/intern/pbvh.c
parent2c9d22fe31dc20df9fecc6322bdb7cbe56783164 (diff)
Add dynamic topology support to the PBVH
* Add BLI_pbvh_build_bmesh(), similar to the other PBVH builders but specialized for BMesh. Whereas the PBVH leaf nodes for mesh and grids only store a start-index and count into the primitive indices array, the BMesh version uses GHashes to store the full set of faces and vertices in leaf nodes * Update PBVH iterator to handle BMesh * Make some of the pbvh.c functions non-static so they can be used by the new pbvh_bmesh code * The BLI_pbvh_bmesh_update_topology() function is the main reason for adding BMesh support to the PBVH. This function is used during a sculpt stroke to dynamically collapse edges that are particular short and subdivide edges that are particularly long.
Diffstat (limited to 'source/blender/blenkernel/intern/pbvh.c')
-rw-r--r--source/blender/blenkernel/intern/pbvh.c81
1 files changed, 65 insertions, 16 deletions
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index e9009050d4b..6e0209e7683 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -66,14 +66,14 @@ typedef struct PBVHIter {
int stackspace;
} PBVHIter;
-static void BB_reset(BB *bb)
+void BB_reset(BB *bb)
{
bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
}
/* Expand the bounding box to include a new coordinate */
-static void BB_expand(BB *bb, float co[3])
+void BB_expand(BB *bb, const float co[3])
{
int i;
for (i = 0; i < 3; ++i) {
@@ -83,7 +83,7 @@ static void BB_expand(BB *bb, float co[3])
}
/* Expand the bounding box to include another bounding box */
-static void BB_expand_with_bb(BB *bb, BB *bb2)
+void BB_expand_with_bb(BB *bb, BB *bb2)
{
int i;
for (i = 0; i < 3; ++i) {
@@ -93,7 +93,7 @@ static void BB_expand_with_bb(BB *bb, BB *bb2)
}
/* Return 0, 1, or 2 to indicate the widest axis of the bounding box */
-static int BB_widest_axis(BB *bb)
+int BB_widest_axis(const BB *bb)
{
float dim[3];
int i;
@@ -115,7 +115,7 @@ static int BB_widest_axis(BB *bb)
}
}
-static void BBC_update_centroid(BBC *bbc)
+void BBC_update_centroid(BBC *bbc)
{
int i;
for (i = 0; i < 3; ++i)
@@ -220,7 +220,7 @@ static int partition_indices_material(PBVH *bvh, int lo, int hi)
}
}
-static void grow_nodes(PBVH *bvh, int totnode)
+void pbvh_grow_nodes(PBVH *bvh, int totnode)
{
if (totnode > bvh->node_mem_count) {
PBVHNode *prev = bvh->nodes;
@@ -433,7 +433,7 @@ static void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
/* Add two child nodes */
bvh->nodes[node_index].children_offset = bvh->totnode;
- grow_nodes(bvh, bvh->totnode + 2);
+ pbvh_grow_nodes(bvh, bvh->totnode + 2);
/* Update parent node bounding box */
update_vb(bvh, &bvh->nodes[node_index], prim_bbc, offset, count);
@@ -601,6 +601,13 @@ void BLI_pbvh_free(PBVH *bvh)
if (node->face_vert_indices)
MEM_freeN(node->face_vert_indices);
BLI_pbvh_node_layer_disp_free(node);
+
+ if (node->bm_faces)
+ BLI_ghash_free(node->bm_faces, NULL, NULL);
+ if (node->bm_unique_verts)
+ BLI_ghash_free(node->bm_unique_verts, NULL, NULL);
+ if (node->bm_other_verts)
+ BLI_ghash_free(node->bm_other_verts, NULL, NULL);
}
}
@@ -620,6 +627,11 @@ void BLI_pbvh_free(PBVH *bvh)
if (bvh->prim_indices)
MEM_freeN(bvh->prim_indices);
+ if (bvh->bm_vert_to_node)
+ BLI_ghash_free(bvh->bm_vert_to_node, NULL, NULL);
+ if (bvh->bm_face_to_node)
+ BLI_ghash_free(bvh->bm_face_to_node, NULL, NULL);
+
MEM_freeN(bvh);
}
@@ -900,6 +912,11 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
float (*vnor)[3];
int n;
+ if (bvh->type == PBVH_BMESH) {
+ pbvh_bmesh_normals_update(nodes, totnode);
+ return;
+ }
+
if (bvh->type != PBVH_FACES)
return;
@@ -993,8 +1010,7 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
MEM_freeN(vnor);
}
-static void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes,
- int totnode, int flag)
+void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag)
{
int n;
@@ -1041,6 +1057,11 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
node->prim_indices,
node->totprim);
break;
+ case PBVH_BMESH:
+ node->draw_buffers =
+ GPU_build_bmesh_buffers(bvh->flags &
+ PBVH_DYNTOPO_SMOOTH_SHADING);
+ break;
}
node->flag &= ~PBVH_RebuildDrawBuffers;
@@ -1068,6 +1089,13 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
node->face_vert_indices,
bvh->show_diffuse_color);
break;
+ case PBVH_BMESH:
+ GPU_update_bmesh_buffers(node->draw_buffers,
+ bvh->bm,
+ node->bm_faces,
+ node->bm_unique_verts,
+ node->bm_other_verts);
+ break;
}
node->flag &= ~PBVH_UpdateDrawBuffers;
@@ -1222,6 +1250,12 @@ void BLI_pbvh_get_grid_key(const PBVH *bvh, CCGKey *key)
*key = bvh->gridkey;
}
+BMesh *BLI_pbvh_get_bmesh(PBVH *bvh)
+{
+ BLI_assert(bvh->type == PBVH_BMESH);
+ return bvh->bm;
+}
+
/***************************** Node Access ***********************************/
void BLI_pbvh_node_mark_update(PBVHNode *node)
@@ -1264,6 +1298,11 @@ void BLI_pbvh_node_num_verts(PBVH *bvh, PBVHNode *node, int *uniquevert, int *to
if (totvert) *totvert = node->uniq_verts + node->face_verts;
if (uniquevert) *uniquevert = node->uniq_verts;
break;
+ case PBVH_BMESH:
+ tot = BLI_ghash_size(node->bm_unique_verts);
+ if (totvert) *totvert = tot + BLI_ghash_size(node->bm_other_verts);
+ if (uniquevert) *uniquevert = tot;
+ break;
}
}
@@ -1279,6 +1318,7 @@ void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node, int **grid_indices, int
if (gridadj) *gridadj = bvh->gridadj;
break;
case PBVH_FACES:
+ case PBVH_BMESH:
if (grid_indices) *grid_indices = NULL;
if (totgrid) *totgrid = 0;
if (maxgrid) *maxgrid = 0;
@@ -1345,11 +1385,11 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
}
-static int ray_face_intersection(const float ray_start[3],
- const float ray_normal[3],
- const float *t0, const float *t1,
- const float *t2, const float *t3,
- float *fdist)
+int ray_face_intersection(const float ray_start[3],
+ const float ray_normal[3],
+ const float *t0, const float *t1,
+ const float *t2, const float *t3,
+ float *fdist)
{
float dist;
@@ -1455,7 +1495,7 @@ static int pbvh_grids_node_raycast(PBVH *bvh, PBVHNode *node,
return hit;
}
-int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
+int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
const float ray_start[3], const float ray_normal[3],
float *dist)
{
@@ -1473,6 +1513,9 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
hit |= pbvh_grids_node_raycast(bvh, node, origco,
ray_start, ray_normal, dist);
break;
+ case PBVH_BMESH:
+ hit = pbvh_bmesh_node_raycast(node, ray_start, ray_normal, dist, use_origco);
+ break;
}
return hit;
@@ -1803,12 +1846,18 @@ void pbvh_vertex_iter_init(PBVH *bvh, PBVHNode *node,
vi->vert_indices = vert_indices;
vi->mverts = verts;
+ if (bvh->type == PBVH_BMESH) {
+ BLI_ghashIterator_init(&vi->bm_unique_verts, node->bm_unique_verts);
+ BLI_ghashIterator_init(&vi->bm_other_verts, node->bm_other_verts);
+ vi->bm_vdata = &bvh->bm->vdata;
+ }
+
vi->gh = NULL;
if (vi->grids && mode == PBVH_ITER_UNIQUE)
vi->grid_hidden = bvh->grid_hidden;
vi->mask = NULL;
- if (!vi->grids)
+ if (bvh->type == PBVH_FACES)
vi->vmask = CustomData_get_layer(bvh->vdata, CD_PAINT_MASK);
}