diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_mask.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_mask.c | 196 |
1 files changed, 133 insertions, 63 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 118f3a7571f..a47b9a0b936 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -41,6 +41,7 @@ #include "BLI_math_geom.h" #include "BLI_utildefines.h" #include "BLI_lasso.h" +#include "BLI_task.h" #include "BKE_pbvh.h" #include "BKE_ccg.h" @@ -91,6 +92,39 @@ static void mask_flood_fill_set_elem(float *elem, } } +typedef struct MaskTaskData { + Object *ob; + PBVH *pbvh; + PBVHNode **nodes; + bool multires; + + PaintMaskFloodMode mode; + float value; + float (*clip_planes_final)[4]; +} MaskTaskData; + +static void mask_flood_fill_task_cb(void *userdata, const int i) +{ + MaskTaskData *data = userdata; + + PBVHNode *node = data->nodes[i]; + + const PaintMaskFloodMode mode = data->mode; + const float value = data->value; + + PBVHVertexIter vi; + + sculpt_undo_push_node(data->ob, node, SCULPT_UNDO_MASK); + + BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE) { + mask_flood_fill_set_elem(vi.mask, mode, value); + } BKE_pbvh_vertex_iter_end; + + BKE_pbvh_node_mark_redraw(node); + if (data->multires) + BKE_pbvh_node_mark_normals_update(node); +} + static int mask_flood_fill_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); @@ -100,7 +134,7 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) float value; PBVH *pbvh; PBVHNode **nodes; - int totnode, i; + int totnode; bool multires; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; @@ -115,25 +149,19 @@ static int mask_flood_fill_exec(bContext *C, wmOperator *op) sculpt_undo_push_begin("Mask flood fill"); -#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) - for (i = 0; i < totnode; i++) { - PBVHVertexIter vi; - - sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK); + MaskTaskData data = { + .ob = ob, .pbvh = pbvh, .nodes = nodes, .multires = multires, + .mode = mode, .value = value, + }; - BKE_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) { - mask_flood_fill_set_elem(vi.mask, mode, value); - } BKE_pbvh_vertex_iter_end; - - BKE_pbvh_node_mark_redraw(nodes[i]); - if (multires) - BKE_pbvh_node_mark_normals_update(nodes[i]); - } + BLI_task_parallel_range( + 0, totnode, &data, mask_flood_fill_task_cb, + ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT)); if (multires) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); - sculpt_undo_push_end(); + sculpt_undo_push_end(C); if (nodes) MEM_freeN(nodes); @@ -189,6 +217,35 @@ static void flip_plane(float out[4], const float in[4], const char symm) out[3] = in[3]; } +static void mask_box_select_task_cb(void *userdata, const int i) +{ + MaskTaskData *data = userdata; + + PBVHNode *node = data->nodes[i]; + + const PaintMaskFloodMode mode = data->mode; + const float value = data->value; + float (*clip_planes_final)[4] = data->clip_planes_final; + + PBVHVertexIter vi; + bool any_masked = false; + + BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE) { + if (is_effected(clip_planes_final, vi.co)) { + if (!any_masked) { + any_masked = true; + + sculpt_undo_push_node(data->ob, node, SCULPT_UNDO_MASK); + + BKE_pbvh_node_mark_redraw(node); + if (data->multires) + BKE_pbvh_node_mark_normals_update(node); + } + mask_flood_fill_set_elem(vi.mask, mode, value); + } + } BKE_pbvh_vertex_iter_end; +} + int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *rect, bool select, bool UNUSED(extend)) { Sculpt *sd = vc->scene->toolsettings->sculpt; @@ -204,7 +261,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r bool multires; PBVH *pbvh; PBVHNode **nodes; - int totnode, i, symmpass; + int totnode, symmpass; int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; mode = PAINT_MASK_FLOOD_VALUE; @@ -236,26 +293,14 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes_final, &nodes, &totnode); -#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) - for (i = 0; i < totnode; i++) { - PBVHVertexIter vi; - bool any_masked = false; - - BKE_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) { - if (is_effected(clip_planes_final, vi.co)) { - if (!any_masked) { - any_masked = true; - - sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK); - - BKE_pbvh_node_mark_redraw(nodes[i]); - if (multires) - BKE_pbvh_node_mark_normals_update(nodes[i]); - } - mask_flood_fill_set_elem(vi.mask, mode, value); - } - } BKE_pbvh_vertex_iter_end; - } + MaskTaskData data = { + .ob = ob, .pbvh = pbvh, .nodes = nodes, .multires = multires, + .mode = mode, .value = value, .clip_planes_final = clip_planes_final, + }; + + BLI_task_parallel_range( + 0, totnode, &data, mask_box_select_task_cb, + ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT)); if (nodes) MEM_freeN(nodes); @@ -265,7 +310,7 @@ int ED_sculpt_mask_box_select(struct bContext *C, ViewContext *vc, const rcti *r if (multires) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); - sculpt_undo_push_end(); + sculpt_undo_push_end(C); ED_region_tag_redraw(ar); @@ -281,6 +326,8 @@ typedef struct LassoMaskData { int width; rcti rect; /* bounding box for scanfilling */ int symmpass; + + MaskTaskData task_data; } LassoMaskData; @@ -315,10 +362,44 @@ static bool is_effected_lasso(LassoMaskData *data, float co[3]) return BLI_BITMAP_TEST_BOOL(data->px, scr_co_s[1] * data->width + scr_co_s[0]); } -static void mask_lasso_px_cb(int x, int y, void *user_data) +static void mask_lasso_px_cb(int x, int x_end, int y, void *user_data) +{ + LassoMaskData *data = user_data; + int index = (y * data->width) + x; + int index_end = (y * data->width) + x_end; + do { + BLI_BITMAP_ENABLE(data->px, index); + } while (++index != index_end); +} + +static void mask_gesture_lasso_task_cb(void *userdata, const int i) { - struct LassoMaskData *data = user_data; - BLI_BITMAP_ENABLE(data->px, (y * data->width) + x); + LassoMaskData *lasso_data = userdata; + MaskTaskData *data = &lasso_data->task_data; + + PBVHNode *node = data->nodes[i]; + + const PaintMaskFloodMode mode = data->mode; + const float value = data->value; + + PBVHVertexIter vi; + bool any_masked = false; + + BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE) { + if (is_effected_lasso(lasso_data, vi.co)) { + if (!any_masked) { + any_masked = true; + + sculpt_undo_push_node(data->ob, node, SCULPT_UNDO_MASK); + + BKE_pbvh_node_mark_redraw(node); + if (data->multires) + BKE_pbvh_node_mark_normals_update(node); + } + + mask_flood_fill_set_elem(vi.mask, mode, value); + } + } BKE_pbvh_vertex_iter_end; } static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) @@ -338,7 +419,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL; PBVH *pbvh; PBVHNode **nodes; - int totnode, i, symmpass; + int totnode, symmpass; bool multires; PaintMaskFloodMode mode = RNA_enum_get(op->ptr, "mode"); float value = RNA_float_get(op->ptr, "value"); @@ -390,27 +471,16 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) /* gather nodes inside lasso's enclosing rectangle (should greatly help with bigger meshes) */ BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_planes_contain_AABB, clip_planes_final, &nodes, &totnode); -#pragma omp parallel for schedule(guided) if ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_OMP_LIMIT) - for (i = 0; i < totnode; i++) { - PBVHVertexIter vi; - bool any_masked = false; - - BKE_pbvh_vertex_iter_begin(pbvh, nodes[i], vi, PBVH_ITER_UNIQUE) { - if (is_effected_lasso(&data, vi.co)) { - if (!any_masked) { - any_masked = true; + data.task_data.ob = ob; + data.task_data.pbvh = pbvh; + data.task_data.nodes = nodes; + data.task_data.multires = multires; + data.task_data.mode = mode; + data.task_data.value = value; - sculpt_undo_push_node(ob, nodes[i], SCULPT_UNDO_MASK); - - BKE_pbvh_node_mark_redraw(nodes[i]); - if (multires) - BKE_pbvh_node_mark_normals_update(nodes[i]); - } - - mask_flood_fill_set_elem(vi.mask, mode, value); - } - } BKE_pbvh_vertex_iter_end; - } + BLI_task_parallel_range( + 0, totnode, &data, mask_gesture_lasso_task_cb, + ((sd->flags & SCULPT_USE_OPENMP) && (totnode > SCULPT_THREADED_LIMIT))); if (nodes) MEM_freeN(nodes); @@ -420,7 +490,7 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op) if (multires) multires_mark_as_modified(ob, MULTIRES_COORDS_MODIFIED); - sculpt_undo_push_end(); + sculpt_undo_push_end(C); ED_region_tag_redraw(vc.ar); MEM_freeN((void *)mcords); @@ -439,7 +509,7 @@ void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot) ot->name = "Mask Lasso Gesture"; ot->idname = "PAINT_OT_mask_lasso_gesture"; - ot->description = "Add mask within the lasso as you move the pointer"; + ot->description = "Add mask within the lasso as you move the brush"; ot->invoke = WM_gesture_lasso_invoke; ot->modal = WM_gesture_lasso_modal; |