[Bf-blender-cvs] [0ec5917cd1c] sculpt-mode-features: Mask filter: update to new sculpt API
Pablo Dobarro
noreply at git.blender.org
Mon Aug 5 15:41:06 CEST 2019
Commit: 0ec5917cd1c88c032244b4ed9dc8bdc2d8886c1f
Author: Pablo Dobarro
Date: Mon Aug 5 15:24:18 2019 +0200
Branches: sculpt-mode-features
https://developer.blender.org/rB0ec5917cd1c88c032244b4ed9dc8bdc2d8886c1f
Mask filter: update to new sculpt API
===================================================================
M source/blender/editors/sculpt_paint/sculpt.c
===================================================================
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 33d3604e5ad..18d2beb2c2a 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -318,6 +318,19 @@ void sculpt_vertex_neighbours_get(SculptSession *ss, int index, SculptVertexNeig
MEM_freeN(neighbour_iterator.neighbours); \
}
+/* Utils */
+void sculpt_vertex_mask_clamp(SculptSession *ss, int index, float min, float max)
+{
+ if (sculpt_vertex_mask_get(ss, index) > max) {
+ sculpt_vertex_mask_set(ss, index, max);
+ return;
+ }
+ if (sculpt_vertex_mask_get(ss, index) < min) {
+ sculpt_vertex_mask_set(ss, index, min);
+ return;
+ }
+}
+
/** \name Tool Capabilities
*
* Avoid duplicate checks, internal logic only,
@@ -1901,31 +1914,26 @@ static float neighbor_average_mask(SculptSession *ss, unsigned vert)
static float neighbor_dirty_mask(SculptSession *ss, const int vert)
{
- const MeshElemMap *vert_map = &ss->pmap[vert];
- const MVert *mvert = ss->mvert;
-
- int i = 0;
int total = 0;
float avg[3];
zero_v3(avg);
- for (i = 0; i < vert_map->count; i++) {
- const MPoly *p = &ss->mpoly[vert_map->indices[i]];
- unsigned f_adj_v[2];
- if (poly_get_adj_loops_from_vert(p, ss->mloop, vert, f_adj_v) != -1) {
- int j;
- for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
- float normalized[3];
- sub_v3_v3v3(normalized, mvert[f_adj_v[j]].co, mvert[vert].co);
- normalize_v3(normalized);
- add_v3_v3(avg, normalized);
- total++;
- }
- }
+
+ SculptVertexNeighbourIter ni;
+ sculpt_vertex_neighbours_iter_begin(ss, vert, ni)
+ {
+ float normalized[3];
+ sub_v3_v3v3(normalized, sculpt_vertex_co_get(ss, ni.index), sculpt_vertex_co_get(ss, vert));
+ normalize_v3(normalized);
+ add_v3_v3(avg, normalized);
+ total++;
}
- if (total > 0) {
+ sculpt_vertex_neighbours_iter_end(ni)
+
+ if (total > 0)
+ {
mul_v3_fl(avg, 1.0f / total);
float normal[3];
- normal_short_to_float_v3(normal, mvert[vert].no);
+ sculpt_vertex_normal_get(ss, vert, normal);
float dot = dot_v3v3(avg, normal);
float ang = acos(dot);
if (ang < DEG2RAD(0)) {
@@ -1936,54 +1944,6 @@ static float neighbor_dirty_mask(SculptSession *ss, const int vert)
return 0;
}
-static float neighbor_min_mask(SculptSession *ss, const int vert, float *prev_mask)
-{
- const MeshElemMap *vert_map = &ss->pmap[vert];
- const float *vmask = prev_mask;
-
- int i = 0;
- float min = 1.0f;
- for (i = 0; i < vert_map->count; i++) {
- const MPoly *p = &ss->mpoly[vert_map->indices[i]];
- unsigned f_adj_v[2];
-
- if (poly_get_adj_loops_from_vert(p, ss->mloop, vert, f_adj_v) != -1) {
- int j;
- for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
- float vmask_f = vmask[f_adj_v[j]];
- if (vmask_f < min) {
- min = vmask_f;
- }
- }
- }
- }
- return min;
-}
-
-static float neighbor_max_mask(SculptSession *ss, const int vert, float *prev_mask)
-{
- const MeshElemMap *vert_map = &ss->pmap[vert];
- const float *vmask = prev_mask;
-
- int i = 0;
- float max = 0.0f;
- for (i = 0; i < vert_map->count; i++) {
- const MPoly *p = &ss->mpoly[vert_map->indices[i]];
- unsigned f_adj_v[2];
-
- if (poly_get_adj_loops_from_vert(p, ss->mloop, vert, f_adj_v) != -1) {
- int j;
- for (j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) {
- float vmask_f = vmask[f_adj_v[j]];
- if (vmask_f > max) {
- max = vmask_f;
- }
- }
- }
- }
- return max;
-}
-
static void neighbor_average_color(SculptSession *ss, float avg[3], unsigned vert)
{
const MeshElemMap *vert_map = &ss->pmap[vert];
@@ -8635,7 +8595,8 @@ static void mask_filter_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
{
float val;
- float contrast, delta, gain, offset;
+ float contrast, delta, gain, offset, max, min;
+ SculptVertexNeighbourIter ni;
switch (mode) {
case MASK_FILTER_BLUR:
if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
@@ -8664,40 +8625,46 @@ static void mask_filter_task_cb(void *__restrict userdata,
CLAMP(*vd.mask, 0.0f, 1.0f);
break;
case MASK_FILTER_GROW:
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
- val = neighbor_max_mask(ss, vd.vert_indices[vd.i], data->prev_mask);
- *vd.mask = val;
- CLAMP(*vd.mask, 0.0f, 1.0f);
+ max = 0.0f;
+ sculpt_vertex_neighbours_iter_begin(ss, vd.index, ni)
+ {
+ float vmask_f = data->prev_mask[ni.index];
+ if (vmask_f > max) {
+ max = vmask_f;
+ }
}
+ sculpt_vertex_neighbours_iter_end(ni) *vd.mask = max;
+ CLAMP(*vd.mask, 0.0f, 1.0f);
break;
case MASK_FILTER_SHRINK:
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
- val = neighbor_min_mask(ss, vd.vert_indices[vd.i], data->prev_mask);
- *vd.mask = val;
- CLAMP(*vd.mask, 0.0f, 1.0f);
+ min = 1.0f;
+ sculpt_vertex_neighbours_iter_begin(ss, vd.index, ni)
+ {
+ float vmask_f = data->prev_mask[ni.index];
+ if (vmask_f < min) {
+ min = vmask_f;
+ }
}
+ sculpt_vertex_neighbours_iter_end(ni) *vd.mask = min;
+ CLAMP(*vd.mask, 0.0f, 1.0f);
break;
case MASK_FILTER_DIRTY:
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
- val = neighbor_dirty_mask(ss, vd.vert_indices[vd.i]);
- data->prev_mask[vd.vert_indices[vd.i]] = val;
- }
+ val = neighbor_dirty_mask(ss, vd.index);
+ data->prev_mask[vd.index] = val;
break;
case MASK_FILTER_CONTRAST:
- if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) {
- contrast = 0.1;
- delta = contrast / 2.0f;
- gain = 1.0f - delta * 2.0f;
- if (contrast > 0) {
- gain = 1.0f / ((gain != 0.0f) ? gain : FLT_EPSILON);
- offset = gain * (-delta);
- }
- else {
- delta *= -1;
- offset = gain * (delta);
- }
- *vd.mask = gain * (*vd.mask) + offset;
+ contrast = 0.1f;
+ delta = contrast / 2.0f;
+ gain = 1.0f - delta * 2.0f;
+ if (contrast > 0) {
+ gain = 1.0f / ((gain != 0.0f) ? gain : FLT_EPSILON);
+ offset = gain * (-delta);
+ }
+ else {
+ delta *= -1;
+ offset = gain * (delta);
}
+ *vd.mask = gain * (*vd.mask) + offset;
break;
}
if (vd.mvert)
@@ -8706,14 +8673,11 @@ static void mask_filter_task_cb(void *__restrict userdata,
BKE_pbvh_vertex_iter_end;
BKE_pbvh_node_mark_redraw(node);
- if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS)
- BKE_pbvh_node_mark_normals_update(node);
}
-static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
+static int sculpt_mask_filter_invoke(bContext *C, wmOperator *op)
{
ARegion *ar = CTX_wm_region(C);
- struct Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
SculptSession *ss = ob->sculpt;
Depsgraph *depsgraph = CTX_data_depsgraph(C);
@@ -8728,8 +8692,14 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ if (BKE_pbvh_type(pbvh) == PBVH_BMESH) {
+ BM_mesh_elem_table_init(ss->bm, BM_VERT);
+ BM_mesh_elem_index_ensure(ss->bm, BM_VERT);
+ }
+
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true);
- if (BKE_pbvh_type(pbvh) == PBVH_FACES && !ob->sculpt->pmap) {
+
+ if (!ob->sculpt->pmap) {
return OPERATOR_CANCELLED;
}
@@ -8750,7 +8720,10 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
for (int i = 0; i < iterations; i++) {
if (ELEM(mode, MASK_FILTER_GROW, MASK_FILTER_SHRINK, MASK_FILTER_DIRTY)) {
- prev_mask = MEM_dupallocN(ss->vmask);
+ prev_mask = MEM_mallocN(sculpt_vertex_count_get(ss) * sizeof(float), "prevmask");
+ for (int j = 0; j < sculpt_vertex_count_get(ss); j++) {
+ prev_mask[j] = sculpt_vertex_mask_get(ss, j);
+ }
}
SculptThreadedTaskData data = {
@@ -8767,14 +8740,15 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT);
BLI_task_parallel_range(0, totnode, &data, mask_filter_task_cb, &settings);
- if (ELEM(mode, MASK_FILTER_GROW, MASK_FILTER_SHRINK))
+ if (ELEM(mode, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) {
MEM_freeN(prev_mask);
+ }
}
if (mode == MASK_FILTER_DIRTY) {
float min = FLT_MAX;
float max = FLT_MIN;
- for (int i = 0; i < ss->totvert; i++) {
+ for (int i = 0; i < sculpt_vertex_count_get(ss); i++) {
float val = prev_mask[i];
if (val < min) {
min = val;
@@ -8793,20 +8767,22 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
}
bool dirty_only = RNA_boolean_get(op->ptr, "dirty_only");
- for (int i = 0; i < ss->totvert; i++) {
- ss->vmask[i] += 1 - ((prev_mask[i] - min) * range);
+ for (int i = 0; i < sculpt_vertex_count_get(ss); i++) {
+ sculpt_vertex_mask_set(
+ ss, i, sculpt_vertex_mask_get(ss, i) + (1 - ((prev_mask[i] - min) * range)));
if (dirty_only) {
- ss->vmask[i] = fmin(ss->vmask[i], 0.5) * 2.0f;
+ sculpt_vertex_mask_set(ss, i, fmin(sculpt_vertex_mask_get(ss, i), 0.5f) * 2.0f);
}
- CLAMP(ss->vmask[i], 0.0f, 1.0f);
+ sculpt_vertex_mask_clamp(ss, i, 0.0f, 1.0f);
}
MEM_freeN(prev_mask);
}
sculpt_undo_push_end();
- if (nodes)
+ if (nodes) {
MEM_freeN(nodes);
+ }
ED_region_tag_redraw(ar);
@@ -8823,7 +8799,7 @@ void SCULPT_OT_mask_filter(struct wmOperatorType *ot)
ot->description = "Applies a filter to modify the current mask";
/* api callbacks */
- ot->exec = sculpt_mask_filter_exec;
+ ot->invoke = sculpt_mask_filter_invoke;
ot->poll = sculpt_mode_poll;
ot->flag = OPTYPE_REGISTER;
More information about the Bf-blender-cvs
mailing list