[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