Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_mask.c')
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c604
1 files changed, 284 insertions, 320 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 05ffb80d8a1..ab8b81a8155 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -31,6 +31,7 @@
#include "BLI_lasso_2d.h"
#include "BLI_math_geom.h"
#include "BLI_math_matrix.h"
+#include "BLI_rect.h"
#include "BLI_task.h"
#include "BLI_utildefines.h"
@@ -221,392 +222,383 @@ void PAINT_OT_mask_flood_fill(struct wmOperatorType *ot)
1.0f);
}
-/* Box select, operator is VIEW3D_OT_select_box, defined in view3d_select.c. */
+/* Sculpt Gesture Operators. */
-static bool is_effected(float planes[4][4], const float co[3])
-{
- return isect_point_planes_v3(planes, 4, co);
-}
+typedef enum eSculptGestureShapeType {
+ SCULPT_GESTURE_SHAPE_BOX,
+ SCULPT_GESTURE_SHAPE_LASSO,
+} eMaskGesturesShapeType;
-static void flip_plane(float out[4], const float in[4], const char symm)
-{
- if (symm & PAINT_SYMM_X) {
- out[0] = -in[0];
- }
- else {
- out[0] = in[0];
- }
- if (symm & PAINT_SYMM_Y) {
- out[1] = -in[1];
- }
- else {
- out[1] = in[1];
- }
- if (symm & PAINT_SYMM_Z) {
- out[2] = -in[2];
- }
- else {
- out[2] = in[2];
- }
+typedef struct LassoGestureData {
+ float projviewobjmat[4][4];
- out[3] = in[3];
-}
+ rcti boundbox;
+ int width;
-static void mask_box_select_task_cb(void *__restrict userdata,
- const int i,
- const TaskParallelTLS *__restrict UNUSED(tls))
-{
- MaskTaskData *data = userdata;
+ /* 2D bitmap to test if a vertex is affected by the lasso shape. */
+ BLI_bitmap *mask_px;
+} LassoGestureData;
- PBVHNode *node = data->nodes[i];
+typedef struct SculptGestureContext {
+ SculptSession *ss;
+ ViewContext vc;
- const PaintMaskFloodMode mode = data->mode;
- const float value = data->value;
- float(*clip_planes_final)[4] = data->clip_planes_final;
+ /* Enabled and currently active symmetry. */
+ ePaintSymmetryFlags symm;
+ ePaintSymmetryFlags symmpass;
- PBVHVertexIter vi;
- bool any_masked = false;
- bool redraw = false;
+ /* Operation parameters. */
+ eMaskGesturesShapeType shape_type;
+ bool front_faces_only;
- float vertex_normal[3];
+ /* Mask operation parameters. */
+ PaintMaskFloodMode mask_mode;
+ float mask_value;
- BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE)
- {
- SCULPT_vertex_normal_get(data->ob->sculpt, vi.index, vertex_normal);
- float dot = dot_v3v3(data->view_normal, vertex_normal);
- const bool is_effected_front_face = !(data->front_faces_only && dot < 0.0f);
+ /* View parameters. */
+ float true_view_normal[3];
+ float view_normal[3];
- if (is_effected_front_face && is_effected(clip_planes_final, vi.co)) {
- float prevmask = *vi.mask;
- if (!any_masked) {
- any_masked = true;
+ float true_clip_planes[4][4];
+ float clip_planes[4][4];
- SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_MASK);
+ /* Lasso Gesture. */
+ LassoGestureData lasso;
- if (data->multires) {
- BKE_pbvh_node_mark_normals_update(node);
- }
- }
- mask_flood_fill_set_elem(vi.mask, mode, value);
- if (prevmask != *vi.mask) {
- redraw = true;
- }
- }
- }
- BKE_pbvh_vertex_iter_end;
+ /* Task Callback Data. */
+ PBVHNode **nodes;
+ int totnode;
+} SculptGestureContext;
- if (redraw) {
- BKE_pbvh_node_mark_update_mask(node);
- }
+static void sculpt_gesture_operator_properties(wmOperatorType *ot)
+{
+ RNA_def_boolean(ot->srna,
+ "use_front_faces_only",
+ false,
+ "Front Faces Only",
+ "Affect only faces facing towards the view");
}
-static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op)
+static void sculpt_gesture_context_init_common(bContext *C,
+ wmOperator *op,
+ SculptGestureContext *sgcontext)
{
- ViewContext vc;
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- ED_view3d_viewcontext_init(C, &vc, depsgraph);
-
- Sculpt *sd = vc.scene->toolsettings->sculpt;
- BoundBox bb;
- float clip_planes[4][4];
- float clip_planes_final[4][4];
- ARegion *region = vc.region;
- Object *ob = vc.obact;
- bool multires;
- PBVH *pbvh;
- PBVHNode **nodes;
- int totnode;
- int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
-
- const PaintMaskFloodMode mode = RNA_enum_get(op->ptr, "mode");
- const float value = RNA_float_get(op->ptr, "value");
- const bool front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only");
+ ED_view3d_viewcontext_init(C, &sgcontext->vc, depsgraph);
- rcti rect;
- WM_operator_properties_border_to_rcti(op, &rect);
+ Sculpt *sd = sgcontext->vc.scene->toolsettings->sculpt;
+ Object *ob = sgcontext->vc.obact;
- /* Transform the clip planes in object space. */
- ED_view3d_clipping_calc(&bb, clip_planes, vc.region, vc.obact, &rect);
+ /* Operator properties. */
+ sgcontext->front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only");
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
- pbvh = ob->sculpt->pbvh;
- multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
+ /* SculptSession */
+ sgcontext->ss = ob->sculpt;
- SCULPT_undo_push_begin("Mask box fill");
+ /* Symmetry. */
+ sgcontext->symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
- /* Calculate the view normal in object space. */
+ /* View Normal. */
float mat[3][3];
float view_dir[3] = {0.0f, 0.0f, 1.0f};
- float true_view_normal[3];
- copy_m3_m4(mat, vc.rv3d->viewinv);
+ copy_m3_m4(mat, sgcontext->vc.rv3d->viewinv);
mul_m3_v3(mat, view_dir);
copy_m3_m4(mat, ob->imat);
mul_m3_v3(mat, view_dir);
- normalize_v3_v3(true_view_normal, view_dir);
+ normalize_v3_v3(sgcontext->true_view_normal, view_dir);
+}
- for (int symmpass = 0; symmpass <= symm; symmpass++) {
- if (symmpass == 0 || (symm & symmpass && (symm != 5 || symmpass != 3) &&
- (symm != 6 || (symmpass != 3 && symmpass != 5)))) {
+static void sculpt_gesture_lasso_px_cb(int x, int x_end, int y, void *user_data)
+{
+ SculptGestureContext *mcontext = user_data;
+ LassoGestureData *lasso = &mcontext->lasso;
+ int index = (y * lasso->width) + x;
+ int index_end = (y * lasso->width) + x_end;
+ do {
+ BLI_BITMAP_ENABLE(lasso->mask_px, index);
+ } while (++index != index_end);
+}
- /* Flip the planes symmetrically as needed. */
- for (int j = 0; j < 4; j++) {
- flip_plane(clip_planes_final[j], clip_planes[j], symmpass);
- }
+static SculptGestureContext *sculpt_gesture_init_from_lasso(bContext *C, wmOperator *op)
+{
+ SculptGestureContext *sgcontext = MEM_callocN(sizeof(SculptGestureContext),
+ "sculpt gesture context lasso");
+ sgcontext->shape_type = SCULPT_GESTURE_SHAPE_LASSO;
+
+ sculpt_gesture_context_init_common(C, op, sgcontext);
- PBVHFrustumPlanes frustum = {.planes = clip_planes_final, .num_planes = 4};
- BKE_pbvh_search_gather(pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum, &nodes, &totnode);
+ int mcoords_len;
+ const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
- negate_m4(clip_planes_final);
+ if (!mcoords) {
+ return NULL;
+ }
- MaskTaskData data = {
- .ob = ob,
- .pbvh = pbvh,
- .nodes = nodes,
- .multires = multires,
- .mode = mode,
- .value = value,
- .clip_planes_final = clip_planes_final,
- .front_faces_only = front_faces_only,
- };
+ ED_view3d_ob_project_mat_get(
+ sgcontext->vc.rv3d, sgcontext->vc.obact, sgcontext->lasso.projviewobjmat);
+ BLI_lasso_boundbox(&sgcontext->lasso.boundbox, mcoords, mcoords_len);
+ sgcontext->lasso.width = sgcontext->lasso.boundbox.xmax - sgcontext->lasso.boundbox.xmin;
+ sgcontext->lasso.mask_px = BLI_BITMAP_NEW(
+ sgcontext->lasso.width * (sgcontext->lasso.boundbox.ymax - sgcontext->lasso.boundbox.ymin),
+ __func__);
+
+ BLI_bitmap_draw_2d_poly_v2i_n(sgcontext->lasso.boundbox.xmin,
+ sgcontext->lasso.boundbox.ymin,
+ sgcontext->lasso.boundbox.xmax,
+ sgcontext->lasso.boundbox.ymax,
+ mcoords,
+ mcoords_len,
+ sculpt_gesture_lasso_px_cb,
+ sgcontext);
- flip_v3_v3(data.view_normal, true_view_normal, symmpass);
+ BoundBox bb;
+ ED_view3d_clipping_calc(&bb,
+ sgcontext->true_clip_planes,
+ sgcontext->vc.region,
+ sgcontext->vc.obact,
+ &sgcontext->lasso.boundbox);
+ MEM_freeN((void *)mcoords);
+
+ return sgcontext;
+}
- TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
- BLI_task_parallel_range(0, totnode, &data, mask_box_select_task_cb, &settings);
+static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperator *op)
+{
+ SculptGestureContext *sgcontext = MEM_callocN(sizeof(SculptGestureContext),
+ "sculpt gesture context box");
+ sgcontext->shape_type = SCULPT_GESTURE_SHAPE_BOX;
- if (nodes) {
- MEM_freeN(nodes);
- }
- }
- }
+ sculpt_gesture_context_init_common(C, op, sgcontext);
- if (multires) {
- multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED);
- }
+ rcti rect;
+ WM_operator_properties_border_to_rcti(op, &rect);
- BKE_pbvh_update_vertex_data(pbvh, PBVH_UpdateMask);
+ BoundBox bb;
+ ED_view3d_clipping_calc(
+ &bb, sgcontext->true_clip_planes, sgcontext->vc.region, sgcontext->vc.obact, &rect);
- SCULPT_undo_push_end();
+ return sgcontext;
+}
- ED_region_tag_redraw(region);
+static void sculpt_gesture_context_free(SculptGestureContext *sgcontext)
+{
+ MEM_SAFE_FREE(sgcontext->lasso.mask_px);
+ MEM_SAFE_FREE(sgcontext->nodes);
+ MEM_SAFE_FREE(sgcontext);
+}
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+static void flip_plane(float out[4], const float in[4], const char symm)
+{
+ if (symm & PAINT_SYMM_X) {
+ out[0] = -in[0];
+ }
+ else {
+ out[0] = in[0];
+ }
+ if (symm & PAINT_SYMM_Y) {
+ out[1] = -in[1];
+ }
+ else {
+ out[1] = in[1];
+ }
+ if (symm & PAINT_SYMM_Z) {
+ out[2] = -in[2];
+ }
+ else {
+ out[2] = in[2];
+ }
- return true;
+ out[3] = in[3];
}
-typedef struct LassoMaskData {
- struct ViewContext *vc;
- float projviewobjmat[4][4];
- BLI_bitmap *px;
- int width;
- /* Bounding box for scanfilling. */
- rcti rect;
- int symmpass;
+static void sculpt_gesture_flip_for_symmetry_pass(SculptGestureContext *sgcontext,
+ const ePaintSymmetryFlags symmpass)
+{
+ sgcontext->symmpass = symmpass;
+ for (int j = 0; j < 4; j++) {
+ flip_plane(sgcontext->clip_planes[j], sgcontext->true_clip_planes[j], symmpass);
+ }
+ negate_m4(sgcontext->clip_planes);
+ flip_v3_v3(sgcontext->view_normal, sgcontext->true_view_normal, symmpass);
+}
- MaskTaskData task_data;
-} LassoMaskData;
+static void sculpt_gesture_update_effected_nodes(SculptGestureContext *sgcontext)
+{
+ SculptSession *ss = sgcontext->ss;
+ float clip_planes[4][4];
+ copy_m4_m4(clip_planes, sgcontext->clip_planes);
+ negate_m4(clip_planes);
+ PBVHFrustumPlanes frustum = {.planes = clip_planes, .num_planes = 4};
+ BKE_pbvh_search_gather(ss->pbvh,
+ BKE_pbvh_node_frustum_contain_AABB,
+ &frustum,
+ &sgcontext->nodes,
+ &sgcontext->totnode);
+}
-/**
- * Lasso select. This could be defined as part of #VIEW3D_OT_select_lasso,
- * still the shortcuts conflict, so we will use a separate operator.
- */
-static bool is_effected_lasso(LassoMaskData *data, const float co[3])
+static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, const float co[3])
{
float scr_co_f[2];
int scr_co_s[2];
float co_final[3];
- flip_v3_v3(co_final, co, data->symmpass);
+ flip_v3_v3(co_final, co, sgcontext->symmpass);
+
/* First project point to 2d space. */
- ED_view3d_project_float_v2_m4(data->vc->region, co_final, scr_co_f, data->projviewobjmat);
+ ED_view3d_project_float_v2_m4(
+ sgcontext->vc.region, co_final, scr_co_f, sgcontext->lasso.projviewobjmat);
scr_co_s[0] = scr_co_f[0];
scr_co_s[1] = scr_co_f[1];
- /* Clip against screen, because lasso is limited to screen only. */
- if ((scr_co_s[0] < data->rect.xmin) || (scr_co_s[1] < data->rect.ymin) ||
- (scr_co_s[0] >= data->rect.xmax) || (scr_co_s[1] >= data->rect.ymax)) {
+ /* Clip against lasso boundbox. */
+ LassoGestureData *lasso = &sgcontext->lasso;
+ if (!BLI_rcti_isect_pt(&lasso->boundbox, scr_co_s[0], scr_co_s[1])) {
return false;
}
- scr_co_s[0] -= data->rect.xmin;
- scr_co_s[1] -= data->rect.ymin;
+ scr_co_s[0] -= lasso->boundbox.xmin;
+ scr_co_s[1] -= lasso->boundbox.ymin;
- return BLI_BITMAP_TEST_BOOL(data->px, scr_co_s[1] * data->width + scr_co_s[0]);
+ return BLI_BITMAP_TEST_BOOL(lasso->mask_px, scr_co_s[1] * lasso->width + scr_co_s[0]);
}
-static void mask_lasso_px_cb(int x, int x_end, int y, void *user_data)
+static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, PBVHVertexIter *vd)
{
- 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);
+ float vertex_normal[3];
+ SCULPT_vertex_normal_get(sgcontext->ss, vd->index, vertex_normal);
+ float dot = dot_v3v3(sgcontext->view_normal, vertex_normal);
+ const bool is_effected_front_face = !(sgcontext->front_faces_only && dot < 0.0f);
+
+ if (!is_effected_front_face) {
+ return false;
+ }
+
+ switch (sgcontext->shape_type) {
+ case SCULPT_GESTURE_SHAPE_BOX:
+ return isect_point_planes_v3(sgcontext->clip_planes, 4, vd->co);
+ case SCULPT_GESTURE_SHAPE_LASSO:
+ return sculpt_gesture_is_effected_lasso(sgcontext, vd->co);
+ }
+ return false;
}
-static void mask_gesture_lasso_task_cb(void *__restrict userdata,
+static void mask_gesture_apply_task_cb(void *__restrict userdata,
const int i,
const TaskParallelTLS *__restrict UNUSED(tls))
{
- LassoMaskData *lasso_data = userdata;
- MaskTaskData *data = &lasso_data->task_data;
-
- PBVHNode *node = data->nodes[i];
+ SculptGestureContext *sgcontext = userdata;
+ Object *ob = sgcontext->vc.obact;
+ PBVHNode *node = sgcontext->nodes[i];
- const PaintMaskFloodMode mode = data->mode;
- const float value = data->value;
+ const bool is_multires = BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS;
- PBVHVertexIter vi;
+ PBVHVertexIter vd;
bool any_masked = false;
+ bool redraw = false;
- float vertex_normal[3];
-
- BKE_pbvh_vertex_iter_begin(data->pbvh, node, vi, PBVH_ITER_UNIQUE)
+ BKE_pbvh_vertex_iter_begin(sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE)
{
- SCULPT_vertex_normal_get(data->ob->sculpt, vi.index, vertex_normal);
- float dot = dot_v3v3(lasso_data->task_data.view_normal, vertex_normal);
- const bool is_effected_front_face = !(data->front_faces_only && dot < 0.0f);
-
- if (is_effected_front_face && is_effected_lasso(lasso_data, vi.co)) {
+ if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) {
+ float prevmask = *vd.mask;
if (!any_masked) {
any_masked = true;
- SCULPT_undo_push_node(data->ob, node, SCULPT_UNDO_MASK);
+ SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK);
- BKE_pbvh_node_mark_redraw(node);
- if (data->multires) {
+ if (is_multires) {
BKE_pbvh_node_mark_normals_update(node);
}
}
-
- mask_flood_fill_set_elem(vi.mask, mode, value);
+ mask_flood_fill_set_elem(vd.mask, sgcontext->mask_mode, sgcontext->mask_value);
+ if (prevmask != *vd.mask) {
+ redraw = true;
+ }
}
}
BKE_pbvh_vertex_iter_end;
+
+ if (redraw) {
+ BKE_pbvh_node_mark_update_mask(node);
+ }
}
-static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
+static void sculpt_gesture_apply(bContext *C, SculptGestureContext *mcontext)
{
- int mcoords_len;
- const int(*mcoords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcoords_len);
+ Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
+ BKE_sculpt_update_object_for_edit(depsgraph, mcontext->vc.obact, false, true, false);
- if (mcoords) {
- Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
- float clip_planes[4][4], clip_planes_final[4][4];
- BoundBox bb;
- Object *ob;
- ViewContext vc;
- LassoMaskData data;
- Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
- int symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
- PBVH *pbvh;
- PBVHNode **nodes;
- int totnode;
- bool multires;
- PaintMaskFloodMode mode = RNA_enum_get(op->ptr, "mode");
- float value = RNA_float_get(op->ptr, "value");
- const bool front_faces_only = RNA_boolean_get(op->ptr, "use_front_faces_only");
-
- /* Calculations of individual vertices are done in 2D screen space to diminish the amount of
- * calculations done. Bounding box PBVH collision is not computed against enclosing rectangle
- * of lasso. */
- ED_view3d_viewcontext_init(C, &vc, depsgraph);
-
- /* Lasso data calculations. */
- data.vc = &vc;
- ob = vc.obact;
- ED_view3d_ob_project_mat_get(vc.rv3d, ob, data.projviewobjmat);
-
- BLI_lasso_boundbox(&data.rect, mcoords, mcoords_len);
- data.width = data.rect.xmax - data.rect.xmin;
- data.px = BLI_BITMAP_NEW(data.width * (data.rect.ymax - data.rect.ymin), __func__);
-
- BLI_bitmap_draw_2d_poly_v2i_n(data.rect.xmin,
- data.rect.ymin,
- data.rect.xmax,
- data.rect.ymax,
- mcoords,
- mcoords_len,
- mask_lasso_px_cb,
- &data);
-
- ED_view3d_clipping_calc(&bb, clip_planes, vc.region, vc.obact, &data.rect);
-
- BKE_sculpt_update_object_for_edit(depsgraph, ob, false, true, false);
- pbvh = ob->sculpt->pbvh;
- multires = (BKE_pbvh_type(pbvh) == PBVH_GRIDS);
-
- SCULPT_undo_push_begin("Mask lasso fill");
-
- /* Calculate the view normal in object space. */
- float mat[3][3];
- float view_dir[3] = {0.0f, 0.0f, 1.0f};
- float true_view_normal[3];
- copy_m3_m4(mat, vc.rv3d->viewinv);
- mul_m3_v3(mat, view_dir);
- copy_m3_m4(mat, ob->imat);
- mul_m3_v3(mat, view_dir);
- normalize_v3_v3(true_view_normal, view_dir);
-
- for (int symmpass = 0; symmpass <= symm; symmpass++) {
- if ((symmpass == 0) || (symm & symmpass && (symm != 5 || symmpass != 3) &&
- (symm != 6 || (symmpass != 3 && symmpass != 5)))) {
-
- /* Flip the planes symmetrically as needed. */
- for (int j = 0; j < 4; j++) {
- flip_plane(clip_planes_final[j], clip_planes[j], symmpass);
- }
+ SCULPT_undo_push_begin("Sculpt Gesture Apply");
- flip_v3_v3(data.task_data.view_normal, true_view_normal, symmpass);
+ for (ePaintSymmetryFlags symmpass = 0; symmpass <= mcontext->symm; symmpass++) {
+ if (SCULPT_is_symmetry_iteration_valid(symmpass, mcontext->symm)) {
+ sculpt_gesture_flip_for_symmetry_pass(mcontext, symmpass);
+ sculpt_gesture_update_effected_nodes(mcontext);
- data.symmpass = symmpass;
-
- /* Gather nodes inside lasso's enclosing rectangle
- * (should greatly help with bigger meshes). */
- PBVHFrustumPlanes frustum = {.planes = clip_planes_final, .num_planes = 4};
- BKE_pbvh_search_gather(
- pbvh, BKE_pbvh_node_frustum_contain_AABB, &frustum, &nodes, &totnode);
-
- negate_m4(clip_planes_final);
+ TaskParallelSettings settings;
+ BKE_pbvh_parallel_range_settings(&settings, true, mcontext->totnode);
+ BLI_task_parallel_range(
+ 0, mcontext->totnode, mcontext, mask_gesture_apply_task_cb, &settings);
- 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;
- data.task_data.front_faces_only = front_faces_only;
+ MEM_SAFE_FREE(mcontext->nodes);
+ }
+ }
- TaskParallelSettings settings;
- BKE_pbvh_parallel_range_settings(&settings, true, totnode);
- BLI_task_parallel_range(0, totnode, &data, mask_gesture_lasso_task_cb, &settings);
+ if (BKE_pbvh_type(mcontext->ss->pbvh) == PBVH_GRIDS) {
+ multires_mark_as_modified(depsgraph, mcontext->vc.obact, MULTIRES_COORDS_MODIFIED);
+ }
- if (nodes) {
- MEM_freeN(nodes);
- }
- }
- }
+ BKE_pbvh_update_vertex_data(mcontext->ss->pbvh, PBVH_UpdateMask);
- if (multires) {
- multires_mark_as_modified(depsgraph, ob, MULTIRES_COORDS_MODIFIED);
- }
+ SCULPT_undo_push_end();
- BKE_pbvh_update_vertex_data(pbvh, PBVH_UpdateMask);
+ ED_region_tag_redraw(mcontext->vc.region);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, mcontext->vc.obact);
+}
- SCULPT_undo_push_end();
+static void sculpt_gesture_init_mask_properties(SculptGestureContext *sgcontext, wmOperator *op)
+{
+ sgcontext->mask_mode = RNA_enum_get(op->ptr, "mode");
+ sgcontext->mask_value = RNA_float_get(op->ptr, "value");
+}
- ED_region_tag_redraw(vc.region);
- MEM_freeN((void *)mcoords);
- MEM_freeN(data.px);
+static void paint_mask_gesture_operator_properties(wmOperatorType *ot)
+{
+ RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL);
+ RNA_def_float(
+ ot->srna,
+ "value",
+ 1.0f,
+ 0.0f,
+ 1.0f,
+ "Value",
+ "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
+ 0.0f,
+ 1.0f);
+}
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
+static int paint_mask_gesture_box_exec(bContext *C, wmOperator *op)
+{
+ SculptGestureContext *sgcontext = sculpt_gesture_init_from_box(C, op);
+ if (!sgcontext) {
+ return OPERATOR_CANCELLED;
+ }
+ sculpt_gesture_init_mask_properties(sgcontext, op);
+ sculpt_gesture_apply(C, sgcontext);
+ sculpt_gesture_context_free(sgcontext);
+ return OPERATOR_FINISHED;
+}
- return OPERATOR_FINISHED;
+static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
+{
+ SculptGestureContext *sgcontext = sculpt_gesture_init_from_lasso(C, op);
+ if (!sgcontext) {
+ return OPERATOR_CANCELLED;
}
- return OPERATOR_PASS_THROUGH;
+ sculpt_gesture_init_mask_properties(sgcontext, op);
+ sculpt_gesture_apply(C, sgcontext);
+ sculpt_gesture_context_free(sgcontext);
+ return OPERATOR_FINISHED;
}
void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
@@ -625,23 +617,9 @@ void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
/* Properties. */
WM_operator_properties_gesture_lasso(ot);
+ sculpt_gesture_operator_properties(ot);
- RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL);
- RNA_def_float(
- ot->srna,
- "value",
- 1.0f,
- 0.0f,
- 1.0f,
- "Value",
- "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
- 0.0f,
- 1.0f);
- RNA_def_boolean(ot->srna,
- "use_front_faces_only",
- false,
- "Front Faces Only",
- "Affect only faces facing towards the view");
+ paint_mask_gesture_operator_properties(ot);
}
void PAINT_OT_mask_box_gesture(wmOperatorType *ot)
@@ -660,21 +638,7 @@ void PAINT_OT_mask_box_gesture(wmOperatorType *ot)
/* Properties. */
WM_operator_properties_border(ot);
+ sculpt_gesture_operator_properties(ot);
- RNA_def_enum(ot->srna, "mode", mode_items, PAINT_MASK_FLOOD_VALUE, "Mode", NULL);
- RNA_def_float(
- ot->srna,
- "value",
- 1.0f,
- 0.0f,
- 1.0f,
- "Value",
- "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
- 0.0f,
- 1.0f);
- RNA_def_boolean(ot->srna,
- "use_front_faces_only",
- false,
- "Front Faces Only",
- "Affect only faces facing towards the view");
+ paint_mask_gesture_operator_properties(ot);
}