diff options
author | Pablo Dobarro <pablodp606@gmail.com> | 2020-09-04 15:56:15 +0300 |
---|---|---|
committer | Pablo Dobarro <pablodp606@gmail.com> | 2020-09-04 17:42:05 +0300 |
commit | 587f75f009714d293efb2c7a13d479099a60a3fb (patch) | |
tree | 124343fea81c378fc54180e01903115915a6a53d /source/blender | |
parent | 985cc48fca8801f0bb2519b1bbfb5514b7877922 (diff) |
Cleanup: Use function pointers in sculpt gestures
This replaces the switch case and operation types with a
SculptGestureOperation struct with callbacks.
Reviewed By: sergey
Differential Revision: https://developer.blender.org/D8798
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_mask.c | 243 |
1 files changed, 149 insertions, 94 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index a8726482ccc..843454e6f59 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -230,11 +230,6 @@ typedef enum eSculptGestureShapeType { SCULPT_GESTURE_SHAPE_LASSO, } eMaskGesturesShapeType; -typedef enum eSculptGestureOperationType { - SCULPT_GESTURE_MASK, - SCULPT_GESTURE_FACE_SET, -} eSculptGestureOperationType; - typedef struct LassoGestureData { float projviewobjmat[4][4]; @@ -245,6 +240,8 @@ typedef struct LassoGestureData { BLI_bitmap *mask_px; } LassoGestureData; +struct SculptGestureOperation; + typedef struct SculptGestureContext { SculptSession *ss; ViewContext vc; @@ -255,15 +252,9 @@ typedef struct SculptGestureContext { /* Operation parameters. */ eMaskGesturesShapeType shape_type; - eSculptGestureOperationType operation; bool front_faces_only; - /* Mask operation parameters. */ - PaintMaskFloodMode mask_mode; - float mask_value; - - /* Face Set operation parameters. */ - int new_face_set_id; + struct SculptGestureOperation *operation; /* View parameters. */ float true_view_normal[3]; @@ -280,6 +271,18 @@ typedef struct SculptGestureContext { int totnode; } SculptGestureContext; +typedef struct SculptGestureOperation { + /* Initial setup (data updates, special undo push...). */ + void (*sculpt_gesture_begin)(struct bContext *, SculptGestureContext *); + + /* Apply the gesture action for each symmetry pass. */ + void (*sculpt_gesture_apply_for_symmetry_pass)(struct bContext *, SculptGestureContext *); + + /* Remaining actions after finishing the symmetry passes iterations (updating datalayers, tagging + * PBVH updates...) */ + void (*sculpt_gesture_end)(struct bContext *, SculptGestureContext *); +} SculptGestureOperation; + static void sculpt_gesture_operator_properties(wmOperatorType *ot) { RNA_def_boolean(ot->srna, @@ -393,6 +396,7 @@ static SculptGestureContext *sculpt_gesture_init_from_box(bContext *C, wmOperato static void sculpt_gesture_context_free(SculptGestureContext *sgcontext) { MEM_SAFE_FREE(sgcontext->lasso.mask_px); + MEM_SAFE_FREE(sgcontext->operation); MEM_SAFE_FREE(sgcontext->nodes); MEM_SAFE_FREE(sgcontext); } @@ -493,44 +497,47 @@ static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, P return false; } -static void mask_gesture_apply_task_cb(void *__restrict userdata, - const int i, - const TaskParallelTLS *__restrict UNUSED(tls)) +static void sculpt_gesture_apply(bContext *C, SculptGestureContext *sgcontext) { - SculptGestureContext *sgcontext = userdata; - Object *ob = sgcontext->vc.obact; - PBVHNode *node = sgcontext->nodes[i]; - - const bool is_multires = BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS; + SculptGestureOperation *operation = sgcontext->operation; + SCULPT_undo_push_begin("Sculpt Gesture Apply"); - PBVHVertexIter vd; - bool any_masked = false; - bool redraw = false; + operation->sculpt_gesture_begin(C, sgcontext); - BKE_pbvh_vertex_iter_begin(sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) - { - if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { - float prevmask = *vd.mask; - if (!any_masked) { - any_masked = true; + for (ePaintSymmetryFlags symmpass = 0; symmpass <= sgcontext->symm; symmpass++) { + if (SCULPT_is_symmetry_iteration_valid(symmpass, sgcontext->symm)) { + sculpt_gesture_flip_for_symmetry_pass(sgcontext, symmpass); + sculpt_gesture_update_effected_nodes(sgcontext); - SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK); + operation->sculpt_gesture_apply_for_symmetry_pass(C, sgcontext); - if (is_multires) { - BKE_pbvh_node_mark_normals_update(node); - } - } - mask_flood_fill_set_elem(vd.mask, sgcontext->mask_mode, sgcontext->mask_value); - if (prevmask != *vd.mask) { - redraw = true; - } + MEM_SAFE_FREE(sgcontext->nodes); } } - BKE_pbvh_vertex_iter_end; - if (redraw) { - BKE_pbvh_node_mark_update_mask(node); - } + operation->sculpt_gesture_end(C, sgcontext); + + SCULPT_undo_push_end(); + + ED_region_tag_redraw(sgcontext->vc.region); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, sgcontext->vc.obact); +} + +/* Face Set Gesture Operation. */ + +typedef struct SculptGestureFaceSetOperation { + SculptGestureOperation op; + + int new_face_set_id; +} SculptGestureFaceSetOperation; + +static void sculpt_gesture_face_set_begin(bContext *C, SculptGestureContext *sgcontext) +{ + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, true, false, false); + + /* Face Sets modifications do a single undo push. */ + SCULPT_undo_push_node(sgcontext->vc.obact, NULL, SCULPT_UNDO_FACE_SETS); } static void face_set_gesture_apply_task_cb(void *__restrict userdata, @@ -538,6 +545,8 @@ static void face_set_gesture_apply_task_cb(void *__restrict userdata, const TaskParallelTLS *__restrict UNUSED(tls)) { SculptGestureContext *sgcontext = userdata; + SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) + sgcontext->operation; PBVHNode *node = sgcontext->nodes[i]; PBVHVertexIter vd; bool any_updated = false; @@ -545,7 +554,7 @@ static void face_set_gesture_apply_task_cb(void *__restrict userdata, BKE_pbvh_vertex_iter_begin(sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { - SCULPT_vertex_face_set_set(sgcontext->ss, vd.index, sgcontext->new_face_set_id); + SCULPT_vertex_face_set_set(sgcontext->ss, vd.index, face_set_operation->new_face_set_id); any_updated = true; } } @@ -556,77 +565,123 @@ static void face_set_gesture_apply_task_cb(void *__restrict userdata, } } -static void sculpt_gesture_apply(bContext *C, SculptGestureContext *mcontext) +static void sculpt_gesture_face_set_apply_for_symmetry_pass(bContext *UNUSED(C), + SculptGestureContext *sgcontext) +{ + TaskParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode); + BLI_task_parallel_range( + 0, sgcontext->totnode, sgcontext, face_set_gesture_apply_task_cb, &settings); +} + +static void sculpt_gesture_face_set_end(bContext *UNUSED(C), SculptGestureContext *sgcontext) +{ + BKE_pbvh_update_vertex_data(sgcontext->ss->pbvh, PBVH_UpdateVisibility); +} + +static void sculpt_gesture_init_face_set_properties(SculptGestureContext *sgcontext, + wmOperator *UNUSED(op)) +{ + struct Mesh *mesh = BKE_mesh_from_object(sgcontext->vc.obact); + sgcontext->operation = MEM_callocN(sizeof(SculptGestureFaceSetOperation), "Face Set Operation"); + + SculptGestureFaceSetOperation *face_set_operation = (SculptGestureFaceSetOperation *) + sgcontext->operation; + + face_set_operation->op.sculpt_gesture_begin = sculpt_gesture_face_set_begin; + face_set_operation->op.sculpt_gesture_apply_for_symmetry_pass = + sculpt_gesture_face_set_apply_for_symmetry_pass; + face_set_operation->op.sculpt_gesture_end = sculpt_gesture_face_set_end; + + face_set_operation->new_face_set_id = ED_sculpt_face_sets_find_next_available_id(mesh); +} + +/* Mask Gesture Operation. */ + +typedef struct SculptGestureMaskOperation { + SculptGestureOperation op; + + PaintMaskFloodMode mode; + float value; +} SculptGestureMaskOperation; + +static void sculpt_gesture_mask_begin(bContext *C, SculptGestureContext *sgcontext) { Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + BKE_sculpt_update_object_for_edit(depsgraph, sgcontext->vc.obact, false, true, false); +} - const bool needs_mask = mcontext->operation == SCULPT_GESTURE_MASK; - const bool needs_connectivity = mcontext->operation == SCULPT_GESTURE_FACE_SET; +static void mask_gesture_apply_task_cb(void *__restrict userdata, + const int i, + const TaskParallelTLS *__restrict UNUSED(tls)) +{ + SculptGestureContext *sgcontext = userdata; + SculptGestureMaskOperation *mask_operation = (SculptGestureMaskOperation *)sgcontext->operation; + Object *ob = sgcontext->vc.obact; + PBVHNode *node = sgcontext->nodes[i]; - BKE_sculpt_update_object_for_edit( - depsgraph, mcontext->vc.obact, needs_connectivity, needs_mask, false); + const bool is_multires = BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS; - SCULPT_undo_push_begin("Sculpt Gesture Apply"); + PBVHVertexIter vd; + bool any_masked = false; + bool redraw = false; - if (mcontext->operation == SCULPT_GESTURE_FACE_SET) { - /* Face Sets modifications do a single undo push. */ - SCULPT_undo_push_node(mcontext->vc.obact, NULL, SCULPT_UNDO_FACE_SETS); - } + BKE_pbvh_vertex_iter_begin(sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) + { + if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { + float prevmask = *vd.mask; + if (!any_masked) { + any_masked = true; - 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); - - TaskParallelSettings settings; - BKE_pbvh_parallel_range_settings(&settings, true, mcontext->totnode); - switch (mcontext->operation) { - case SCULPT_GESTURE_MASK: - BLI_task_parallel_range( - 0, mcontext->totnode, mcontext, mask_gesture_apply_task_cb, &settings); - break; - case SCULPT_GESTURE_FACE_SET: - BLI_task_parallel_range( - 0, mcontext->totnode, mcontext, face_set_gesture_apply_task_cb, &settings); - break; - } + SCULPT_undo_push_node(ob, node, SCULPT_UNDO_MASK); - MEM_SAFE_FREE(mcontext->nodes); + if (is_multires) { + BKE_pbvh_node_mark_normals_update(node); + } + } + mask_flood_fill_set_elem(vd.mask, mask_operation->mode, mask_operation->value); + if (prevmask != *vd.mask) { + redraw = true; + } } } + BKE_pbvh_vertex_iter_end; - switch (mcontext->operation) { - case SCULPT_GESTURE_MASK: - if (BKE_pbvh_type(mcontext->ss->pbvh) == PBVH_GRIDS) { - multires_mark_as_modified(depsgraph, mcontext->vc.obact, MULTIRES_COORDS_MODIFIED); - } - BKE_pbvh_update_vertex_data(mcontext->ss->pbvh, PBVH_UpdateMask); - break; - - case SCULPT_GESTURE_FACE_SET: - BKE_pbvh_update_vertex_data(mcontext->ss->pbvh, PBVH_UpdateVisibility); - break; + if (redraw) { + BKE_pbvh_node_mark_update_mask(node); } +} - SCULPT_undo_push_end(); - - ED_region_tag_redraw(mcontext->vc.region); - WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, mcontext->vc.obact); +static void sculpt_gesture_mask_apply_for_symmetry_pass(bContext *UNUSED(C), + SculptGestureContext *sgcontext) +{ + TaskParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, true, sgcontext->totnode); + BLI_task_parallel_range(0, sgcontext->totnode, sgcontext, mask_gesture_apply_task_cb, &settings); } -static void sculpt_gesture_init_face_set_properties(SculptGestureContext *sgcontext, - wmOperator *UNUSED(op)) +static void sculpt_gesture_mask_end(bContext *C, SculptGestureContext *sgcontext) { - sgcontext->operation = SCULPT_GESTURE_FACE_SET; - struct Mesh *mesh = BKE_mesh_from_object(sgcontext->vc.obact); - sgcontext->new_face_set_id = ED_sculpt_face_sets_find_next_available_id(mesh); + Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); + if (BKE_pbvh_type(sgcontext->ss->pbvh) == PBVH_GRIDS) { + multires_mark_as_modified(depsgraph, sgcontext->vc.obact, MULTIRES_COORDS_MODIFIED); + } + BKE_pbvh_update_vertex_data(sgcontext->ss->pbvh, PBVH_UpdateMask); } static void sculpt_gesture_init_mask_properties(SculptGestureContext *sgcontext, wmOperator *op) { - sgcontext->operation = SCULPT_GESTURE_MASK; - sgcontext->mask_mode = RNA_enum_get(op->ptr, "mode"); - sgcontext->mask_value = RNA_float_get(op->ptr, "value"); + sgcontext->operation = MEM_callocN(sizeof(SculptGestureFaceSetOperation), "Mask Operation"); + + SculptGestureMaskOperation *mask_operation = (SculptGestureMaskOperation *)sgcontext->operation; + + mask_operation->op.sculpt_gesture_begin = sculpt_gesture_mask_begin; + mask_operation->op.sculpt_gesture_apply_for_symmetry_pass = + sculpt_gesture_mask_apply_for_symmetry_pass; + mask_operation->op.sculpt_gesture_end = sculpt_gesture_mask_end; + + mask_operation->mode = RNA_enum_get(op->ptr, "mode"); + mask_operation->value = RNA_float_get(op->ptr, "value"); } static void paint_mask_gesture_operator_properties(wmOperatorType *ot) |