[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [53441] trunk/blender/source/blender/ blenkernel: Add dynamic topology support to the PBVH
Nicholas Bishop
nicholasbishop at gmail.com
Sun Dec 30 19:28:37 CET 2012
Revision: 53441
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=53441
Author: nicholasbishop
Date: 2012-12-30 18:28:36 +0000 (Sun, 30 Dec 2012)
Log Message:
-----------
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.
Modified Paths:
--------------
trunk/blender/source/blender/blenkernel/BKE_pbvh.h
trunk/blender/source/blender/blenkernel/CMakeLists.txt
trunk/blender/source/blender/blenkernel/intern/pbvh.c
trunk/blender/source/blender/blenkernel/intern/pbvh_intern.h
Added Paths:
-----------
trunk/blender/source/blender/blenkernel/intern/pbvh_bmesh.c
Modified: trunk/blender/source/blender/blenkernel/BKE_pbvh.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_pbvh.h 2012-12-30 18:28:10 UTC (rev 53440)
+++ trunk/blender/source/blender/blenkernel/BKE_pbvh.h 2012-12-30 18:28:36 UTC (rev 53441)
@@ -27,13 +27,18 @@
*/
#include "BLI_bitmap.h"
+#include "BLI_ghash.h"
+#include "BLI_utildefines.h"
+/* Needed for BMesh functions used in the PBVH iterator macro */
+#include "bmesh.h"
+
struct CCGElem;
struct CCGKey;
struct CustomData;
struct DMFlagMat;
struct DMGridAdjacency;
-struct ListBase;
+struct GHash;
struct MFace;
struct MVert;
struct PBVH;
@@ -63,6 +68,9 @@
struct DMGridAdjacency *gridadj, int totgrid,
struct CCGKey *key, void **gridfaces, struct DMFlagMat *flagmats,
unsigned int **grid_hidden);
+void BLI_pbvh_build_bmesh(PBVH *bvh, struct BMesh *bm, int smooth_shading,
+ struct BMLog *log);
+
void BLI_pbvh_free(PBVH *bvh);
/* Hierarchical Search in the BVH, two methods:
@@ -86,7 +94,7 @@
const float ray_start[3], const float ray_normal[3],
int original);
-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);
@@ -100,6 +108,7 @@
typedef enum {
PBVH_FACES,
PBVH_GRIDS,
+ PBVH_BMESH
} PBVHType;
PBVHType BLI_pbvh_type(const PBVH *bvh);
@@ -110,6 +119,17 @@
/* multires level, only valid for type == PBVH_GRIDS */
void BLI_pbvh_get_grid_key(const PBVH *pbvh, struct CCGKey *key);
+/* Only valid for type == PBVH_BMESH */
+BMesh *BLI_pbvh_get_bmesh(PBVH *pbvh);
+void BLI_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size);
+
+typedef enum {
+ PBVH_Subdivide = 1,
+ PBVH_Collapse = 2,
+} PBVHTopologyUpdateMode;
+int BLI_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
+ const float center[3], float radius);
+
/* Node Access */
typedef enum {
@@ -122,12 +142,15 @@
PBVH_UpdateRedraw = 32,
PBVH_RebuildDrawBuffers = 64,
- PBVH_FullyHidden = 128
+ PBVH_FullyHidden = 128,
+
+ PBVH_UpdateTopology = 256,
} PBVHNodeFlags;
void BLI_pbvh_node_mark_update(PBVHNode *node);
void BLI_pbvh_node_mark_rebuild_draw(PBVHNode *node);
void BLI_pbvh_node_fully_hidden_set(PBVHNode *node, int fully_hidden);
+void BLI_pbvh_node_mark_topology_update(PBVHNode *node);
void BLI_pbvh_node_get_grids(PBVH *bvh, PBVHNode *node,
int **grid_indices, int *totgrid, int *maxgrid, int *gridsize,
@@ -147,6 +170,11 @@
/* test if AABB is at least partially outside the planes' volume */
int BLI_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data);
+struct GHash *BLI_pbvh_bmesh_node_unique_verts(PBVHNode *node);
+struct GHash *BLI_pbvh_bmesh_node_other_verts(PBVHNode *node);
+void BLI_pbvh_bmesh_node_save_orig(PBVHNode *node);
+void BLI_pbvh_bmesh_after_stroke(PBVH *bvh);
+
/* Update Normals/Bounding Box/Draw Buffers/Redraw and clear flags */
void BLI_pbvh_update(PBVH *bvh, int flags, float (*face_nors)[3]);
@@ -169,7 +197,6 @@
void BLI_pbvh_apply_vertCos(struct PBVH *pbvh, float (*vertCos)[3]);
int BLI_pbvh_isDeformed(struct PBVH *pbvh);
-
/* Vertex Iterator */
/* this iterator has quite a lot of code, but it's designed to:
@@ -205,9 +232,15 @@
int *vert_indices;
float *vmask;
+ /* bmesh */
+ struct GHashIterator bm_unique_verts;
+ struct GHashIterator bm_other_verts;
+ struct CustomData *bm_vdata;
+
/* result: these are all computed in the macro, but we assume
* that compiler optimization's will skip the ones we don't use */
struct MVert *mvert;
+ struct BMVert *bm_vert;
float *co;
short *no;
float *fno;
@@ -249,7 +282,7 @@
continue; \
} \
} \
- else { \
+ else if (vi.mverts) { \
vi.mvert = &vi.mverts[vi.vert_indices[vi.gx]]; \
if (mode == PBVH_ITER_UNIQUE && vi.mvert->flag & ME_HIDE) \
continue; \
@@ -258,6 +291,24 @@
if (vi.vmask) \
vi.mask = &vi.vmask[vi.vert_indices[vi.gx]]; \
} \
+ else { \
+ if (!BLI_ghashIterator_isDone(&vi.bm_unique_verts)) {\
+ vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_unique_verts); \
+ BLI_ghashIterator_step(&vi.bm_unique_verts); \
+ } \
+ else { \
+ vi.bm_vert = BLI_ghashIterator_getKey(&vi.bm_other_verts); \
+ BLI_ghashIterator_step(&vi.bm_other_verts); \
+ } \
+ if (mode == PBVH_ITER_UNIQUE && \
+ BM_elem_flag_test(vi.bm_vert, BM_ELEM_HIDDEN)) \
+ continue; \
+ vi.co = vi.bm_vert->co; \
+ vi.fno = vi.bm_vert->no; \
+ vi.mask = CustomData_bmesh_get(vi.bm_vdata, \
+ vi.bm_vert->head.data, \
+ CD_PAINT_MASK); \
+ }
#define BLI_pbvh_vertex_iter_end \
} \
Modified: trunk/blender/source/blender/blenkernel/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/blenkernel/CMakeLists.txt 2012-12-30 18:28:10 UTC (rev 53440)
+++ trunk/blender/source/blender/blenkernel/CMakeLists.txt 2012-12-30 18:28:36 UTC (rev 53441)
@@ -124,6 +124,7 @@
intern/particle.c
intern/particle_system.c
intern/pbvh.c
+ intern/pbvh_bmesh.c
intern/pointcache.c
intern/property.c
intern/report.c
Modified: trunk/blender/source/blender/blenkernel/intern/pbvh.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/pbvh.c 2012-12-30 18:28:10 UTC (rev 53440)
+++ trunk/blender/source/blender/blenkernel/intern/pbvh.c 2012-12-30 18:28:36 UTC (rev 53441)
@@ -66,14 +66,14 @@
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 @@
}
/* 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 @@
}
/* 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 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 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 @@
/* 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
*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 @@
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 @@
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 @@
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,
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list