Array Brush: Add template code and support geometry modifications

This commit is contained in:
Pablo Dobarro 2021-07-02 16:38:37 +02:00
parent e8e062f866
commit 47c226cbe3
8 changed files with 45 additions and 2 deletions

View File

@ -524,6 +524,10 @@ typedef struct SculptSession {
bool show_mask;
bool show_face_sets;
/* Setting this to true allows a PBVH rebuild when evaluating the object even if the stroke or
* filter caches are active. */
bool needs_pbvh_rebuild;
/* Painting on deformed mesh */
bool deform_modifiers_active; /* Object is deformed with some modifiers. */
float (*orig_cos)[3]; /* Coords of un-deformed mesh. */

View File

@ -2001,6 +2001,7 @@ void BKE_brush_sculpt_reset(Brush *br)
case SCULPT_TOOL_DRAW_FACE_SETS:
case SCULPT_TOOL_DISPLACEMENT_ERASER:
case SCULPT_TOOL_DISPLACEMENT_SMEAR:
case SCULPT_TOOL_ARRAY:
br->add_col[0] = 0.75f;
br->add_col[1] = 0.75f;
br->add_col[2] = 0.75f;

View File

@ -1763,8 +1763,8 @@ void BKE_sculpt_update_object_before_eval(Object *ob)
/* Update before mesh evaluation in the dependency graph. */
SculptSession *ss = ob->sculpt;
if (ss && ss->building_vp_handle == false) {
if (!ss->cache && !ss->filter_cache && !ss->expand_cache) {
if (ss && (ss->building_vp_handle == false || ss->needs_pbvh_rebuild)) {
if (ss->needs_pbvh_rebuild || (!ss->cache && !ss->filter_cache && !ss->expand_cache)) {
/* We free pbvh on changes, except in the middle of drawing a stroke
* since it can't deal with changing PVBH node organization, we hope
* topology does not change in the meantime .. weak. */

View File

@ -56,6 +56,7 @@ set(SRC
paint_vertex_weight_ops.c
paint_vertex_weight_utils.c
sculpt.c
sculpt_array.c
sculpt_automasking.c
sculpt_boundary.c
sculpt_cloth.c

View File

@ -2513,6 +2513,9 @@ static float brush_strength(const Sculpt *sd,
case SCULPT_TOOL_GRAB:
return root_alpha * feather;
case SCULPT_TOOL_ARRAY:
return root_alpha * feather;
case SCULPT_TOOL_ROTATE:
return alpha * pressure * feather;
@ -6941,6 +6944,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
case SCULPT_TOOL_SYMMETRIZE:
SCULPT_do_symmetrize_brush(sd, ob, nodes, totnode);
break;
case SCULPT_TOOL_ARRAY:
SCULPT_do_array_brush(sd, ob, nodes, totnode);
break;
}
if (!ELEM(brush->sculpt_tool, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK) &&
@ -7541,6 +7547,8 @@ static const char *sculpt_tool_name(Sculpt *sd)
return "Symmetrize Brush";
case SCULPT_TOOL_TWIST:
return "Clay Strips Brush";
case SCULPT_TOOL_ARRAY:
return "Array Brush";
}
return "Sculpting";
@ -7824,6 +7832,7 @@ static bool sculpt_needs_delta_from_anchored_origin(Brush *brush)
SCULPT_TOOL_GRAB,
SCULPT_TOOL_POSE,
SCULPT_TOOL_BOUNDARY,
SCULPT_TOOL_ARRAY,
SCULPT_TOOL_THUMB,
SCULPT_TOOL_ELASTIC_DEFORM)) {
return true;
@ -7876,6 +7885,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
SCULPT_TOOL_SNAKE_HOOK,
SCULPT_TOOL_POSE,
SCULPT_TOOL_BOUNDARY,
SCULPT_TOOL_ARRAY,
SCULPT_TOOL_THUMB) &&
!sculpt_brush_use_topology_rake(ss, brush)) {
return;
@ -8797,6 +8807,11 @@ static bool sculpt_stroke_test_start(bContext *C, struct wmOperator *op, const f
sculpt_update_cache_invariants(C, sd, ss, op, mouse);
SCULPT_undo_push_begin(ob, sculpt_tool_name(sd));
Brush *brush = BKE_paint_brush(&sd->paint);
if (brush->sculpt_tool == SCULPT_TOOL_ARRAY) {
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_GEOMETRY);
}
return true;
}
@ -8839,6 +8854,19 @@ static void sculpt_stroke_update_step(bContext *C,
}
do_symmetrical_brush_actions(sd, ob, do_brush_action, ups);
if (ss->needs_pbvh_rebuild) {
/* The mesh was modified, rebuild the PBVH. */
SCULPT_pbvh_clear(ob);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false);
if (brush->sculpt_tool == SCULPT_TOOL_ARRAY) {
SCULPT_tag_update_overlays(C);
}
ss->needs_pbvh_rebuild = false;
}
sculpt_combine_proxies(sd, ob);
if (brush->sculpt_tool == SCULPT_TOOL_FAIRING) {
@ -8939,6 +8967,10 @@ static void sculpt_stroke_done(const bContext *C, struct PaintStroke *UNUSED(str
SCULPT_cache_free(ss->cache);
ss->cache = NULL;
if (brush->sculpt_tool == SCULPT_TOOL_ARRAY) {
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_GEOMETRY);
}
SCULPT_undo_push_end();
if (brush->sculpt_tool == SCULPT_TOOL_MASK) {

View File

@ -535,6 +535,9 @@ void SCULPT_boundary_edges_preview_draw(const uint gpuattr,
const float outline_alpha);
void SCULPT_boundary_pivot_line_preview_draw(const uint gpuattr, struct SculptSession *ss);
/* Array Brush. */
void SCULPT_do_array_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
/* Multi-plane Scrape Brush. */
void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode);
void SCULPT_multiplane_scrape_preview_draw(const uint gpuattr,

View File

@ -478,6 +478,7 @@ typedef enum eBrushSculptTool {
SCULPT_TOOL_SCENE_PROJECT = 34,
SCULPT_TOOL_SYMMETRIZE = 35,
SCULPT_TOOL_TWIST = 36,
SCULPT_TOOL_ARRAY = 37,
} eBrushSculptTool;
/* Brush.uv_sculpt_tool */

View File

@ -142,6 +142,7 @@ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = {
{SCULPT_TOOL_SCENE_PROJECT, "SCENE_PROJECT", ICON_BRUSH_MASK, "Scene Project", ""},
{SCULPT_TOOL_DRAW_FACE_SETS, "DRAW_FACE_SETS", ICON_BRUSH_MASK, "Draw Face Sets", ""},
{SCULPT_TOOL_SYMMETRIZE, "SYMMETRIZE", ICON_BRUSH_SCULPT_DRAW, "Symmetrize", ""},
{SCULPT_TOOL_ARRAY, "ARRAY", ICON_BRUSH_SCULPT_DRAW, "Array", ""},
{0, NULL, 0, NULL, NULL},
};
/* clang-format on */