[Bf-blender-cvs] [378baee4986] sculpt-mode-features: Dam brush: Initial implementation

Pablo Dobarro noreply at git.blender.org
Mon Mar 18 04:37:06 CET 2019


Commit: 378baee4986e3ce27dae6d348a6111ec041f6b20
Author: Pablo Dobarro
Date:   Mon Mar 18 04:36:35 2019 +0100
Branches: sculpt-mode-features
https://developer.blender.org/rB378baee4986e3ce27dae6d348a6111ec041f6b20

Dam brush: Initial implementation

The purpose of this brush is to create sharp edges without creasing or
pinching the geometry. It is useful when sculpting cloth wrinkles, hard
surface objects or small cavities.
To avoid artifacts, set the stroke spacing to a lower value than 10 and
enable symmetry feather. This affects performance, so I am not adding it
to the defaults for now.
It does not create new geometry in dyntopo, so you will need to create
the geometry with another tool or switch to the voxel remesher workflow.
I'm not quite happy with the deformation as it is now (maybe it is too
smooth). I also need to try the brush with different pen tablets to
properly calibrate the pressure.

===================================================================

M	source/blender/blenkernel/intern/brush.c
M	source/blender/editors/sculpt_paint/sculpt.c
M	source/blender/makesdna/DNA_brush_types.h
M	source/blender/makesrna/intern/rna_brush.c

===================================================================

diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 0c9ecc55c0b..c284f7ed5d1 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1190,7 +1190,7 @@ bool BKE_brush_sculpt_has_secondary_color(const Brush *brush)
 	        SCULPT_TOOL_INFLATE, SCULPT_TOOL_CLAY, SCULPT_TOOL_CLAY_STRIPS,
 	        SCULPT_TOOL_PINCH, SCULPT_TOOL_CREASE, SCULPT_TOOL_LAYER,
 	        SCULPT_TOOL_FLATTEN, SCULPT_TOOL_FILL, SCULPT_TOOL_SCRAPE,
-	        SCULPT_TOOL_MASK);
+	        SCULPT_TOOL_MASK, SCULPT_TOOL_DAM);
 }
 
 void BKE_brush_unprojected_radius_set(Scene *scene, Brush *brush, float unprojected_radius)
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 927012f6062..3c626380289 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -154,6 +154,7 @@ static int sculpt_brush_needs_normal(
 	             SCULPT_TOOL_BLOB,
 	             SCULPT_TOOL_CREASE,
 	             SCULPT_TOOL_DRAW,
+	             SCULPT_TOOL_DAM,
 	             SCULPT_TOOL_LAYER,
 	             SCULPT_TOOL_NUDGE,
 	             SCULPT_TOOL_ROTATE,
@@ -1155,7 +1156,8 @@ static float brush_strength(
 		case SCULPT_TOOL_DRAW:
 		case SCULPT_TOOL_LAYER:
 			return alpha * flip * pressure * overlap * feather;
-
+		case SCULPT_TOOL_DAM:
+			return alpha * flip * 4 * pressure * overlap * feather;
 		case SCULPT_TOOL_MASK:
 			overlap = (1 + overlap) / 2;
 			switch ((BrushMaskTool)brush->mask_tool) {
@@ -1301,6 +1303,13 @@ float tex_strength(SculptSession *ss, const Brush *br,
 			avg *= (1 - factor);
 			avg *= 0.5f;
 			break;
+		case SCULPT_TOOL_DAM:
+			dist_nrm = len/cache->radius;
+			dist_nrm = 1 - dist_nrm;
+			factor = dist_nrm * dist_nrm * dist_nrm * dist_nrm;
+			factor = 1 - factor;
+			avg *= (1 - factor);
+			avg *= -2;
 		default:
 			avg *= BKE_brush_curve_strength(br, len, cache->radius);
 			break;
@@ -2347,6 +2356,78 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
 	            &settings);
 }
 
+static void do_dam_brush_task_cb_ex(
+        void *__restrict userdata,
+        const int n,
+        const ParallelRangeTLS *__restrict tls)
+{
+	SculptThreadedTaskData *data = userdata;
+	SculptSession *ss = data->ob->sculpt;
+	const Brush *brush = data->brush;
+	const float *offset = data->offset;
+
+	PBVHVertexIter vd;
+	float (*proxy)[3];
+
+	proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
+
+	SculptOrigVertData orig_data;
+	sculpt_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
+
+	SculptBrushTest test;
+	SculptBrushTestFn sculpt_brush_test_sq_fn =
+	        sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape);
+
+	BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+	{
+		sculpt_orig_vert_data_update(&orig_data, &vd);
+		if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
+			/* offset vertex */
+			const float fade = tex_strength(
+			        ss, brush, orig_data.co, sqrtf(test.dist),
+			        orig_data.no, vd.fno, vd.mask ? *vd.mask : 0.0f, tls->thread_id);
+
+			mul_v3_v3fl(proxy[vd.i], offset, fade);
+
+			if (vd.mvert)
+				vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
+		}
+	}
+	BKE_pbvh_vertex_iter_end;
+}
+
+static void do_dam_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+{
+	SculptSession *ss = ob->sculpt;
+	Brush *brush = BKE_paint_brush(&sd->paint);
+	float offset[3];
+	const float bstrength = ss->cache->bstrength;
+
+	/* offset with as much as possible factored in already */
+	mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius);
+	mul_v3_v3(offset, ss->cache->scale);
+	mul_v3_fl(offset, bstrength);
+
+	/* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise
+	 * initialize before threads so they can do curve mapping */
+	curvemapping_initialize(brush->curve);
+
+	/* threaded loop over nodes */
+	SculptThreadedTaskData data = {
+	    .sd = sd, .ob = ob, .brush = brush, .nodes = nodes,
+	    .offset = offset,
+	};
+
+	ParallelRangeSettings settings;
+	BLI_parallel_range_settings_defaults(&settings);
+	settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
+	BLI_task_parallel_range(
+	            0, totnode,
+	            &data,
+	            do_dam_brush_task_cb_ex,
+	            &settings);
+}
+
 /**
  * Used for 'SCULPT_TOOL_CREASE' and 'SCULPT_TOOL_BLOB'
  */
