[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29483] branches/soc-2010-nicolasbishop: Brought back hiding parts of the mesh in sculpt mode in proper 2.5-style.

Nicholas Bishop nicholasbishop at gmail.com
Wed Jun 16 06:55:08 CEST 2010


Revision: 29483
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29483
Author:   nicholasbishop
Date:     2010-06-16 06:55:06 +0200 (Wed, 16 Jun 2010)

Log Message:
-----------
Brought back hiding parts of the mesh in sculpt mode in proper 2.5-style. (No more ugly reordering of mesh elements leading to mesh corruption!)

UI changes:
* Ctrl+Alt brings up a border select you can hide a rectangular area of the mesh with.
* Ctrl+Shift is the same, but hides the area outside of the rectangle.
* Clicking without dragging while holding either Ctrl+Alt or Ctrl+Shift will re-show hidden areas.
* Added these three operations to the Sculpt menu.

Hiding areas is done by rebuilding the PBVH and excluding primitives based on whether their AABB intersects the user-selected areas. Note that for multires meshes, the primitives are grids, not faces, so if you are bad and use multires on a plain cube, there are only 6*4 grids that can be hidden.

TODO:
* Applying multires temporarily shows hidden areas. Once you start sculpting they hide themselves again. Same for turning off display of multires modifier.
* Going to multires level zero also shows hidden areas improperly.

Modified Paths:
--------------
    branches/soc-2010-nicolasbishop/release/scripts/ui/space_view3d.py
    branches/soc-2010-nicolasbishop/source/blender/blenkernel/BKE_paint.h
    branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/cdderivedmesh.c
    branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/object.c
    branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/subsurf_ccg.c
    branches/soc-2010-nicolasbishop/source/blender/blenlib/BLI_pbvh.h
    branches/soc-2010-nicolasbishop/source/blender/blenlib/intern/pbvh.c
    branches/soc-2010-nicolasbishop/source/blender/editors/sculpt_paint/paint_ops.c
    branches/soc-2010-nicolasbishop/source/blender/editors/sculpt_paint/sculpt.c
    branches/soc-2010-nicolasbishop/source/blender/windowmanager/intern/wm_operators.c

Modified: branches/soc-2010-nicolasbishop/release/scripts/ui/space_view3d.py
===================================================================
--- branches/soc-2010-nicolasbishop/release/scripts/ui/space_view3d.py	2010-06-16 00:42:18 UTC (rev 29482)
+++ branches/soc-2010-nicolasbishop/release/scripts/ui/space_view3d.py	2010-06-16 04:55:06 UTC (rev 29483)
@@ -956,6 +956,11 @@
         sculpt = context.tool_settings.sculpt
         brush = context.tool_settings.sculpt.brush
 
+        layout.operator("sculpt.area_hide", text="Show Hidden").show_all = True
+        layout.operator("sculpt.area_hide", text="Hide Exterior Area")
+        layout.operator("sculpt.area_hide", text="Hide Interior Area").hide_inside = True
+        layout.separator()
+
         layout.prop(sculpt, "symmetry_x")
         layout.prop(sculpt, "symmetry_y")
         layout.prop(sculpt, "symmetry_z")

Modified: branches/soc-2010-nicolasbishop/source/blender/blenkernel/BKE_paint.h
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/blenkernel/BKE_paint.h	2010-06-16 00:42:18 UTC (rev 29482)
+++ branches/soc-2010-nicolasbishop/source/blender/blenkernel/BKE_paint.h	2010-06-16 04:55:06 UTC (rev 29483)
@@ -83,6 +83,9 @@
 
 	/* Partial redraw */
 	int partial_redraw;
+
+	/* Area hiding */
+	ListBase hidden_areas;
 	
 	/* Used to cache the render of the active texture */
 	unsigned int texcache_side, *texcache, texcache_actual;

Modified: branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/cdderivedmesh.c
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/cdderivedmesh.c	2010-06-16 00:42:18 UTC (rev 29482)
+++ branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/cdderivedmesh.c	2010-06-16 04:55:06 UTC (rev 29483)
@@ -210,7 +210,8 @@
 		cddm->pbvh = BLI_pbvh_new();
 		cddm->pbvh_draw = (cddm->mvert == me->mvert) || ob->sculpt->kb;
 		BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
-				    &me->vdata, me->totface, me->totvert);
+				    &me->vdata, me->totface, me->totvert,
+				    &ob->sculpt->hidden_areas);
 	}
 
 	return cddm->pbvh;

Modified: branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/object.c
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/object.c	2010-06-16 00:42:18 UTC (rev 29482)
+++ branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/object.c	2010-06-16 04:55:06 UTC (rev 29483)
@@ -236,6 +236,9 @@
 
 		if(ss->pbvh)
 			BLI_pbvh_free(ss->pbvh);
+
+		BLI_freelistN(&ss->hidden_areas);
+
 		if(dm && dm->getPBVH)
 			dm->getPBVH(NULL, dm); /* signal to clear */
 

