[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [24330] branches/sculpt25/source/blender: Sculpt: tool updates for latest changes

Brecht Van Lommel brecht at blender.org
Wed Nov 4 22:10:28 CET 2009


Revision: 24330
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=24330
Author:   blendix
Date:     2009-11-04 22:10:28 +0100 (Wed, 04 Nov 2009)

Log Message:
-----------
Sculpt: tool updates for latest changes

* Smooth: vert-face map is now only created when this tool is used, would be
  best to also avoid using it here to avoid a sudden increase in memory, but
  is not trivial.
* Grab: now no longer uses active verts list and loops over nodes like other
  tools.
* Layer: uses original coordinates from undo now to save memory when not
  using persistent layer.
* Anchored: this option works again now, though is still quite slow as it
  loops over all verts/faces.

Smooth, layer tools and the anchored option could still be improved to use
less memory and/or work faster by only doing things per node.

Modified Paths:
--------------
    branches/sculpt25/source/blender/blenkernel/BKE_paint.h
    branches/sculpt25/source/blender/blenkernel/intern/object.c
    branches/sculpt25/source/blender/editors/sculpt_paint/sculpt.c

Modified: branches/sculpt25/source/blender/blenkernel/BKE_paint.h
===================================================================
--- branches/sculpt25/source/blender/blenkernel/BKE_paint.h	2009-11-04 20:56:46 UTC (rev 24329)
+++ branches/sculpt25/source/blender/blenkernel/BKE_paint.h	2009-11-04 21:10:28 UTC (rev 24330)
@@ -85,7 +85,7 @@
 	unsigned int texcache_side, *texcache, texcache_actual;
 
 	/* Layer brush persistence between strokes */
- 	float (*mesh_co_orig)[3]; /* Copy of the mesh vertices' locations */
+ 	float (*layer_co)[3]; /* Copy of the mesh vertices' locations */
 	float *layer_disps; /* Displacements for each vertex */
 
 	struct SculptStroke *stroke;

Modified: branches/sculpt25/source/blender/blenkernel/intern/object.c
===================================================================
--- branches/sculpt25/source/blender/blenkernel/intern/object.c	2009-11-04 20:56:46 UTC (rev 24329)
+++ branches/sculpt25/source/blender/blenkernel/intern/object.c	2009-11-04 21:10:28 UTC (rev 24330)
@@ -235,12 +235,9 @@
 		if(ss->layer_disps)
 			MEM_freeN(ss->layer_disps);
 
-		if(ss->mesh_co_orig)
-			MEM_freeN(ss->mesh_co_orig);
+		if(ss->layer_co)
+			MEM_freeN(ss->layer_co);
 
-		if(ss->face_normals)
-			MEM_freeN(ss->face_normals);
-
 		MEM_freeN(ss);
 
 		*ssp = NULL;

Modified: branches/sculpt25/source/blender/editors/sculpt_paint/sculpt.c
===================================================================
--- branches/sculpt25/source/blender/editors/sculpt_paint/sculpt.c	2009-11-04 20:56:46 UTC (rev 24329)
+++ branches/sculpt25/source/blender/editors/sculpt_paint/sculpt.c	2009-11-04 21:10:28 UTC (rev 24330)
@@ -159,9 +159,9 @@
 	float (*face_norms)[3]; /* Copy of the mesh faces' normals */
 	float rotation; /* Texture rotation (radians) for anchored and rake modes */
 	int pixel_radius, previous_pixel_radius;
-	ListBase grab_active_verts[8]; /* The same list of verts is used throught grab stroke */
-	PBVHNode **grab_active_nodes[8];
+	PBVHNode **grab_active_nodes[8]; /* The same list of nodes is used throught grab stroke */
 	int grab_active_totnode[8];
+	float grab_active_location[8][3];
 	float grab_delta[3], grab_delta_symmetry[3];
 	float old_grab_location[3];
 	int symmetry; /* Symmetry index between 0 and 7 */
@@ -873,34 +873,39 @@
 
 static void do_grab_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
 {
-	ActiveData *node= ss->cache->grab_active_verts[ss->cache->symmetry].first;
-	float add[3];
-	float grab_delta[3];
+	Brush *brush = paint_brush(&sd->paint);
+	float bstrength= ss->cache->bstrength;
+	float grab_delta[3], (*origco)[3];
 	int n;
 	
 	VecCopyf(grab_delta, ss->cache->grab_delta_symmetry);
-	
-	while(node) {
-		float *co= ss->mvert[node->Index].co;
+
+	#pragma omp parallel for private(n) schedule(static)
+	for(n=0; n<totnode; n++) {
+		SculptVertexData vd;
 		
-		VecCopyf(add, grab_delta);
-		VecMulf(add, node->Fade);
-		VecAddf(add, add, co);
+		origco= sculpt_undo_push_node(ss, nodes[n]);
+		sculpt_node_verts_init(sd, ss, nodes[n], origco, &vd);
 
-		sculpt_clip(sd, ss, co, add);
+		while(sculpt_node_verts_next(&vd)) {
+			const float fade = tex_strength(ss, brush, origco[vd.i], vd.dist)*bstrength;
+			const float add[3]= {vd.co[0]+fade*grab_delta[0],
+								 vd.co[1]+fade*grab_delta[1],
+								 vd.co[2]+fade*grab_delta[2]};
 
-		node= node->next;
-	}
+			sculpt_clip(sd, ss, vd.co, add);			
+			ss->mvert[vd.index].flag |= ME_VERT_PBVH_UPDATE;
+		}
 
-	for(n=0; n<totnode; n++)
 		BLI_pbvh_node_mark_update(nodes[n]);
+	}
 }
 
 static void do_layer_brush(Sculpt *sd, SculptSession *ss, PBVHNode **nodes, int totnode)
 {
 	Brush *brush = paint_brush(&sd->paint);
 	float bstrength= ss->cache->bstrength;
-	float area_normal[3];
+	float area_normal[3], offset[3];
 	float lim= ss->cache->radius / 4;
 	int n;
 
@@ -909,10 +914,16 @@
 
 	calc_area_normal(sd, ss, area_normal, nodes, totnode);
 
+	offset[0]= ss->cache->scale[0]*area_normal[0];
+	offset[1]= ss->cache->scale[1]*area_normal[1];
+	offset[2]= ss->cache->scale[2]*area_normal[2];
+
 	#pragma omp parallel for private(n) schedule(static)
 	for(n=0; n<totnode; n++) {
 		SculptVertexData vd;
+		float (*origco)[3];
 		
+		origco= sculpt_undo_push_node(ss, nodes[n]);
 		sculpt_node_verts_init(sd, ss, nodes[n], NULL, &vd);
 
 		while(sculpt_node_verts_next(&vd)) {
@@ -926,11 +937,20 @@
 			if((lim < 0 && *disp < lim) || (lim > 0 && *disp > lim))
 				*disp = lim;
 			
-			val[0] = ss->mesh_co_orig[vd.index][0]+area_normal[0] * *disp*ss->cache->scale[0];
-			val[1] = ss->mesh_co_orig[vd.index][1]+area_normal[1] * *disp*ss->cache->scale[1];
-			val[2] = ss->mesh_co_orig[vd.index][2]+area_normal[2] * *disp*ss->cache->scale[2];
+			if(ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
+				/* persistent base */
+				val[0] = ss->layer_co[vd.index][0] + (*disp)*offset[0];
+				val[1] = ss->layer_co[vd.index][1] + (*disp)*offset[1];
+				val[2] = ss->layer_co[vd.index][2] + (*disp)*offset[2];
+			}
+			else {
+				val[0] = origco[vd.i][0] + (*disp)*offset[0];
+				val[1] = origco[vd.i][1] + (*disp)*offset[1];
+				val[2] = origco[vd.i][2] + (*disp)*offset[2];
+			}
 
 			sculpt_clip(sd, ss, vd.co, val);
+			ss->mvert[vd.index].flag |= ME_VERT_PBVH_UPDATE;
 		}
 
 		BLI_pbvh_node_mark_update(nodes[n]);
@@ -1097,74 +1117,35 @@
 	}
 }
 
-static void sculpt_brush_hit_cb(PBVHNode *node, void *data_v)
-{
-	SculptSearchSphereData *data = data_v;
-	int i, totvert, *verts;
-
-	BLI_pbvh_node_get_verts(node, &verts, &totvert);
-
-	/* XXX: for now grab brush still uses an active vert list,
-	   will be fixed later */
-
-	for(i = 0; i < totvert; ++i) {
-		int v = verts[i];
-		float delta[3], dsq;
-		
-		VecSubf(delta, data->ss->mvert[v].co,
-			data->ss->cache->location);
-		dsq = Inpf(delta, delta);
-		
-		if(dsq < data->radius_squared) {
-			ActiveData *adata =
-				(ActiveData*)MEM_mallocN(sizeof(ActiveData),
-							 "ActiveData");
-			adata->Index = v;
-			adata->dist = sqrt(dsq);
-			BLI_addtail(data->active_verts, adata);
-		}
-	}
-
-	BLI_pbvh_node_mark_update(node);
-}
-
 static void do_brush_action(Sculpt *sd, SculptSession *ss, StrokeCache *cache)
 {
+	SculptSearchSphereData data;
 	Brush *brush = paint_brush(&sd->paint);
 	//KeyBlock *keyblock= NULL; /*XXX: ob_get_keyblock(OBACT); */
 	PBVHNode **nodes= NULL;
 	int totnode;
-	SculptSearchSphereData data;
 
 	data.ss = ss;
 	data.sd = sd;
 	data.radius_squared = ss->cache->radius * ss->cache->radius;
 
-	/* Build a list of all vertices that are potentially within the brush's
+	/* Build a list of all nodes that are potentially within the brush's
 	   area of influence */
 	if(brush->sculpt_tool == SCULPT_TOOL_GRAB) {
 		if(cache->first_time) {
-			const float bstrength= brush_strength(sd, cache);
-			ListBase *grab_active_verts = &ss->cache->grab_active_verts[ss->cache->symmetry];
-			ActiveData *adata;
-
-			data.active_verts = grab_active_verts;
-			BLI_pbvh_search_callback(ss->tree, sculpt_search_sphere_cb, &data,
-					sculpt_brush_hit_cb, &data);
-
+			/* For the grab tool we store these nodes once in the beginning
+			   and then reuse them. */
 			BLI_pbvh_search_gather(ss->tree, sculpt_search_sphere_cb, &data,
 				&nodes, &totnode);
 			
 			ss->cache->grab_active_nodes[ss->cache->symmetry]= nodes;
 			ss->cache->grab_active_totnode[ss->cache->symmetry]= totnode;
-
-			/* Update brush strength for each vertex */
-			for(adata = data.active_verts->first; adata; adata = adata->next)
-				adata->Fade = tex_strength(ss, brush, ss->mvert[adata->Index].co, adata->dist) * bstrength;
+			VecCopyf(ss->cache->grab_active_location[ss->cache->symmetry], ss->cache->location);
 		}
 		else {
 			nodes= ss->cache->grab_active_nodes[ss->cache->symmetry];
 			totnode= ss->cache->grab_active_totnode[ss->cache->symmetry];
+			VecCopyf(ss->cache->location, ss->cache->grab_active_location[ss->cache->symmetry]);
 		}
 	}
 	else {
@@ -1226,9 +1207,8 @@
 		}
 #endif
 		
-		if(brush->sculpt_tool != SCULPT_TOOL_GRAB)
-			if(nodes)
-				MEM_freeN(nodes);
+		if((brush->sculpt_tool != SCULPT_TOOL_GRAB) && nodes)
+			MEM_freeN(nodes);
 	}	
 }
 
