[Bf-blender-cvs] [e1b6180e413] sculpt-mode-features: Topology automasking: update to new sculpt API
Pablo Dobarro
noreply at git.blender.org
Tue Aug 6 15:49:45 CEST 2019
Commit: e1b6180e413c95663a23e9a5cba9efe4ce72cd2a
Author: Pablo Dobarro
Date: Tue Aug 6 15:50:58 2019 +0200
Branches: sculpt-mode-features
https://developer.blender.org/rBe1b6180e413c95663a23e9a5cba9efe4ce72cd2a
Topology automasking: update to new sculpt API
===================================================================
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
===================================================================
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index c67783a8913..28cc5cec702 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -331,6 +331,75 @@ void sculpt_vertex_mask_clamp(SculptSession *ss, int index, float min, float max
}
}
+static void do_nearest_vertex_get_task_cb(void *__restrict userdata,
+ const int n,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
+{
+ SculptThreadedTaskData *data = userdata;
+ SculptSession *ss = data->ob->sculpt;
+
+ PBVHVertexIter vd;
+ BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+ {
+ if (len_squared_v3v3(vd.co, data->nearest_vertex_search_co) < data->max_distance_squared) {
+ BLI_mutex_lock(&data->mutex);
+ if (data->nearest_vertex_index == -1) {
+ data->nearest_vertex_index = vd.index;
+ }
+ else {
+ if (len_v3v3(data->nearest_vertex_search_co,
+ sculpt_vertex_co_get(ss, data->nearest_vertex_index)) >
+ len_v3v3(vd.co, data->nearest_vertex_search_co)) {
+ data->nearest_vertex_index = vd.index;
+ }
+ }
+ BLI_mutex_unlock(&data->mutex);
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+}
+
+int sculpt_nearest_vertex_get(
+ Sculpt *sd, Object *ob, float co[3], float max_distance, bool use_original)
+{
+ SculptSession *ss = ob->sculpt;
+ PBVHNode **nodes = NULL;
+ int totnode;
+ SculptSearchSphereData data = {
+ .ss = ss,
+ .sd = sd,
+ .radius_squared = max_distance * max_distance,
+ .original = use_original,
+
+ };
+ copy_v3_v3(data.location, co);
+ BKE_pbvh_search_gather(ss->pbvh, sculpt_search_sphere_cb, &data, &nodes, &totnode);
+ if (totnode == 0) {
+ return -1;
+ }
+
+ SculptThreadedTaskData task_data = {
+ .sd = sd,
+ .ob = ob,
+ .nodes = nodes,
+ .max_distance_squared = max_distance * max_distance,
+ .nearest_vertex_index = -1,
+ };
+
+ copy_v3_v3(task_data.nearest_vertex_search_co, co);
+
+ BLI_mutex_init(&task_data.mutex);
+
+ 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, &task_data, do_nearest_vertex_get_task_cb, &settings);
+
+ BLI_mutex_end(&task_data.mutex);
+
+ return task_data.nearest_vertex_index;
+}
+
/** \name Tool Capabilities
*
* Avoid duplicate checks, internal logic only,
@@ -1812,9 +1881,11 @@ static void calc_brush_local_mat(const Brush *brush, Object *ob, float local_mat
static bool sculpt_automasking_enabled(SculptSession *ss, const Brush *br)
{
- if (!BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) {
return false;
}
+
if (br->automasking_mode != BRUSH_AUTOMASKING_NONE) {
return true;
}
@@ -3050,7 +3121,7 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata,
tls->thread_id);
if (sculpt_automasking_enabled(ss, brush)) {
- fade *= sculpt_automasking_value_get(ss, brush, vd.vert_indices[vd.i]);
+ fade *= sculpt_automasking_value_get(ss, brush, vd.index);
}
if (brush->sculpt_color_mix_mode & BRUSH_SCULPT_COLOR_MIX) {
@@ -3387,7 +3458,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata,
vd.mask ? *vd.mask : 0.0f,
tls->thread_id);
if (sculpt_automasking_enabled(ss, brush)) {
- fade *= sculpt_automasking_value_get(ss, brush, vd.vert_indices[vd.i]);
+ fade *= sculpt_automasking_value_get(ss, brush, vd.index);
}
mul_v3_v3fl(proxy[vd.i], grab_delta, fade);
@@ -3531,7 +3602,7 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata,
tls->thread_id);
float automasking = 1.0f;
if (sculpt_automasking_enabled(ss, brush)) {
- automasking = sculpt_automasking_value_get(ss, brush, vd.vert_indices[vd.i]);
+ automasking = sculpt_automasking_value_get(ss, brush, vd.index);
}
mul_v3_v3fl(proxy[vd.i], grab_delta, fade * automasking);
@@ -4822,7 +4893,7 @@ static bool find_connected_set(
static bool sculpt_automasking_needs_updates(const Brush *br)
{
- if (br->sculpt_tool == SCULPT_TOOL_GRAB || br->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK) {
+ if (br->sculpt_tool == SCULPT_TOOL_GRAB) {
return false;
}
return true;
@@ -4837,14 +4908,11 @@ static void init_topology_automask_cb_exec(void *__restrict userdata,
PBVHVertexIter vd;
SculptOrigVertData orig_data;
- float(*proxy)[3];
if (sculpt_tool_needs_original(data->brush->sculpt_tool)) {
sculpt_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]);
}
- 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);
@@ -4855,9 +4923,9 @@ static void init_topology_automask_cb_exec(void *__restrict userdata,
flip_v3_v3(active_vertex_co, active_vertex_co, ss->cache->mirror_symmetry_pass);
}
else {
- copy_v3_v3(active_vertex_co, ss->mvert[ss->cache->active_vertex_mesh_index].co);
+ copy_v3_v3(active_vertex_co, sculpt_vertex_co_get(ss, sculpt_active_vertex_get(ss)));
flip_v3_v3(active_vertex_co,
- ss->mvert[ss->cache->active_vertex_mesh_index].co,
+ sculpt_vertex_co_get(ss, sculpt_active_vertex_get(ss)),
ss->cache->mirror_symmetry_pass);
}
@@ -4944,52 +5012,67 @@ static void sculpt_automasking_clear(Sculpt *sd, Object *ob)
}
}
-static void sculpt_topology_automasking_init(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
+typedef struct vertex_topology_it {
+ int v;
+ int it;
+} vertex_topology_it;
+
+static float *sculpt_topology_automasking_init(Sculpt *sd, Object *ob, int initial_vertex_index)
{
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);
+ return NULL;
- if (type == PBVH_FACES && !ss->pmap) {
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) {
BLI_assert(!"Topology masking: pmap missing");
- return;
+ return NULL;
}
ss->cache->mirror_active_vertex[0] = ss->cache->active_vertex_mesh_index;
- if (ss->cache->influence_set[msp] == NULL) {
- ss->cache->influence_set[msp] = BLI_gset_new(
- BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "verts influence");
- ss->cache->topo_connected_set[msp] = BLI_gset_new(
- BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "verts topology connected");
- }
+ char *visited_vertices = MEM_callocN(sculpt_vertex_count_get(ss) * sizeof(char),
+ "visited vertices");
+ float *automask_factor = MEM_callocN(sizeof(float) * sculpt_vertex_count_get(ss),
+ "automask_factor");
- SculptThreadedTaskData data = {
- .sd = sd,
- .ob = ob,
- .brush = brush,
- .nodes = nodes,
- .min_len = FLT_MAX,
- };
+ float brush_co[3];
+ copy_v3_v3(brush_co, ss->cache->location);
- data.use_automasking_brush_location = sculpt_automasking_needs_updates(brush);
+ GSQueue *queue = BLI_gsqueue_new(sizeof(vertex_topology_it));
+ vertex_topology_it mevit;
+ mevit.v = initial_vertex_index;
+ mevit.it = 1;
+ BLI_gsqueue_push(queue, &mevit);
- 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_topology_automask_cb_exec, &settings);
- BLI_mutex_end(&data.mutex);
+ while (!BLI_gsqueue_is_empty(queue)) {
+ vertex_topology_it c_mevit;
+ BLI_gsqueue_pop(queue, &c_mevit);
+ SculptVertexNeighbourIter ni;
+ sculpt_vertex_neighbours_iter_begin(ss, c_mevit.v, ni)
+ {
+ if (visited_vertices[(int)ni.index] == 0) {
+ vertex_topology_it new_entry;
+ new_entry.v = ni.index;
+ new_entry.it = c_mevit.it + 1;
+ automask_factor[new_entry.v] = 1.0f;
+ visited_vertices[(int)ni.index] = 1;
+ if (len_squared_v3v3(ss->cache->location, sculpt_vertex_co_get(ss, new_entry.v)) <
+ ss->cache->radius_squared) {
+ BLI_gsqueue_push(queue, &new_entry);
+ }
+ }
+ }
+ sculpt_vertex_neighbours_iter_end(ni)
+ }
+
+ BLI_gsqueue_free(queue);
- 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]);
+ MEM_freeN(visited_vertices);
+
+ return automask_factor;
}
static void sculpt_automasking_init(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
@@ -5000,10 +5083,15 @@ static void sculpt_automasking_init(Sculpt *sd, Object *ob, PBVHNode **nodes, in
return;
int msp = ss->cache->mirror_symmetry_pass;
- ss->cache->automask[msp] = MEM_callocN(sizeof(float) * ss->totvert, "automask");
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) {
+ BM_mesh_elem_table_init(ss->bm, BM_VERT);
+ BM_mesh_elem_index_ensure(ss->bm, BM_VERT);
+ }
if (brush->automasking_mode & BRUSH_AUTOMASKING_TOPOLOGY) {
- sculpt_topology_automasking_init(sd, ob, nodes, totnode);
+ int active_vertex_mirrored = sculpt_nearest_vertex_get(
+ sd, ob, ss->cache->location, FLT_MAX, false);
+ ss->cache->automask[msp] = sculpt_topology_automasking_init(sd, ob, active_vertex_mirrored);
}
if (brush->automasking_mode & BRUSH_AUTOMASKING_EDGES) {
@@ -9648,11 +9736,6 @@ int sculpt_mask_expand_modal(bContext *C, wmOpe
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list