diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 230 |
1 files changed, 181 insertions, 49 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 13b576f0402..03d079ba0e1 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -109,7 +109,7 @@ * For multi-resolution, the same vertex in multiple grids is counted multiple times, with * different index for each grid. */ -void SCULPT_vertex_random_access_init(SculptSession *ss) +void SCULPT_vertex_random_access_ensure(SculptSession *ss) { if (BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) { BM_mesh_elem_index_ensure(ss->bm, BM_VERT); @@ -196,7 +196,7 @@ void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]) } } -static const float *sculpt_vertex_persistent_co_get(SculptSession *ss, int index) +const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index) { if (ss->persistent_base) { return ss->persistent_base[index].co; @@ -204,7 +204,28 @@ static const float *sculpt_vertex_persistent_co_get(SculptSession *ss, int index return SCULPT_vertex_co_get(ss, index); } -static void sculpt_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]) +void SCULPT_vertex_limit_surface_get(SculptSession *ss, int index, float r_co[3]) +{ + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_FACES: + case PBVH_BMESH: + copy_v3_v3(r_co, SCULPT_vertex_co_get(ss, index)); + break; + case PBVH_GRIDS: { + const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); + const int grid_index = index / key->grid_area; + const int vertex_index = index - grid_index * key->grid_area; + + SubdivCCGCoord coord = {.grid_index = grid_index, + .x = vertex_index % key->grid_size, + .y = vertex_index / key->grid_size}; + BKE_subdiv_ccg_eval_limit_point(ss->subdiv_ccg, &coord, r_co); + break; + } + } +} + +void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]) { if (ss->persistent_base) { copy_v3_v3(no, ss->persistent_base[index].no); @@ -581,7 +602,8 @@ static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss p1 = vert_map->indices[i]; break; } - else if (p2 == -1) { + + if (p2 == -1) { p2 = vert_map->indices[i]; break; } @@ -999,7 +1021,7 @@ bool SCULPT_is_vertex_inside_brush_radius_symm(const float vertex[3], void SCULPT_floodfill_init(SculptSession *ss, SculptFloodFill *flood) { int vertex_count = SCULPT_vertex_count_get(ss); - SCULPT_vertex_random_access_init(ss); + SCULPT_vertex_random_access_ensure(ss); flood->queue = BLI_gsqueue_new(sizeof(int)); flood->visited_vertices = BLI_BITMAP_NEW(vertex_count, "visited vertices"); @@ -1125,6 +1147,7 @@ static bool sculpt_tool_needs_original(const char sculpt_tool) SCULPT_TOOL_DRAW_SHARP, SCULPT_TOOL_ELASTIC_DEFORM, SCULPT_TOOL_SMOOTH, + SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_POSE); } @@ -1134,6 +1157,7 @@ static bool sculpt_tool_is_proxy_used(const char sculpt_tool) SCULPT_TOOL_SMOOTH, SCULPT_TOOL_LAYER, SCULPT_TOOL_POSE, + SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_CLOTH, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR, @@ -1918,8 +1942,7 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, if (use_area_cos && area_test_r) { /* Weight the coordinates towards the center. */ float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius); - float afactor = 3.0f * p * p - 2.0f * p * p * p; - CLAMP(afactor, 0.0f, 1.0f); + const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f); float disp[3]; sub_v3_v3v3(disp, co, area_test.location); @@ -1932,8 +1955,7 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, if (use_area_nos && normal_test_r) { /* Weight the normals towards the center. */ float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius); - float nfactor = 3.0f * p * p - 2.0f * p * p * p; - CLAMP(nfactor, 0.0f, 1.0f); + const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f); mul_v3_fl(no, nfactor); add_v3_v3(anctd->area_nos[flip_index], no); @@ -1994,8 +2016,7 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, if (use_area_cos && area_test_r) { /* Weight the coordinates towards the center. */ float p = 1.0f - (sqrtf(area_test.dist) / area_test.radius); - float afactor = 3.0f * p * p - 2.0f * p * p * p; - CLAMP(afactor, 0.0f, 1.0f); + const float afactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f); float disp[3]; sub_v3_v3v3(disp, co, area_test.location); @@ -2008,8 +2029,7 @@ static void calc_area_normal_and_center_task_cb(void *__restrict userdata, if (use_area_nos && normal_test_r) { /* Weight the normals towards the center. */ float p = 1.0f - (sqrtf(normal_test.dist) / normal_test.radius); - float nfactor = 3.0f * p * p - 2.0f * p * p * p; - CLAMP(nfactor, 0.0f, 1.0f); + const float nfactor = clamp_f(3.0f * p * p - 2.0f * p * p * p, 0.0f, 1.0f); mul_v3_fl(no, nfactor); add_v3_v3(anctd->area_nos[flip_index], no); @@ -2237,6 +2257,8 @@ static float brush_strength(const Sculpt *sd, case SCULPT_TOOL_DRAW_SHARP: case SCULPT_TOOL_LAYER: return alpha * flip * pressure * overlap * feather; + case SCULPT_TOOL_DISPLACEMENT_ERASER: + return alpha * pressure * overlap * feather; case SCULPT_TOOL_CLOTH: if (brush->cloth_deform_type == BRUSH_CLOTH_DEFORM_GRAB) { /* Grab deform uses the same falloff as a regular grab brush. */ @@ -2337,6 +2359,7 @@ static float brush_strength(const Sculpt *sd, case SCULPT_TOOL_ELASTIC_DEFORM: case SCULPT_TOOL_POSE: + case SCULPT_TOOL_BOUNDARY: return root_alpha * feather; default: @@ -2774,8 +2797,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, return; } - float bstrength = data->strength; - CLAMP(bstrength, 0.0f, 1.0f); + const float bstrength = clamp_f(data->strength, 0.0f, 1.0f); SculptBrushTest test; SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( @@ -2814,14 +2836,14 @@ static void bmesh_topology_rake( Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, float bstrength) { Brush *brush = BKE_paint_brush(&sd->paint); - CLAMP(bstrength, 0.0f, 1.0f); + const float strength = clamp_f(bstrength, 0.0f, 1.0f); /* Interactions increase both strength and quality. */ const int iterations = 3; int iteration; - const int count = iterations * bstrength + 1; - const float factor = iterations * bstrength / count; + const int count = iterations * strength + 1; + const float factor = iterations * strength / count; for (iteration = 0; iteration <= count; iteration++) { @@ -2867,7 +2889,7 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata, else { (*vd.mask) += fade * bstrength * (*vd.mask); } - CLAMP(*vd.mask, 0.0f, 1.0f); + *vd.mask = clamp_f(*vd.mask, 0.0f, 1.0f); if (vd.mvert) { vd.mvert->flag |= ME_VERT_PBVH_UPDATE; @@ -2909,6 +2931,73 @@ static void do_mask_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) } } +/** \name Sculpt Multires Displacement Eraser Brush + * \{ */ + +static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, + const int n, + const TaskParallelTLS *__restrict tls) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + const Brush *brush = data->brush; + const float bstrength = clamp_f(ss->cache->bstrength, 0.0f, 1.0f); + + float(*proxy)[3] = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; + + SculptBrushTest test; + SculptBrushTestFn sculpt_brush_test_sq_fn = SCULPT_brush_test_init_with_falloff_shape( + ss, &test, data->brush->falloff_shape); + const int thread_id = BLI_task_parallel_thread_id(tls); + + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) + { + if (sculpt_brush_test_sq_fn(&test, vd.co)) { + const float fade = bstrength * SCULPT_brush_strength_factor(ss, + brush, + vd.co, + sqrtf(test.dist), + vd.no, + vd.fno, + vd.mask ? *vd.mask : 0.0f, + vd.index, + thread_id); + + float limit_co[3]; + float disp[3]; + SCULPT_vertex_limit_surface_get(ss, vd.index, limit_co); + sub_v3_v3v3(disp, limit_co, vd.co); + mul_v3_v3fl(proxy[vd.i], disp, fade); + + if (vd.mvert) { + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + } + } + } + BKE_pbvh_vertex_iter_end; +} + +static void do_displacement_eraser_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +{ + Brush *brush = BKE_paint_brush(&sd->paint); + BKE_curvemapping_init(brush->curve); + + /* Threaded loop over nodes. */ + SculptThreadedTaskData data = { + .sd = sd, + .ob = ob, + .brush = brush, + .nodes = nodes, + }; + + TaskParallelSettings settings; + BKE_pbvh_parallel_range_settings(&settings, true, totnode); + BLI_task_parallel_range(0, totnode, &data, do_displacement_eraser_brush_task_cb_ex, &settings); +} + +/** \} */ + static void do_draw_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls) @@ -2966,7 +3055,7 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise * initialize before threads so they can do curve mapping. */ - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); /* Threaded loop over nodes. */ SculptThreadedTaskData data = { @@ -3043,7 +3132,7 @@ static void do_draw_sharp_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to /* XXX - this shouldn't be necessary, but sculpting crashes in blender2.8 otherwise * initialize before threads so they can do curve mapping. */ - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); /* Threaded loop over nodes. */ SculptThreadedTaskData data = { @@ -3189,7 +3278,7 @@ void SCULPT_relax_vertex(SculptSession *ss, } if (avg_count > 0) { - mul_v3_fl(smooth_pos, 1.0f / (float)avg_count); + mul_v3_fl(smooth_pos, 1.0f / avg_count); } else { copy_v3_v3(r_final_pos, vd->co); @@ -3273,7 +3362,7 @@ static void do_slide_relax_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t return; } - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); SculptThreadedTaskData data = { .sd = sd, @@ -4331,19 +4420,19 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, } if (vd.mask) { const float clamp_mask = 1.0f - *vd.mask; - CLAMP(*disp_factor, -clamp_mask, clamp_mask); + *disp_factor = clamp_f(*disp_factor, -clamp_mask, clamp_mask); } else { - CLAMP(*disp_factor, -1.0f, 1.0f); + *disp_factor = clamp_f(*disp_factor, -1.0f, 1.0f); } float final_co[3]; float normal[3]; if (use_persistent_base) { - sculpt_vertex_persistent_normal_get(ss, vi, normal); + SCULPT_vertex_persistent_normal_get(ss, vi, normal); mul_v3_fl(normal, brush->height); - madd_v3_v3v3fl(final_co, sculpt_vertex_persistent_co_get(ss, vi), normal, *disp_factor); + madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor); } else { normal_short_to_float_v3(normal, orig_data.no); @@ -5184,7 +5273,7 @@ static float sculpt_clay_thumb_get_stabilized_pressure(StrokeCache *cache) for (int i = 0; i < SCULPT_CLAY_STABILIZER_LEN; i++) { final_pressure += cache->clay_pressure_stabilizer[i]; } - return final_pressure / (float)SCULPT_CLAY_STABILIZER_LEN; + return final_pressure / SCULPT_CLAY_STABILIZER_LEN; } static void do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) @@ -5225,7 +5314,7 @@ static void do_clay_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to * stroke. */ 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); + ss->cache->clay_thumb_front_angle = clamp_f(ss->cache->clay_thumb_front_angle, 0.0f, 60.0f); } if (is_zero_v3(ss->cache->grab_delta_symmetry)) { @@ -5509,19 +5598,28 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe /* Pose needs all nodes because it applies all symmetry iterations at the same time and the IK * chain can grow to any area of the model. */ /* This can be optimized by filtering the nodes after calculating the chain. */ - if (ELEM(brush->sculpt_tool, SCULPT_TOOL_ELASTIC_DEFORM, SCULPT_TOOL_POSE)) { + if (ELEM(brush->sculpt_tool, + SCULPT_TOOL_ELASTIC_DEFORM, + SCULPT_TOOL_POSE, + SCULPT_TOOL_BOUNDARY)) { BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); } else if (brush->sculpt_tool == SCULPT_TOOL_CLOTH) { - SculptSearchSphereData data = { - .ss = ss, - .sd = sd, - .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)), - .original = false, - .ignore_fully_ineffective = false, - .center = ss->cache->initial_location, - }; - BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); + if (brush->cloth_simulation_area_type == BRUSH_CLOTH_SIMULATION_AREA_LOCAL) { + SculptSearchSphereData data = { + .ss = ss, + .sd = sd, + .radius_squared = square_f(ss->cache->initial_radius * (1.0 + brush->cloth_sim_limit)), + .original = false, + .ignore_fully_ineffective = false, + .center = ss->cache->initial_location, + }; + BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); + } + else { + /* Gobal simulation, get all nodes. */ + BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); + } } else { const bool use_original = sculpt_tool_needs_original(brush->sculpt_tool) ? true : @@ -5683,12 +5781,18 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe case SCULPT_TOOL_SLIDE_RELAX: do_slide_relax_brush(sd, ob, nodes, totnode); break; + case SCULPT_TOOL_BOUNDARY: + SCULPT_do_boundary_brush(sd, ob, nodes, totnode); + break; case SCULPT_TOOL_CLOTH: SCULPT_do_cloth_brush(sd, ob, nodes, totnode); break; case SCULPT_TOOL_DRAW_FACE_SETS: SCULPT_do_draw_face_sets_brush(sd, ob, nodes, totnode); break; + case SCULPT_TOOL_DISPLACEMENT_ERASER: + do_displacement_eraser_brush(sd, ob, nodes, totnode); + break; case SCULPT_TOOL_PAINT: SCULPT_do_paint_brush(sd, ob, nodes, totnode); break; @@ -5717,8 +5821,10 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe } /* The cloth brush adds the gravity as a regular force and it is processed in the solver. */ - if (ss->cache->supports_gravity && - !ELEM(brush->sculpt_tool, SCULPT_TOOL_CLOTH, SCULPT_TOOL_DRAW_FACE_SETS)) { + if (ss->cache->supports_gravity && !ELEM(brush->sculpt_tool, + SCULPT_TOOL_CLOTH, + SCULPT_TOOL_DRAW_FACE_SETS, + SCULPT_TOOL_BOUNDARY)) { do_gravity(sd, ob, nodes, totnode, sd->gravity_factor); } @@ -5770,6 +5876,7 @@ static void sculpt_combine_proxies_task_cb(void *__restrict userdata, SCULPT_TOOL_ROTATE, SCULPT_TOOL_THUMB, SCULPT_TOOL_ELASTIC_DEFORM, + SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_POSE); PBVHVertexIter vd; @@ -6231,10 +6338,14 @@ static const char *sculpt_tool_name(Sculpt *sd) return "Multi-plane Scrape Brush"; case SCULPT_TOOL_SLIDE_RELAX: return "Slide/Relax Brush"; + case SCULPT_TOOL_BOUNDARY: + return "Boundary Brush"; case SCULPT_TOOL_CLOTH: return "Cloth Brush"; case SCULPT_TOOL_DRAW_FACE_SETS: return "Draw Face Sets"; + case SCULPT_TOOL_DISPLACEMENT_ERASER: + return "Multires Displacement Eraser"; case SCULPT_TOOL_PAINT: return "Paint Brush"; case SCULPT_TOOL_SMEAR: @@ -6259,6 +6370,12 @@ void SCULPT_cache_free(StrokeCache *cache) SCULPT_pose_ik_chain_free(cache->pose_ik_chain); } + for (int i = 0; i < PAINT_SYMM_AREAS; i++) { + if (cache->boundaries[i]) { + SCULPT_boundary_data_free(cache->boundaries[i]); + } + } + if (cache->cloth_sim) { SCULPT_cloth_simulation_free(cache->cloth_sim); } @@ -6390,7 +6507,7 @@ static void sculpt_update_cache_invariants( brush = br; cache->saved_smooth_size = BKE_brush_size_get(scene, brush); BKE_brush_size_set(scene, brush, size); - BKE_curvemapping_initialize(brush->curve); + BKE_curvemapping_init(brush->curve); } } } @@ -6414,9 +6531,12 @@ static void sculpt_update_cache_invariants( mul_m3_v3(mat, viewDir); normalize_v3_v3(cache->true_view_normal, viewDir); - cache->supports_gravity = - (!ELEM(brush->sculpt_tool, SCULPT_TOOL_MASK, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_SIMPLIFY) && - (sd->gravity_factor > 0.0f)); + cache->supports_gravity = (!ELEM(brush->sculpt_tool, + SCULPT_TOOL_MASK, + SCULPT_TOOL_SMOOTH, + SCULPT_TOOL_SIMPLIFY, + SCULPT_TOOL_DISPLACEMENT_ERASER) && + (sd->gravity_factor > 0.0f)); /* Get gravity vector in world space. */ if (cache->supports_gravity) { if (sd->gravity_object) { @@ -6458,7 +6578,7 @@ static void sculpt_update_cache_invariants( #define PIXEL_INPUT_THRESHHOLD 5 if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) { - cache->dial = BLI_dial_initialize(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD); + cache->dial = BLI_dial_init(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD); } #undef PIXEL_INPUT_THRESHHOLD @@ -6487,6 +6607,7 @@ static bool sculpt_needs_delta_from_anchored_origin(Brush *brush) return ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_POSE, + SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_THUMB, SCULPT_TOOL_ELASTIC_DEFORM) || SCULPT_is_cloth_deform_brush(brush); @@ -6530,6 +6651,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru SCULPT_TOOL_CLAY_THUMB, SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_POSE, + SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_THUMB) || sculpt_brush_use_topology_rake(ss, brush)) { float grab_location[3], imat[4][4], delta[3], loc[3]; @@ -6818,6 +6940,7 @@ static bool sculpt_needs_connectivity_info(const Sculpt *sd, (brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || (brush->autosmooth_factor > 0) || ((brush->sculpt_tool == SCULPT_TOOL_MASK) && (brush->mask_tool == BRUSH_MASK_SMOOTH)) || (brush->sculpt_tool == SCULPT_TOOL_POSE) || + (brush->sculpt_tool == SCULPT_TOOL_BOUNDARY) || (brush->sculpt_tool == SCULPT_TOOL_SLIDE_RELAX) || (brush->sculpt_tool == SCULPT_TOOL_CLOTH) || (brush->sculpt_tool == SCULPT_TOOL_SMEAR) || (brush->sculpt_tool == SCULPT_TOOL_DRAW_FACE_SETS)); @@ -7002,6 +7125,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, /* Update the active vertex of the SculptSession. */ ss->active_vertex_index = srd.active_vertex_index; + SCULPT_vertex_random_access_ensure(ss); copy_v3_v3(out->active_vertex_co, SCULPT_active_vertex_co_get(ss)); switch (BKE_pbvh_type(ss->pbvh)) { @@ -7436,7 +7560,7 @@ static void sculpt_stroke_update_step(bContext *C, else { BKE_pbvh_bmesh_detail_size_set(ss->pbvh, (ss->cache->radius / ss->cache->dyntopo_pixel_radius) * - (float)(sd->detail_size * U.pixelsize) / 0.4f); + (sd->detail_size * U.pixelsize) / 0.4f); } if (SCULPT_stroke_is_dynamic_topology(ss, brush)) { @@ -7671,7 +7795,7 @@ static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op)) SculptSession *ss = ob->sculpt; if (ss) { - SCULPT_vertex_random_access_init(ss); + SCULPT_vertex_random_access_ensure(ss); BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false, false); MEM_SAFE_FREE(ss->persistent_base); @@ -8160,6 +8284,14 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float return; } + if (!ss->deform_modifiers_active) { + return; + } + + if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) { + return; + } + BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false); if (!ss->pmap) { @@ -8893,7 +9025,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven return OPERATOR_CANCELLED; } - SCULPT_vertex_random_access_init(ss); + SCULPT_vertex_random_access_ensure(ss); /* Tools that are not brushes do not have the brush gizmo to update the vertex as the mouse move, * so it needs to be updated here. */ |