Modified: branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/subsurf_ccg.c
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/subsurf_ccg.c	2010-06-16 00:42:18 UTC (rev 29482)
+++ branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/subsurf_ccg.c	2010-06-16 04:55:06 UTC (rev 29483)
@@ -2328,7 +2328,8 @@
 
 		ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
 		BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
-				     numGrids, gridSize, gridkey, (void**)ccgdm->gridFaces);
+				     numGrids, gridSize, gridkey, (void**)ccgdm->gridFaces,
+				     &ob->sculpt->hidden_areas);
 		ccgdm->pbvh_draw = 1;
 	}
 	else if(ob->type == OB_MESH) {
@@ -2336,7 +2337,8 @@
 
 		ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
 		BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
-				    &me->vdata, me->totface, me->totvert);
+				    &me->vdata, me->totface, me->totvert,
+				    &ob->sculpt->hidden_areas);
 		ccgdm->pbvh_draw = 0;
 	}
 

Modified: branches/soc-2010-nicolasbishop/source/blender/blenlib/BLI_pbvh.h
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/blenlib/BLI_pbvh.h	2010-06-16 00:42:18 UTC (rev 29482)
+++ branches/soc-2010-nicolasbishop/source/blender/blenlib/BLI_pbvh.h	2010-06-16 04:55:06 UTC (rev 29483)
@@ -25,6 +25,7 @@
 #ifndef BLI_PBVH_H
 #define BLI_PBVH_H
 
+struct BoundBox;
 struct CustomData;
 struct MFace;
 struct MVert;
@@ -37,6 +38,12 @@
 typedef struct PBVH PBVH;
 typedef struct PBVHNode PBVHNode;
 
+typedef struct PBVHHiddenArea {
+	struct PBVHHiddenArea *next, *prev;
+	float clip_planes[4][4];
+	int hide_inside;
+} HiddenArea;
+
 /* Callbacks */
 
 /* returns 1 if the search should continue from this node, 0 otherwise */
@@ -48,10 +55,12 @@
 
 PBVH *BLI_pbvh_new(void);
 void BLI_pbvh_build_mesh(PBVH *bvh, struct MFace *faces, struct MVert *verts,
-			 struct CustomData *vdata, int totface, int totvert);
+			 struct CustomData *vdata, int totface, int totvert,
+			 ListBase *hidden_areas);
 void BLI_pbvh_build_grids(PBVH *bvh, struct DMGridData **grids,
 			  struct DMGridAdjacency *gridadj, int totgrid,
-			  int gridsize, int gridkey, void **gridfaces);
+			  int gridsize, int gridkey, void **gridfaces,
+			  ListBase *hidden_areas);
 void BLI_pbvh_free(PBVH *bvh);
 
 /* Hierarchical Search in the BVH, two methods:

Modified: branches/soc-2010-nicolasbishop/source/blender/blenlib/intern/pbvh.c
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/blenlib/intern/pbvh.c	2010-06-16 00:42:18 UTC (rev 29482)
+++ branches/soc-2010-nicolasbishop/source/blender/blenlib/intern/pbvh.c	2010-06-16 04:55:06 UTC (rev 29483)
@@ -20,9 +20,8 @@
  * ***** END GPL LICENSE BLOCK *****
  */
 
-
-
 #include "DNA_meshdata_types.h"
+#include "DNA_object_types.h"
 
 #include "BLI_math.h"
 #include "BLI_ghash.h"
@@ -33,6 +32,8 @@
 
 #include "gpu_buffers.h"
 
+static void pbvh_free_nodes(PBVH *bvh);
+
 #define LEAF_LIMIT 10000
 
 //#define PERFCNTRS
@@ -144,6 +145,37 @@
 	int stackspace;
 } PBVHIter;
 
+
+
+/* Adapted from:
+   http://www.gamedev.net/community/forums/topic.asp?topic_id=512123
+   Returns true if the AABB is at least partially within the frustum
+   (ok, not a real frustum), false otherwise.
+*/
+static int pbvh_planes_contain_AABB(float bb_min[3], float bb_max[3], float (*planes)[4])
+{
+	int i, axis;
+	float vmin[3], vmax[3];
+
+	for(i = 0; i < 4; ++i) { 
+		for(axis = 0; axis < 3; ++axis) {
+			if(planes[i][axis] > 0) { 
+				vmin[axis] = bb_min[axis];
+				vmax[axis] = bb_max[axis];
+			}
+			else {
+				vmin[axis] = bb_max[axis];
+				vmax[axis] = bb_min[axis];
+			}
+		}
+		
+		if(dot_v3v3(planes[i], vmin) + planes[i][3] > 0)
+			return 0;
+	} 
+
+	return 1;
+}
+
 static void BB_reset(BB *bb)
 {
 	bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
@@ -450,80 +482,147 @@
 		  prim_bbc, end, offset + count - end);
 }
 
