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:
authorPablo Dobarro <pablodp606@gmail.com>2020-09-04 15:56:15 +0300
committerPablo Dobarro <pablodp606@gmail.com>2020-09-04 17:42:05 +0300
commit587f75f009714d293efb2c7a13d479099a60a3fb (patch)
tree124343fea81c378fc54180e01903115915a6a53d
parent985cc48fca8801f0bb2519b1bbfb5514b7877922 (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
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c243
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)