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. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to