[Bf-blender-cvs] [d6acac5af89] sculpt-mode-features: Automasking: Open edges automasking and refactor

Pablo Dobarro noreply at git.blender.org
Tue Apr 16 20:18:35 CEST 2019


Commit: d6acac5af89525ee483da58af5aa153cb46b0b44
Author: Pablo Dobarro
Date:   Tue Apr 16 20:16:51 2019 +0200
Branches: sculpt-mode-features
https://developer.blender.org/rBd6acac5af89525ee483da58af5aa153cb46b0b44

Automasking: Open edges automasking and refactor

This new version should allow us to stack multiple automasking
operations in one brush. The UI still needs to be done for supporting
that.

This is still a binary mask, it does not have falloff, but now the code
was done with that in mind.

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

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

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

diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 9934b835350..d7ded4e6995 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -1558,24 +1558,24 @@ static void calc_brush_local_mat(const Brush *brush, Object *ob,
 	invert_m4_m4(local_mat, tmat);
 }
 
-static bool sculpt_automasking_compatible(SculptSession *ss){
-	if (BKE_pbvh_type(ss->pbvh)==PBVH_FACES) {
+static bool sculpt_automasking_enabled(SculptSession *ss, const Brush *br){
+	if (!BKE_pbvh_type(ss->pbvh)==PBVH_FACES) {
+		return false;
+	}
+	if (br->automasking_mode != BRUSH_AUTOMASKING_NONE) {
 		return true;
 	}
 	return false;
 }
 
-static float sculpt_automasking_value_get(SculptSession *ss, const Brush *br, MVert *vert) {
-	if (!sculpt_automasking_compatible(ss)) return 1.0f;
-	if (br->automasking_mode & BRUSH_AUTOMASKING_TOPOLOGY) {
-		if (BLI_gset_haskey(ss->cache->topo_connected_set[ss->cache->mirror_symmetry_pass], vert)){
-			return 1.0f;
-		}
-		else {
-			return  0.0f;
-		}
+static float sculpt_automasking_value_get(SculptSession *ss, const Brush *br,int vert) {
+	if (!sculpt_automasking_enabled(ss, br)) return 1.0f;
+	if (ss->cache->automask[ss->cache->mirror_symmetry_pass]){
+		return ss->cache->automask[ss->cache->mirror_symmetry_pass][vert];
+	}
+	else {
+		return 1.0f;
 	}
-	return 1.0f;
 }
 
 static void update_brush_local_mat(Sculpt *sd, Object *ob)
@@ -2480,8 +2480,8 @@ static void do_draw_brush_task_cb_ex(
 			        ss, brush, vd.co, sqrtf(test.dist),
 			        vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, tls->thread_id);
 
-			if (sculpt_automasking_compatible(ss)){
-				fade *= sculpt_automasking_value_get(ss, brush, &ss->mvert[vd.vert_indices[vd.i]]);
+			if (sculpt_automasking_enabled(ss, brush)){
+				fade *= sculpt_automasking_value_get(ss, brush, vd.vert_indices[vd.i]);
 			}
 
 			if (brush->sculpt_color_mix_mode & BRUSH_SCULPT_COLOR_MIX) {
@@ -2794,8 +2794,8 @@ static void do_grab_brush_task_cb_ex(
 			float fade = bstrength * tex_strength(
 			        ss, brush, orig_data.co, sqrtf(test.dist),
 			        orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, tls->thread_id);
-			if (sculpt_automasking_compatible(ss)){
-				fade *= sculpt_automasking_value_get(ss, brush, &ss->mvert[vd.vert_indices[vd.i]]);
+			if (sculpt_automasking_enabled(ss, brush)){
+				fade *= sculpt_automasking_value_get(ss, brush, vd.vert_indices[vd.i]);
 			}
 
 			mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
@@ -2929,8 +2929,8 @@ static void do_snake_hook_brush_task_cb_ex(
 			        ss, brush, vd.co, sqrtf(test.dist),
 			        vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, tls->thread_id);
 			float automasking = 1.0f;
-			if (sculpt_automasking_compatible(ss)){
-				automasking = sculpt_automasking_value_get(ss, brush, &ss->mvert[vd.vert_indices[vd.i]]);
+			if (sculpt_automasking_enabled(ss, brush)){
+				automasking = sculpt_automasking_value_get(ss, brush, vd.vert_indices[vd.i]);
 			}
 
 			mul_v3_v3fl(proxy[vd.i], grab_delta, fade * automasking);
@@ -4053,7 +4053,72 @@ static void sculpt_topology_update(Sculpt *sd, Object *ob, Brush *brush, Unified
 	}
 }
 
-static bool find_connected_set(SculptSession *ss, int init_vert, GSet *influence, GSet *topo_connected) {
+static void init_edge_automask_cb_exec(
+        void *__restrict userdata,
+        const int n,
+        const ParallelRangeTLS *__restrict tls)
+{
+	SculptThreadedTaskData *data = userdata;
+	SculptSession *ss = data->ob->sculpt;
+
+	PBVHVertexIter vd;
+	float (*proxy)[3];
+
+	proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
+
+	SculptBrushTest test;
+	SculptBrushTestFn sculpt_brush_test_sq_fn =
+	        sculpt_brush_test_init_with_falloff_shape(ss, &test, data->brush->falloff_shape);
+
+	const MVert *mvert = ss->mvert;
+	const int msp = ss->cache->mirror_symmetry_pass;
+
+	BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+	{
+		if (sculpt_brush_test_sq_fn(&test, vd.co)) {
+			const MeshElemMap *vert_map = &ss->pmap[vd.vert_indices[vd.i]];
+			if (vert_map->count > 2) {
+				data->automask[vd.vert_indices[vd.i]] = 1.0f;
+			}
+		}
+ 	}
+ 	BKE_pbvh_vertex_iter_end;
+ }
+
+static void sculpt_edges_automasking_init(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) {
+	SculptSession *ss = ob->sculpt;
+	Brush *brush = BKE_paint_brush(&sd->paint);
+	if (!sculpt_automasking_enabled(ss, brush)) return;
+	int msp = ss->cache->mirror_symmetry_pass;
+	PBVHType type = BKE_pbvh_type(ss->pbvh);
+
+	if (type == PBVH_FACES && !ss->pmap) {
+		BLI_assert(!"Edge masking: pmap missing");
+		return;
+	}
+
+	SculptThreadedTaskData data = {
+	    .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .min_len = FLT_MAX,
+		.automask = ss->cache->automask[msp],
+	};
+
+
+	ParallelRangeSettings settings;
+	BLI_parallel_range_settings_defaults(&settings);
+	settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
+	BLI_mutex_init(&data.mutex);
+	BLI_task_parallel_range(
+		    0, totnode,
+		    &data,
+		    init_edge_automask_cb_exec,
+		    &settings);
+	BLI_mutex_end(&data.mutex);
+
+
+}
+
+
+static bool find_connected_set(SculptSession *ss, int init_vert, GSet *influence, GSet *topo_connected, float *automask) {
 	BLI_Stack *stack;
 	const MVert *mvert = ss->mvert;
 
@@ -4079,6 +4144,9 @@ static bool find_connected_set(SculptSession *ss, int init_vert, GSet *influence
 						if(BLI_gset_haskey(influence, &mvert[f_adj_v[j]])){
 							BLI_gset_remove(influence, &mvert[f_adj_v[j]], NULL);
 							BLI_gset_add(topo_connected, &mvert[f_adj_v[j]]);
+							if (automask) {
+								automask[f_adj_v[j]] = 1.0f;
+							}
 							int new_entry = f_adj_v[j];
 							BLI_stack_push(stack, &new_entry);
 						}
@@ -4092,7 +4160,7 @@ static bool find_connected_set(SculptSession *ss, int init_vert, GSet *influence
 	return false;
 }
 
-static bool sculpt_topology_automasking_needs_updates(const Brush *br) {
+static bool sculpt_automasking_needs_updates(const Brush *br) {
 	if (br->sculpt_tool == SCULPT_TOOL_GRAB || br->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK) {
 		return false;
 	}
@@ -4139,7 +4207,7 @@ static void init_topology_automask_cb_exec(
 			if (sculpt_brush_test_sq_fn(&test, orig_data.co)) {
 				BLI_mutex_lock(&data->mutex);
 				BLI_gset_add(ss->cache->influence_set[ss->cache->mirror_symmetry_pass], &ss->mvert[vd.vert_indices[vd.i]]);
-				if(ss->cache->mirror_symmetry_pass != 0 || sculpt_topology_automasking_needs_updates(data->brush)){
+				if(ss->cache->mirror_symmetry_pass != 0 || sculpt_automasking_needs_updates(data->brush)){
 					float len = len_v3v3(active_vertex_co, ss->mvert[vd.vert_indices[vd.i]].co);
 					if(len < data->min_len ){
 						data->min_len = len;
@@ -4154,7 +4222,7 @@ static void init_topology_automask_cb_exec(
 			if (sculpt_brush_test_sq_fn(&test, vd.co)) {
 				BLI_mutex_lock(&data->mutex);
 				BLI_gset_add(ss->cache->influence_set[ss->cache->mirror_symmetry_pass], &ss->mvert[vd.vert_indices[vd.i]]);
-				if(ss->cache->mirror_symmetry_pass != 0 || sculpt_topology_automasking_needs_updates(data->brush)){
+				if(ss->cache->mirror_symmetry_pass != 0 || sculpt_automasking_needs_updates(data->brush)){
 					float len = len_v3v3(active_vertex_co,ss->mvert[vd.vert_indices[vd.i]].co);
 					if(len < data->min_len ){
 						data->min_len = len;
@@ -4172,7 +4240,8 @@ static void init_topology_automask_cb_exec(
 
 static void sculpt_topology_automasking_end(Sculpt *sd, Object *ob) {
 	SculptSession *ss = ob->sculpt;
-	if (!sculpt_automasking_compatible(ss)) return;
+	Brush *brush = BKE_paint_brush(&sd->paint);
+	if (!sculpt_automasking_enabled(ss, brush)) return;
 	for (int i = 0; i < 7; i++ ) {
 		if (ss->cache->influence_set[i] != NULL){
 			BLI_gset_free(ss->cache->influence_set[i] , NULL);
@@ -4180,12 +4249,16 @@ static void sculpt_topology_automasking_end(Sculpt *sd, Object *ob) {
 		if (ss->cache->topo_connected_set[i] != NULL){
 			BLI_gset_free(ss->cache->topo_connected_set[i] , NULL);
 		}
+		if (ss->cache->automask[i]) {
+			MEM_freeN(ss->cache->automask[i]);
+		}
 	}
 }
 
-static void sculpt_topology_automasking_clear(Sculpt *sd, Object *ob) {
+static void sculpt_automasking_clear(Sculpt *sd, Object *ob) {
 	SculptSession *ss = ob->sculpt;
-	if (!sculpt_automasking_compatible(ss)) return;
+	Brush *brush = BKE_paint_brush(&sd->paint);
+	if (!sculpt_automasking_enabled(ss, brush)) return;
 	for (int i = 0; i < 7; i++ ) {
 		if (ss->cache->influence_set[i] != NULL){
 			BLI_gset_clear(ss->cache->influence_set[i] , NULL);
@@ -4193,6 +4266,11 @@ static void sculpt_topology_automasking_clear(Sculpt *sd, Object *ob) {
 		if (ss->cache->topo_connected_set[i] != NULL){
 			BLI_gset_clear(ss->cache->topo_connected_set[i], NULL);
 		}
+		if (ss->cache->automask[i]) {
+			for (int j = 0; j < ss->totvert; j++) {
+				ss->cache->automask[i][j] = 0.0f;
+			}
+		}
 	}
 }
 
@@ -4200,8 +4278,8 @@ static void sculpt_topology_automasking_init(Sculpt *sd, Object *ob, PBVHNode **
 {
 
 	SculptSession *ss = ob->sculpt;
-	if (!sculpt_automasking_compatible(ss)) return;
 	Brush *brush = BKE_paint_brush(&sd->paint);
+	if (!sculpt_automasking_enabled(ss, brush)) return;
 	int msp = ss->cache->mirror_symmetry_pass;
 	PBVHType type = BKE_pbvh_type(ss->pbvh);
 
@@ -4221,7 +4299,7 @@ static void sculpt_topology_automasking_init(Sculpt *sd, Object *ob, PBVHNode **
 	    .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, .min_len = FLT_MAX,
 	};
 
-	data.use_automasking_brush_location = sculpt_topology_automasking_needs_updates(brush);
+	data.use_automasking_brush_location = sculpt_automasking_needs_updates(brush);
 
 	ParallelRangeSettings settings;
 	BLI_parallel_range_settings_defaults(&settings);
@@ -4234,7 +4312,27 @@ static void sculpt_topology_automasking_init(Sculpt *sd, Object *ob, PBVHNode **
 		    &settings);
 	BLI_mutex_end(&data.mutex);
 
-	find_connected_set(ss, ss->cache->mirror_active_vertex[msp], ss->cache->influence_set[msp], ss->cache->topo_connected_set[msp]);
+	find_connected_set(ss, ss->cache->mirror_active_vertex[msp], ss->cache->influence_set[msp], ss->cache->topo_connected_set[msp],
+					   ss->cache->automask[msp]);
+}

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list