-static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
+/* Returns 0 if the primitive should be hidden, 1 otherwise */
+static int test_prim_against_hidden_areas(BBC *prim_bbc, ListBase *hidden_areas)
 {
-	int i;
+	HiddenArea *area;
 
+	for(area = hidden_areas->first; area; area = area->next) {
+		int prim_inside_planes = pbvh_planes_contain_AABB(prim_bbc->bmin, prim_bbc->bmax, area->clip_planes);
+		if((prim_inside_planes && area->hide_inside) || (!prim_inside_planes && !area->hide_inside))
+			return 0;
+	}
+
+	return 1;
+}
+
+/* Initially, the root node contains all primitives in
+   their original order.
+
+   If we are clipping, exclude primitives outside the
+   clip planes from the primitive list
+*/
+static int pbvh_initialize_prim_indices(PBVH *bvh, BBC *prim_bbc, int totprim, ListBase *hidden_areas)
+{
+	int prim, index;
+	int *prim_indices;
+
+	prim_indices = MEM_callocN(sizeof(int) * totprim, "bvh prim indices");
+
+	for(prim= 0, index = 0; prim < totprim; ++prim) {
+		if(!hidden_areas || test_prim_against_hidden_areas(&prim_bbc[prim], hidden_areas)) {
+			prim_indices[index] = prim;
+			++index;
+		}
+	}
+	
+	if(index == prim) {
+		bvh->prim_indices = prim_indices;
+		return totprim;
+	}
+	else {
+		bvh->prim_indices = MEM_callocN(sizeof(int) * index, "bvh prim indices");
+		memcpy(bvh->prim_indices, prim_indices, sizeof(int) * index);
+		MEM_freeN(prim_indices);
+		return index;
+	}
+}
+
+static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim, ListBase *hidden_areas)
+{
+	int max_prim_index;
+
 	if(totprim != bvh->totprim) {
+		/* Initialize the nodes */
 		bvh->totprim = totprim;
-		if(bvh->nodes) MEM_freeN(bvh->nodes);
+		if(bvh->nodes)
+			pbvh_free_nodes(bvh);
 		if(bvh->prim_indices) MEM_freeN(bvh->prim_indices);
-		bvh->prim_indices = MEM_callocN(sizeof(int) * totprim,
-						"bvh prim indices");
-		for(i = 0; i < totprim; ++i)
-			bvh->prim_indices[i] = i;
+
+		max_prim_index = pbvh_initialize_prim_indices(bvh, prim_bbc, totprim, hidden_areas);
+
 		bvh->totnode = 0;
-		if(bvh->node_mem_count < 100) {
+		if(bvh->node_mem_count < 100)
 			bvh->node_mem_count = 100;
-			bvh->nodes = MEM_callocN(sizeof(PBVHNode) *
-						 bvh->node_mem_count,
-						 "bvh initial nodes");
-		}
+
+		bvh->nodes = MEM_callocN(sizeof(PBVHNode) *
+					 bvh->node_mem_count,
+					 "bvh initial nodes");
 	}
 
 	bvh->totnode = 1;
-	build_sub(bvh, 0, cb, prim_bbc, 0, totprim);
+	build_sub(bvh, 0, cb, prim_bbc, 0, max_prim_index);
 }
 
-/* Do a full rebuild with on Mesh data structure */
-void BLI_pbvh_build_mesh(PBVH *bvh, MFace *faces, MVert *verts, CustomData *vdata, int totface, int totvert)
+void pbvh_begin_build(PBVH *bvh, int totprim, ListBase *hidden_areas)
 {
-	BBC *prim_bbc = NULL;
+	int i, j;
+	int totgridelem;
+	BBC *prim_bbc;
 	BB cb;
-	int i, j;
 
-	bvh->faces = faces;
-	bvh->verts = verts;
-	bvh->vdata = vdata;
-	bvh->vert_bitmap = BLI_bitmap_new(totvert);
-	bvh->totvert = totvert;
-	bvh->leaf_limit = LEAF_LIMIT;
-
+	/* cb will be the bounding box around all primitives' centroids */
 	BB_reset(&cb);
 
-	/* For each face, store the AABB and the AABB centroid */
-	prim_bbc = MEM_mallocN(sizeof(BBC) * totface, "prim_bbc");
+	if(bvh->faces)
+		bvh->vert_bitmap = BLI_bitmap_new(bvh->totvert);
+	else
+		totgridelem = bvh->gridsize*bvh->gridsize;
 
-	for(i = 0; i < totface; ++i) {
-		MFace *f = faces + i;
-		const int sides = f->v4 ? 4 : 3;
+	/* For each primitive, store the AABB and the AABB centroid */
+	prim_bbc = MEM_mallocN(sizeof(BBC) * totprim, "prim_bbc");
+
+	for(i = 0; i < totprim; ++i) {
 		BBC *bbc = prim_bbc + i;
 
 		BB_reset((BB*)bbc);
 
-		for(j = 0; j < sides; ++j)

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list