Commit: 239b0ba7504a25a02e5378404b1b5ebfebcfd1bc Author: Pablo Dobarro Date: Wed Aug 26 14:21:18 2020 +0200 Branches: master https://developer.blender.org/rB239b0ba7504a25a02e5378404b1b5ebfebcfd1bc
Clenaup: Refactor Sculpt gesture mask operators This refactors Box Mask and Lasso mask making both functions share the same code. After this change it should be easier to add new functionality, new gesture tools or implement new gesture modes. No functional changes. Reviewed By: sergey Differential Revision: https://developer.blender.org/D8707 =================================================================== M source/blender/editors/sculpt_paint/paint_mask.c =================================================================== 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) +{ + ME @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] https://lists.blender.org/mailman/listinfo/bf-blender-cvs