@@ -1449,7 +1429,6 @@
 	if(cache->mats)
 		MEM_freeN(cache->mats);
 	for(i = 0; i < 8; ++i) {
-		BLI_freelistN(&cache->grab_active_verts[i]);
 		if(cache->grab_active_nodes[i])
 			MEM_freeN(cache->grab_active_nodes[i]);
 	}
@@ -1482,46 +1461,39 @@
 	cache->mats = MEM_callocN(sizeof(bglMats), "sculpt bglMats");
 	view3d_get_transformation(vc->ar, vc->rv3d, vc->obact, cache->mats);
 
-	sculpt_update_mesh_elements(C, 0);
-
-	/* Initialize layer brush displacements */
-	if(brush->sculpt_tool == SCULPT_TOOL_LAYER &&
-	   (!ss->layer_disps || !(brush->flag & BRUSH_PERSISTENT))) {
-		if(ss->layer_disps)
-			MEM_freeN(ss->layer_disps);
-		ss->layer_disps = MEM_callocN(sizeof(float) * ss->totvert, "layer brush displacements");
+	/* Initialize layer brush displacements and persistent coords */
+	if(brush->sculpt_tool == SCULPT_TOOL_LAYER) {
+		if(!ss->layer_disps || !(brush->flag & BRUSH_PERSISTENT)) {
+			if(ss->layer_disps)
+				MEM_freeN(ss->layer_disps);
+			ss->layer_disps = MEM_callocN(sizeof(float) * ss->totvert, "layer brush displacements");
+		}
+		if(!ss->layer_co && (brush->flag & BRUSH_PERSISTENT)) {
+			if(!ss->layer_co)
+				ss->layer_co= MEM_mallocN(sizeof(float) * 3 * ss->totvert,
+								       "sculpt mesh vertices copy");
+			for(i = 0; i < ss->totvert; ++i)
+				VecCopyf(ss->layer_co[i], ss->mvert[i].co);
+		}
 	}
 
 	/* Make copies of the mesh vertex locations and normals for some tools */
-	if(brush->sculpt_tool == SCULPT_TOOL_LAYER || (brush->flag & BRUSH_ANCHORED)) {
-		if(brush->sculpt_tool != SCULPT_TOOL_LAYER ||
-		   !ss->mesh_co_orig || !(brush->flag & BRUSH_PERSISTENT)) {
-			if(!ss->mesh_co_orig)
-				ss->mesh_co_orig= MEM_mallocN(sizeof(float) * 3 * ss->totvert,
-								       "sculpt mesh vertices copy");
-			for(i = 0; i < ss->totvert; ++i)
-				VecCopyf(ss->mesh_co_orig[i], ss->mvert[i].co);
+	if(brush->flag & BRUSH_ANCHORED) {
+		cache->orig_norms= MEM_mallocN(sizeof(short) * 3 * ss->totvert, "Sculpt orig norm");
+		for(i = 0; i < ss->totvert; ++i) {
+			cache->orig_norms[i][0] = ss->mvert[i].no[0];
+			cache->orig_norms[i][1] = ss->mvert[i].no[1];
+			cache->orig_norms[i][2] = ss->mvert[i].no[2];
 		}
 
-		if(brush->flag & BRUSH_ANCHORED) {
-			cache->orig_norms= MEM_mallocN(sizeof(short) * 3 * ss->totvert, "Sculpt orig norm");
-			for(i = 0; i < ss->totvert; ++i) {
-				cache->orig_norms[i][0] = ss->mvert[i].no[0];

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list