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.c143
1 files changed, 136 insertions, 7 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index ab8b81a8155..a8726482ccc 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -37,6 +37,7 @@
#include "BKE_ccg.h"
#include "BKE_context.h"
+#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_paint.h"
#include "BKE_pbvh.h"
@@ -229,6 +230,11 @@ 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];
@@ -249,12 +255,16 @@ 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;
+
/* View parameters. */
float true_view_normal[3];
float view_normal[3];
@@ -523,13 +533,46 @@ static void mask_gesture_apply_task_cb(void *__restrict userdata,
}
}
+static void face_set_gesture_apply_task_cb(void *__restrict userdata,
+ const int i,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ SculptGestureContext *sgcontext = userdata;
+ PBVHNode *node = sgcontext->nodes[i];
+ PBVHVertexIter vd;
+ bool any_updated = false;
+
+ 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);
+ any_updated = true;
+ }
+ }
+ BKE_pbvh_vertex_iter_end;
+
+ if (any_updated) {
+ BKE_pbvh_node_mark_update_visibility(node);
+ }
+}
+
static void sculpt_gesture_apply(bContext *C, SculptGestureContext *mcontext)
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
- BKE_sculpt_update_object_for_edit(depsgraph, mcontext->vc.obact, false, true, false);
+
+ const bool needs_mask = mcontext->operation == SCULPT_GESTURE_MASK;
+ const bool needs_connectivity = mcontext->operation == SCULPT_GESTURE_FACE_SET;
+
+ BKE_sculpt_update_object_for_edit(
+ depsgraph, mcontext->vc.obact, needs_connectivity, needs_mask, false);
SCULPT_undo_push_begin("Sculpt Gesture Apply");
+ 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);
+ }
+
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);
@@ -537,18 +580,33 @@ static void sculpt_gesture_apply(bContext *C, SculptGestureContext *mcontext)
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);
+ 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;
+ }
MEM_SAFE_FREE(mcontext->nodes);
}
}
- if (BKE_pbvh_type(mcontext->ss->pbvh) == PBVH_GRIDS) {
- multires_mark_as_modified(depsgraph, mcontext->vc.obact, MULTIRES_COORDS_MODIFIED);
- }
+ 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;
- BKE_pbvh_update_vertex_data(mcontext->ss->pbvh, PBVH_UpdateMask);
+ case SCULPT_GESTURE_FACE_SET:
+ BKE_pbvh_update_vertex_data(mcontext->ss->pbvh, PBVH_UpdateVisibility);
+ break;
+ }
SCULPT_undo_push_end();
@@ -556,8 +614,17 @@ static void sculpt_gesture_apply(bContext *C, SculptGestureContext *mcontext)
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, mcontext->vc.obact);
}
+static void sculpt_gesture_init_face_set_properties(SculptGestureContext *sgcontext,
+ wmOperator *UNUSED(op))
+{
+ 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);
+}
+
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");
}
@@ -601,6 +668,30 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+static int face_set_gesture_box_exec(bContext *C, wmOperator *op)
+{
+ SculptGestureContext *sgcontext = sculpt_gesture_init_from_box(C, op);
+ if (!sgcontext) {
+ return OPERATOR_CANCELLED;
+ }
+ sculpt_gesture_init_face_set_properties(sgcontext, op);
+ sculpt_gesture_apply(C, sgcontext);
+ sculpt_gesture_context_free(sgcontext);
+ return OPERATOR_FINISHED;
+}
+
+static int face_set_gesture_lasso_exec(bContext *C, wmOperator *op)
+{
+ SculptGestureContext *sgcontext = sculpt_gesture_init_from_lasso(C, op);
+ if (!sgcontext) {
+ return OPERATOR_CANCELLED;
+ }
+ sculpt_gesture_init_face_set_properties(sgcontext, op);
+ sculpt_gesture_apply(C, sgcontext);
+ sculpt_gesture_context_free(sgcontext);
+ return OPERATOR_FINISHED;
+}
+
void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
{
ot->name = "Mask Lasso Gesture";
@@ -642,3 +733,41 @@ void PAINT_OT_mask_box_gesture(wmOperatorType *ot)
paint_mask_gesture_operator_properties(ot);
}
+
+void SCULPT_OT_face_set_lasso_gesture(wmOperatorType *ot)
+{
+ ot->name = "Face Set Lasso Gesture";
+ ot->idname = "SCULPT_OT_face_set_lasso_gesture";
+ ot->description = "Add face set within the lasso as you move the brush";
+
+ ot->invoke = WM_gesture_lasso_invoke;
+ ot->modal = WM_gesture_lasso_modal;
+ ot->exec = face_set_gesture_lasso_exec;
+
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER;
+
+ /* Properties. */
+ WM_operator_properties_gesture_lasso(ot);
+ sculpt_gesture_operator_properties(ot);
+}
+
+void SCULPT_OT_face_set_box_gesture(wmOperatorType *ot)
+{
+ ot->name = "Face Set Box Gesture";
+ ot->idname = "SCULPT_OT_face_set_box_gesture";
+ ot->description = "Add face set within the box as you move the brush";
+
+ ot->invoke = WM_gesture_box_invoke;
+ ot->modal = WM_gesture_box_modal;
+ ot->exec = face_set_gesture_box_exec;
+
+ ot->poll = SCULPT_mode_poll;
+
+ ot->flag = OPTYPE_REGISTER;
+
+ /* Properties. */
+ WM_operator_properties_border(ot);
+ sculpt_gesture_operator_properties(ot);
+}