Cleanup: Add functions to check the first brush step and symmetry passes
This adds three functions to check the state of the stroke in the StrokeCache, removing the references to first_time and mirror_symmetry_pass from the code. This makes easier to understand what each code path is doing inside of each tool. Some tools were using mirror_symmetry_pass incorrectly, so this should also fix unreported bugs with radial and tiling symmetry related to that. Reviewed By: sergey Differential Revision: https://developer.blender.org/D8164
This commit is contained in:
parent
bf5a656ff6
commit
6358c7754c
|
@ -1567,7 +1567,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (vc.obact->sculpt->cache && !vc.obact->sculpt->cache->first_time) {
|
||||
if (vc.obact->sculpt->cache &&
|
||||
!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(vc.obact->sculpt->cache)) {
|
||||
wmViewport(®ion->winrct);
|
||||
|
||||
/* Draw cached dynamic mesh preview lines. */
|
||||
|
@ -1593,7 +1594,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
|
|||
}
|
||||
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_MULTIPLANE_SCRAPE &&
|
||||
brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW && !ss->cache->first_time) {
|
||||
brush->flag2 & BRUSH_MULTIPLANE_SCRAPE_PLANES_PREVIEW &&
|
||||
!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
GPU_matrix_push_projection();
|
||||
ED_view3d_draw_setup_view(wm,
|
||||
CTX_wm_window(C),
|
||||
|
@ -1611,7 +1613,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
|
|||
GPU_matrix_pop_projection();
|
||||
}
|
||||
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_CLOTH && !ss->cache->first_time) {
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_CLOTH &&
|
||||
!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
GPU_matrix_push_projection();
|
||||
ED_view3d_draw_setup_view(CTX_wm_manager(C),
|
||||
CTX_wm_window(C),
|
||||
|
|
|
@ -778,6 +778,31 @@ bool SCULPT_vertex_is_boundary(SculptSession *ss, const int index)
|
|||
}
|
||||
|
||||
/* Utils */
|
||||
|
||||
/* Returns true when the step belongs to the stroke that is directly performend by the brush and
|
||||
* not by one of the symmetry passes. */
|
||||
bool SCULPT_stroke_is_main_symmetry_pass(StrokeCache *cache)
|
||||
{
|
||||
return cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0 &&
|
||||
cache->tile_pass == 0;
|
||||
}
|
||||
|
||||
/* Return true only once per stroke on the first symmetry pass, regardless of the symmetry passes
|
||||
* enabled. */
|
||||
/* This should be used for functionality that needs to be computed once per stroke of a particular
|
||||
* tool (allocating memory, updating random seeds...). */
|
||||
bool SCULPT_stroke_is_first_brush_step(StrokeCache *cache)
|
||||
{
|
||||
return cache->first_time && cache->mirror_symmetry_pass == 0 &&
|
||||
cache->radial_symmetry_pass == 0 && cache->tile_pass == 0;
|
||||
}
|
||||
|
||||
/* Returnns true on the first brush step of each symmetry pass. */
|
||||
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(StrokeCache *cache)
|
||||
{
|
||||
return cache->first_time;
|
||||
}
|
||||
|
||||
bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], const char symm)
|
||||
{
|
||||
bool is_in_symmetry_area = true;
|
||||
|
@ -2558,7 +2583,7 @@ static void update_sculpt_normal(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
|
|||
cache->normal_weight > 0.0f);
|
||||
|
||||
if (cache->mirror_symmetry_pass == 0 && cache->radial_symmetry_pass == 0 &&
|
||||
(cache->first_time || update_normal)) {
|
||||
(SCULPT_stroke_is_first_brush_step_of_symmetry_pass(cache) || update_normal)) {
|
||||
calc_sculpt_normal(sd, ob, nodes, totnode, cache->sculpt_normal);
|
||||
if (brush->falloff_shape == PAINT_FALLOFF_SHAPE_TUBE) {
|
||||
project_plane_v3_v3v3(cache->sculpt_normal, cache->sculpt_normal, cache->view_normal);
|
||||
|
@ -3144,7 +3169,7 @@ static void do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
|
|||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
if (ss->cache->first_time) {
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3175,10 +3200,9 @@ static void calc_sculpt_plane(
|
|||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
if (ss->cache->mirror_symmetry_pass == 0 && ss->cache->radial_symmetry_pass == 0 &&
|
||||
ss->cache->tile_pass == 0 &&
|
||||
(ss->cache->first_time || !(brush->flag & BRUSH_ORIGINAL_PLANE) ||
|
||||
!(brush->flag & BRUSH_ORIGINAL_NORMAL))) {
|
||||
if (SCULPT_stroke_is_main_symmetry_pass(ss->cache) &&
|
||||
(SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) ||
|
||||
!(brush->flag & BRUSH_ORIGINAL_PLANE) || !(brush->flag & BRUSH_ORIGINAL_NORMAL))) {
|
||||
switch (brush->sculpt_plane) {
|
||||
case SCULPT_DISP_DIR_VIEW:
|
||||
copy_v3_v3(r_area_no, ss->cache->true_view_normal);
|
||||
|
@ -3215,7 +3239,8 @@ static void calc_sculpt_plane(
|
|||
}
|
||||
|
||||
/* For area normal. */
|
||||
if ((!ss->cache->first_time) && (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
|
||||
if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
|
||||
(brush->flag & BRUSH_ORIGINAL_NORMAL)) {
|
||||
copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
|
||||
}
|
||||
else {
|
||||
|
@ -3223,7 +3248,8 @@ static void calc_sculpt_plane(
|
|||
}
|
||||
|
||||
/* For flatten center. */
|
||||
if ((!ss->cache->first_time) && (brush->flag & BRUSH_ORIGINAL_PLANE)) {
|
||||
if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
|
||||
(brush->flag & BRUSH_ORIGINAL_PLANE)) {
|
||||
copy_v3_v3(r_area_co, ss->cache->last_center);
|
||||
}
|
||||
else {
|
||||
|
@ -3450,7 +3476,7 @@ static void do_pinch_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
calc_sculpt_plane(sd, ob, nodes, totnode, area_no, area_co);
|
||||
|
||||
/* delay the first daub because grab delta is not setup */
|
||||
if (ss->cache->first_time) {
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3728,10 +3754,9 @@ void SCULPT_calc_brush_plane(
|
|||
zero_v3(r_area_co);
|
||||
zero_v3(r_area_no);
|
||||
|
||||
if (ss->cache->mirror_symmetry_pass == 0 && ss->cache->radial_symmetry_pass == 0 &&
|
||||
ss->cache->tile_pass == 0 &&
|
||||
(ss->cache->first_time || !(brush->flag & BRUSH_ORIGINAL_PLANE) ||
|
||||
!(brush->flag & BRUSH_ORIGINAL_NORMAL))) {
|
||||
if (SCULPT_stroke_is_main_symmetry_pass(ss->cache) &&
|
||||
(SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) ||
|
||||
!(brush->flag & BRUSH_ORIGINAL_PLANE) || !(brush->flag & BRUSH_ORIGINAL_NORMAL))) {
|
||||
switch (brush->sculpt_plane) {
|
||||
case SCULPT_DISP_DIR_VIEW:
|
||||
copy_v3_v3(r_area_no, ss->cache->true_view_normal);
|
||||
|
@ -3768,7 +3793,8 @@ void SCULPT_calc_brush_plane(
|
|||
}
|
||||
|
||||
/* For area normal. */
|
||||
if ((!ss->cache->first_time) && (brush->flag & BRUSH_ORIGINAL_NORMAL)) {
|
||||
if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
|
||||
(brush->flag & BRUSH_ORIGINAL_NORMAL)) {
|
||||
copy_v3_v3(r_area_no, ss->cache->sculpt_normal);
|
||||
}
|
||||
else {
|
||||
|
@ -3776,7 +3802,8 @@ void SCULPT_calc_brush_plane(
|
|||
}
|
||||
|
||||
/* For flatten center. */
|
||||
if ((!ss->cache->first_time) && (brush->flag & BRUSH_ORIGINAL_PLANE)) {
|
||||
if ((!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) &&
|
||||
(brush->flag & BRUSH_ORIGINAL_PLANE)) {
|
||||
copy_v3_v3(r_area_co, ss->cache->last_center);
|
||||
}
|
||||
else {
|
||||
|
@ -4725,7 +4752,7 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t
|
|||
}
|
||||
|
||||
/* Delay the first daub because grab delta is not setup. */
|
||||
if (ss->cache->first_time) {
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5088,14 +5115,14 @@ static void do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to
|
|||
}
|
||||
|
||||
/* Delay the first daub because grab delta is not setup. */
|
||||
if (ss->cache->first_time) {
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
ss->cache->clay_thumb_front_angle = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Simulate the clay accumulation by increasing the plane angle as more samples are added to the
|
||||
* stroke. */
|
||||
if (ss->cache->mirror_symmetry_pass == 0) {
|
||||
if (SCULPT_stroke_is_main_symmetry_pass(ss->cache)) {
|
||||
ss->cache->clay_thumb_front_angle += 0.8f;
|
||||
CLAMP(ss->cache->clay_thumb_front_angle, 0.0f, 60.0f);
|
||||
}
|
||||
|
@ -5407,8 +5434,8 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
|
|||
* vertices and uses regular coords undo. */
|
||||
/* It also assigns the paint_face_set here as it needs to be done regardless of the stroke type
|
||||
* and the number of nodes under the brush influence. */
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS && ss->cache->first_time &&
|
||||
ss->cache->mirror_symmetry_pass == 0 && !ss->cache->alt_smooth) {
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS &&
|
||||
SCULPT_stroke_is_first_brush_step(ss->cache) && !ss->cache->alt_smooth) {
|
||||
|
||||
/* Dyntopo does not support Face Sets data, so it can't store/restore it from undo. */
|
||||
/* TODO (pablodp606): This check should be done in the undo code and not here, but the rest of
|
||||
|
@ -5450,14 +5477,13 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe
|
|||
update_brush_local_mat(sd, ob);
|
||||
}
|
||||
|
||||
if (ss->cache->first_time && ss->cache->mirror_symmetry_pass == 0) {
|
||||
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
||||
if (SCULPT_is_automasking_enabled(sd, ss, brush)) {
|
||||
SCULPT_automasking_init(sd, ob);
|
||||
}
|
||||
}
|
||||
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_POSE && ss->cache->first_time &&
|
||||
ss->cache->mirror_symmetry_pass == 0) {
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_POSE && SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
||||
SCULPT_pose_brush_init(sd, ob, ss, brush);
|
||||
}
|
||||
|
||||
|
@ -6390,7 +6416,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
|
|||
sculpt_brush_use_topology_rake(ss, brush)) {
|
||||
float grab_location[3], imat[4][4], delta[3], loc[3];
|
||||
|
||||
if (cache->first_time) {
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
if (tool == SCULPT_TOOL_GRAB && brush->flag & BRUSH_GRAB_ACTIVE_VERTEX) {
|
||||
copy_v3_v3(cache->orig_grab_location, SCULPT_active_vertex_co_get(ss));
|
||||
}
|
||||
|
@ -6407,7 +6433,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
|
|||
ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->region, loc, mouse, grab_location);
|
||||
|
||||
/* Compute delta to move verts by. */
|
||||
if (!cache->first_time) {
|
||||
if (!SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
if (sculpt_needs_delta_from_anchored_origin(brush)) {
|
||||
sub_v3_v3v3(delta, grab_location, cache->old_grab_location);
|
||||
invert_m4_m4(imat, ob->obmat);
|
||||
|
@ -6471,7 +6497,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
|
|||
invert_m4_m4(imat, ob->obmat);
|
||||
mul_mat3_m4_v3(imat, grab_location);
|
||||
|
||||
if (cache->first_time) {
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
copy_v3_v3(cache->rake_data.follow_co, grab_location);
|
||||
}
|
||||
|
||||
|
@ -6525,7 +6551,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
|
|||
StrokeCache *cache = ss->cache;
|
||||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
|
||||
if (cache->first_time ||
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) ||
|
||||
!((brush->flag & BRUSH_ANCHORED) || (brush->sculpt_tool == SCULPT_TOOL_SNAKE_HOOK) ||
|
||||
(brush->sculpt_tool == SCULPT_TOOL_ROTATE) || SCULPT_is_cloth_deform_brush(brush))) {
|
||||
RNA_float_get_array(ptr, "location", cache->true_location);
|
||||
|
@ -6543,7 +6569,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
|
|||
}
|
||||
|
||||
/* Truly temporary data that isn't stored in properties. */
|
||||
if (cache->first_time) {
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
if (!BKE_brush_use_locked_size(scene, brush)) {
|
||||
cache->initial_radius = paint_calc_object_space_radius(
|
||||
cache->vc, cache->true_location, BKE_brush_size_get(scene, brush));
|
||||
|
@ -6556,7 +6582,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
|
|||
|
||||
/* Clay stabilized pressure. */
|
||||
if (brush->sculpt_tool == SCULPT_TOOL_CLAY_THUMB) {
|
||||
if (ss->cache->first_time) {
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
for (int i = 0; i < SCULPT_CLAY_STABILIZER_LEN; i++) {
|
||||
ss->cache->clay_pressure_stabilizer[i] = 0.0f;
|
||||
}
|
||||
|
|
|
@ -640,10 +640,10 @@ void SCULPT_do_cloth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
* nodes inside the simulation's limits. */
|
||||
/* Brush stroke types that restore the mesh on each brush step also need the cloth sim data to be
|
||||
* created on each step. */
|
||||
if (ss->cache->first_time || !ss->cache->cloth_sim) {
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache) || !ss->cache->cloth_sim) {
|
||||
|
||||
/* The simulation structure only needs to be created on the first symmetry pass. */
|
||||
if (ss->cache->mirror_symmetry_pass == 0) {
|
||||
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
||||
ss->cache->cloth_sim = cloth_brush_simulation_create(
|
||||
ss, brush->cloth_mass, brush->cloth_damping);
|
||||
for (int i = 0; i < totverts; i++) {
|
||||
|
|
|
@ -183,6 +183,10 @@ bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, int index);
|
|||
void SCULPT_face_sets_visibility_invert(SculptSession *ss);
|
||||
void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible);
|
||||
|
||||
bool SCULPT_stroke_is_main_symmetry_pass(struct StrokeCache *cache);
|
||||
bool SCULPT_stroke_is_first_brush_step(struct StrokeCache *cache);
|
||||
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(struct StrokeCache *cache);
|
||||
|
||||
/* Sculpt Original Data */
|
||||
typedef struct {
|
||||
struct BMLog *bm_log;
|
||||
|
|
|
@ -257,7 +257,7 @@ void SCULPT_do_multiplane_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes,
|
|||
}
|
||||
|
||||
/* Delay the first daub because grab delta is not setup. */
|
||||
if (ss->cache->first_time) {
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
ss->cache->multiplane_scrape_angle = 0.0f;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -247,8 +247,10 @@ void SCULPT_do_paint_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
return;
|
||||
}
|
||||
|
||||
if (ss->cache->first_time && ss->cache->mirror_symmetry_pass == 0) {
|
||||
ss->cache->density_seed = BLI_hash_int_01(ss->cache->location[0] * 1000);
|
||||
if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) {
|
||||
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
||||
ss->cache->density_seed = BLI_hash_int_01(ss->cache->location[0] * 1000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -444,7 +446,7 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode
|
|||
|
||||
const int totvert = SCULPT_vertex_count_get(ss);
|
||||
|
||||
if (ss->cache->first_time && ss->cache->mirror_symmetry_pass == 0) {
|
||||
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
||||
if (!ss->cache->prev_colors) {
|
||||
ss->cache->prev_colors = MEM_callocN(sizeof(float) * 4 * totvert, "prev colors");
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
|
|
|
@ -612,8 +612,7 @@ void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, in
|
|||
Brush *brush = BKE_paint_brush(&sd->paint);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
if (ss->cache->first_time && ss->cache->mirror_symmetry_pass == 0 &&
|
||||
ss->cache->radial_symmetry_pass == 0) {
|
||||
if (SCULPT_stroke_is_first_brush_step(ss->cache)) {
|
||||
BLI_assert(ss->cache->surface_smooth_laplacian_disp == NULL);
|
||||
ss->cache->surface_smooth_laplacian_disp = MEM_callocN(
|
||||
SCULPT_vertex_count_get(ss) * 3 * sizeof(float), "HC smooth laplacian b");
|
||||
|
|
Loading…
Reference in New Issue