@@ -3890,6 +3971,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
 			case SCULPT_TOOL_SCRAPE:
 				do_scrape_brush(sd, ob, nodes, totnode);
 				break;
+			case SCULPT_TOOL_DAM:
+				do_dam_brush(sd, ob, nodes, totnode);
+				break;
 			case SCULPT_TOOL_MASK:
 				do_mask_brush(sd, ob, nodes, totnode);
 				break;
@@ -4383,6 +4467,8 @@ static const char *sculpt_tool_name(Sculpt *sd)
 			return "Rotate Brush";
 		case SCULPT_TOOL_MASK:
 			return "Mask Brush";
+		case SCULPT_TOOL_DAM:
+			return "Dam Brush";
 		case SCULPT_TOOL_SIMPLIFY:
 			return "Simplify Brush";
 	}
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 468f97c7228..9cdbc7f19b6 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -432,6 +432,7 @@ typedef enum eBrushSculptTool {
 	SCULPT_TOOL_BLOB = 17,
 	SCULPT_TOOL_CLAY_STRIPS = 18,
 	SCULPT_TOOL_MASK = 19,
+	SCULPT_TOOL_DAM = 20,
 } eBrushSculptTool;
 
 /** When #BRUSH_ACCUMULATE is used */
@@ -462,6 +463,7 @@ typedef enum eBrushSculptTool {
 	SCULPT_TOOL_ROTATE, \
 	SCULPT_TOOL_THUMB, \
 	SCULPT_TOOL_LAYER, \
+	SCULPT_TOOL_DAM, \
 	\
 	/* These brushes could handle dynamic topology, \
 	 * but user feedback indicates it's better not to */ \
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index aad4d75beeb..d7bcb744221 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -73,6 +73,8 @@ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = {
 	{SCULPT_TOOL_SCRAPE, "SCRAPE", ICON_BRUSH_SCRAPE, "Scrape", ""},
 	{SCULPT_TOOL_PINCH, "PINCH", ICON_BRUSH_PINCH, "Pinch", ""},
 	{0, "", 0, NULL, NULL},
+	{SCULPT_TOOL_DAM, "DAM", ICON_BRUSH_PINCH, "Dam", ""},
+	{0, "", 0, NULL, NULL},
 	{SCULPT_TOOL_GRAB, "GRAB", ICON_BRUSH_GRAB, "Grab", ""},
 	{SCULPT_TOOL_SNAKE_HOOK, "SNAKE_HOOK", ICON_BRUSH_SNAKE_HOOK, "Snake Hook", ""},
 	{SCULPT_TOOL_THUMB, "THUMB", ICON_BRUSH_THUMB, "Thumb", ""},



More information about the Bf-blender-cvs mailing list