diff --git a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py index d3b37fa3b8c..039daa1451c 100644 --- a/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py +++ b/release/scripts/startup/bl_ui/space_toolsystem_toolbar.py @@ -1405,6 +1405,7 @@ class _defs_sculpt: props = tool.operator_properties("sculpt.trim_lasso_gesture") layout.prop(props, "trim_mode", expand=False) layout.prop(props, "trim_orientation", expand=False) + layout.prop(props, "trim_location", expand=False) layout.prop(props, "use_cursor_depth", expand=False) return dict( idname="builtin.lasso_trim", diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 534d46a22fb..605b16f1575 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -540,6 +540,7 @@ typedef struct SculptSession { /* For Sculpt trimming gesture tools, initial raycast data from the position of the mouse when * the gesture starts (intersection with the surface and if they ray hit the surface or not). */ + float gesture_initial_back_location[3]; float gesture_initial_location[3]; float gesture_initial_normal[3]; bool gesture_initial_hit; diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h index 0fa44067b16..386bbb83763 100644 --- a/source/blender/blenkernel/BKE_pbvh.h +++ b/source/blender/blenkernel/BKE_pbvh.h @@ -159,7 +159,9 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh, const float ray_start[3], const float ray_normal[3], struct IsectRayPrecalc *isect_precalc, + int *hit_count, float *depth, + float *back_depth, int *active_vertex_index, int *active_face_grid_index, float *face_normal); diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c index e61ab13930f..c04e0008ed5 100644 --- a/source/blender/blenkernel/intern/pbvh.c +++ b/source/blender/blenkernel/intern/pbvh.c @@ -2059,6 +2059,59 @@ bool ray_face_intersection_tri(const float ray_start[3], return false; } +bool ray_update_depth_and_hit_count(const float depth_test, + float *r_depth, + float *r_back_depth, + int *hit_count) +{ + (*hit_count)++; + if (depth_test < *r_depth) { + *r_back_depth = *r_depth; + *r_depth = depth_test; + return true; + } + else if (depth_test > *r_depth && depth_test <= *r_back_depth) { + *r_back_depth = depth_test; + return false; + } + + return false; +} + +float ray_face_intersection_depth_quad(const float ray_start[3], + struct IsectRayPrecalc *isect_precalc, + const float t0[3], + const float t1[3], + const float t2[3], + const float t3[3], + float *r_depth, + float *r_back_depth, + int *hit_count) +{ + float depth_test; + if (!(isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t1, t2, &depth_test, NULL) || + isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t2, t3, &depth_test, NULL))) { + return false; + } + return ray_update_depth_and_hit_count(depth_test, r_depth, r_back_depth, hit_count); +} + +bool ray_face_intersection_depth_tri(const float ray_start[3], + struct IsectRayPrecalc *isect_precalc, + const float t0[3], + const float t1[3], + const float t2[3], + float *r_depth, + float *r_back_depth, + int *hit_count) +{ + float depth_test; + if (!isect_ray_tri_watertight_v3(ray_start, isect_precalc, t0, t1, t2, &depth_test, NULL)) { + return false; + } + return ray_update_depth_and_hit_count(depth_test, r_depth, r_back_depth, hit_count); +} + /* Take advantage of the fact we know this wont be an intersection. * Just handle ray-tri edges. */ static float dist_squared_ray_to_tri_v3_fast(const float ray_origin[3], @@ -2138,7 +2191,9 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, const float ray_start[3], const float ray_normal[3], struct IsectRayPrecalc *isect_precalc, + int *hit_count, float *depth, + float *depth_back, int *r_active_vertex_index, int *r_active_face_index, float *r_face_normal) @@ -2172,26 +2227,29 @@ static bool pbvh_faces_node_raycast(PBVH *pbvh, co[2] = vert[mloop[lt->tri[2]].v].co; } - if (ray_face_intersection_tri(ray_start, isect_precalc, co[0], co[1], co[2], depth)) { - hit = true; + if (!ray_face_intersection_depth_tri( + ray_start, isect_precalc, co[0], co[1], co[2], depth, depth_back, hit_count)) { + continue; + } - if (r_face_normal) { - normal_tri_v3(r_face_normal, co[0], co[1], co[2]); - } + hit = true; - if (r_active_vertex_index) { - float location[3] = {0.0f}; - madd_v3_v3v3fl(location, ray_start, ray_normal, *depth); - for (int j = 0; j < 3; j++) { - /* Always assign nearest_vertex_co in the first iteration to avoid comparison against - * uninitialized values. This stores the closest vertex in the current intersecting - * triangle. */ - if (j == 0 || - len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co)) { - copy_v3_v3(nearest_vertex_co, co[j]); - *r_active_vertex_index = mloop[lt->tri[j]].v; - *r_active_face_index = lt->poly; - } + if (r_face_normal) { + normal_tri_v3(r_face_normal, co[0], co[1], co[2]); + } + + if (r_active_vertex_index) { + float location[3] = {0.0f}; + madd_v3_v3v3fl(location, ray_start, ray_normal, *depth); + for (int j = 0; j < 3; j++) { + /* Always assign nearest_vertex_co in the first iteration to avoid comparison against + * uninitialized values. This stores the closest vertex in the current intersecting + * triangle. */ + if (j == 0 || + len_squared_v3v3(location, co[j]) < len_squared_v3v3(location, nearest_vertex_co)) { + copy_v3_v3(nearest_vertex_co, co[j]); + *r_active_vertex_index = mloop[lt->tri[j]].v; + *r_active_face_index = lt->poly; } } } @@ -2206,7 +2264,9 @@ static bool pbvh_grids_node_raycast(PBVH *pbvh, const float ray_start[3], const float ray_normal[3], struct IsectRayPrecalc *isect_precalc, + int *hit_count, float *depth, + float *back_depth, int *r_active_vertex_index, int *r_active_grid_index, float *r_face_normal) @@ -2251,37 +2311,45 @@ static bool pbvh_grids_node_raycast(PBVH *pbvh, co[3] = CCG_grid_elem_co(gridkey, grid, x, y + 1); } - if (ray_face_intersection_quad( - ray_start, isect_precalc, co[0], co[1], co[2], co[3], depth)) { - hit = true; + if (ray_face_intersection_depth_quad(ray_start, + isect_precalc, + co[0], + co[1], + co[2], + co[3], + depth, + back_depth, + hit_count)) { + continue; + } + hit = true; - if (r_face_normal) { - normal_quad_v3(r_face_normal, co[0], co[1], co[2], co[3]); - } + if (r_face_normal) { + normal_quad_v3(r_face_normal, co[0], co[1], co[2], co[3]); + } - if (r_active_vertex_index) { - float location[3] = {0.0}; - madd_v3_v3v3fl(location, ray_start, ray_normal, *depth); + if (r_active_vertex_index) { + float location[3] = {0.0}; + madd_v3_v3v3fl(location, ray_start, ray_normal, *depth); - const int x_it[4] = {0, 1, 1, 0}; - const int y_it[4] = {0, 0, 1, 1}; + const int x_it[4] = {0, 1, 1, 0}; + const int y_it[4] = {0, 0, 1, 1}; - for (int j = 0; j < 4; j++) { - /* Always assign nearest_vertex_co in the first iteration to avoid comparison against - * uninitialized values. This stores the closest vertex in the current intersecting - * quad. */ - if (j == 0 || len_squared_v3v3(location, co[j]) < - len_squared_v3v3(location, nearest_vertex_co)) { - copy_v3_v3(nearest_vertex_co, co[j]); + for (int j = 0; j < 4; j++) { + /* Always assign nearest_vertex_co in the first iteration to avoid comparison against + * uninitialized values. This stores the closest vertex in the current intersecting + * quad. */ + if (j == 0 || len_squared_v3v3(location, co[j]) < + len_squared_v3v3(location, nearest_vertex_co)) { + copy_v3_v3(nearest_vertex_co, co[j]); - *r_active_vertex_index = gridkey->grid_area * grid_index + - (y + y_it[j]) * gridkey->grid_size + (x + x_it[j]); - } + *r_active_vertex_index = gridkey->grid_area * grid_index + + (y + y_it[j]) * gridkey->grid_size + (x + x_it[j]); } } - if (r_active_grid_index) { - *r_active_grid_index = grid_index; - } + } + if (r_active_grid_index) { + *r_active_grid_index = grid_index; } } } @@ -2301,7 +2369,9 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh, const float ray_start[3], const float ray_normal[3], struct IsectRayPrecalc *isect_precalc, + int *hit_count, float *depth, + float *back_depth, int *active_vertex_index, int *active_face_grid_index, float *face_normal) @@ -2320,7 +2390,9 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh, ray_start, ray_normal, isect_precalc, + hit_count, depth, + back_depth, active_vertex_index, active_face_grid_index, face_normal); @@ -2332,7 +2404,9 @@ bool BKE_pbvh_node_raycast(PBVH *pbvh, ray_start, ray_normal, isect_precalc, + hit_count, depth, + back_depth, active_vertex_index, active_face_grid_index, face_normal); diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 44258d8dba2..a575e0c86d9 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -1367,7 +1367,7 @@ static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcon pcontext->prev_active_vertex_index = ss->active_vertex_index; if (!ups->stroke_active) { pcontext->is_cursor_over_mesh = SCULPT_cursor_geometry_info_update( - C, &gi, mouse, pcontext->brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE); + C, &gi, mouse, (pcontext->brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE), false); copy_v3_v3(pcontext->location, gi.location); copy_v3_v3(pcontext->normal, gi.normal); } diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index 5f09abae21f..fddb5ab5592 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -950,6 +950,24 @@ static EnumPropertyItem prop_trim_orientation_types[] = { {0, NULL, 0, NULL, NULL}, }; +typedef enum eSculptTrimLocationType { + SCULPT_GESTURE_TRIM_LOCATION_DEPTH_SURFACE, + SCULPT_GESTURE_TRIM_LOCATION_DEPTH_VOLUME, +} eSculptTrimLocationType; +static EnumPropertyItem prop_trim_location_types[] = { + {SCULPT_GESTURE_TRIM_LOCATION_DEPTH_SURFACE, + "DEPTH_SURFACE", + 0, + "Surface", + "Use the surface under the cursor to locate the trimming shape"}, + {SCULPT_GESTURE_TRIM_LOCATION_DEPTH_VOLUME, + "DEPTH_VOLUME", + 0, + "Volume", + "Use the volume of the mesh to locate the trimming shape in the center of the volume"}, + {0, NULL, 0, NULL, NULL}, +}; + typedef struct SculptGestureTrimOperation { SculptGestureOperation op; @@ -963,6 +981,7 @@ typedef struct SculptGestureTrimOperation { eSculptTrimOperationType mode; eSculptTrimOrientationType orientation; + eSculptTrimLocationType location; } SculptGestureTrimOperation; static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext) @@ -1054,8 +1073,19 @@ static void sculpt_gesture_trim_calculate_depth(bContext *C, SculptGestureContex if (trim_operation->use_cursor_depth) { float world_space_gesture_initial_location[3]; - mul_v3_m4v3( - world_space_gesture_initial_location, vc->obact->obmat, ss->gesture_initial_location); + + switch (trim_operation->location) { + case SCULPT_GESTURE_TRIM_LOCATION_DEPTH_SURFACE: { + mul_v3_m4v3( + world_space_gesture_initial_location, vc->obact->obmat, ss->gesture_initial_location); + + } break; + case SCULPT_GESTURE_TRIM_LOCATION_DEPTH_VOLUME: { + float center_co[3]; + mid_v3_v3v3(center_co, ss->gesture_initial_location, ss->gesture_initial_back_location); + mul_v3_m4v3(world_space_gesture_initial_location, vc->obact->obmat, center_co); + } break; + } float mid_point_depth; if (trim_operation->orientation == SCULPT_GESTURE_TRIM_ORIENTATION_VIEW) { @@ -1363,6 +1393,7 @@ static void sculpt_gesture_init_trim_properties(SculptGestureContext *sgcontext, trim_operation->mode = RNA_enum_get(op->ptr, "trim_mode"); trim_operation->use_cursor_depth = RNA_boolean_get(op->ptr, "use_cursor_depth"); trim_operation->orientation = RNA_enum_get(op->ptr, "trim_orientation"); + trim_operation->location = RNA_enum_get(op->ptr, "trim_location"); /* If the cursor was not over the mesh, force the orientation to view. */ if (!sgcontext->ss->gesture_initial_hit) { @@ -1390,6 +1421,13 @@ static void sculpt_trim_gesture_operator_properties(wmOperatorType *ot) SCULPT_GESTURE_TRIM_ORIENTATION_VIEW, "Shape Orientation", NULL); + + RNA_def_enum(ot->srna, + "trim_location", + prop_trim_location_types, + SCULPT_GESTURE_TRIM_LOCATION_DEPTH_SURFACE, + "Shape Location", + NULL); } /* Project Gesture Operation. */ @@ -1741,7 +1779,7 @@ static int sculpt_trim_gesture_box_invoke(bContext *C, wmOperator *op, const wmE SculptCursorGeometryInfo sgi; float mouse[2] = {event->mval[0], event->mval[1]}; SCULPT_vertex_random_access_ensure(ss); - ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false); if (ss->gesture_initial_hit) { copy_v3_v3(ss->gesture_initial_location, sgi.location); copy_v3_v3(ss->gesture_initial_normal, sgi.normal); @@ -1782,9 +1820,10 @@ static int sculpt_trim_gesture_lasso_invoke(bContext *C, wmOperator *op, const w SculptCursorGeometryInfo sgi; float mouse[2] = {event->mval[0], event->mval[1]}; SCULPT_vertex_random_access_ensure(ss); - ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + ss->gesture_initial_hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, true); if (ss->gesture_initial_hit) { copy_v3_v3(ss->gesture_initial_location, sgi.location); + copy_v3_v3(ss->gesture_initial_back_location, sgi.back_location); copy_v3_v3(ss->gesture_initial_normal, sgi.normal); } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index a406133d7c8..e380dfe538b 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -2887,9 +2887,18 @@ typedef struct { const float *ray_start; const float *ray_normal; bool hit; + int hit_count; + bool back_hit; float depth; bool original; + /* Depth of the second raycast hit. */ + float back_depth; + + /* When the back depth is not needed, this can be set to false to avoid traversing unnecesary + * nodes. */ + bool use_back_depth; + int active_vertex_index; float *face_normal; @@ -7791,8 +7800,8 @@ void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *b static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) { - if (BKE_pbvh_node_get_tmin(node) < *tmin) { - SculptRaycastData *srd = data_v; + SculptRaycastData *srd = data_v; + if (srd->use_back_depth || BKE_pbvh_node_get_tmin(node) < *tmin) { float(*origco)[3] = NULL; bool use_origco = false; @@ -7815,13 +7824,19 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) srd->ray_start, srd->ray_normal, &srd->isect_precalc, + &srd->hit_count, &srd->depth, + &srd->back_depth, &srd->active_vertex_index, &srd->active_face_grid_index, srd->face_normal)) { srd->hit = true; *tmin = srd->depth; } + + if (srd->hit_count >= 2) { + srd->back_hit = true; + } } } @@ -7901,7 +7916,8 @@ float SCULPT_raycast_init(ViewContext *vc, bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mouse[2], - bool use_sampled_normal) + bool use_sampled_normal, + bool use_back_depth) { Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); Scene *scene = CTX_data_scene(C); @@ -7931,14 +7947,19 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, /* PBVH raycast to get active vertex and face normal. */ depth = SCULPT_raycast_init(&vc, mouse, ray_start, ray_end, ray_normal, original); SCULPT_stroke_modifiers_check(C, ob, brush); + float back_depth = depth; SculptRaycastData srd = { .original = original, .ss = ob->sculpt, .hit = false, + .back_hit = false, .ray_start = ray_start, .ray_normal = ray_normal, .depth = depth, + .back_depth = back_depth, + .hit_count = 0, + .use_back_depth = use_back_depth, .face_normal = face_normal, }; isect_ray_tri_watertight_v3_precalc(&srd.isect_precalc, ray_normal); @@ -7976,6 +7997,17 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, mul_v3_fl(out->location, srd.depth); add_v3_v3(out->location, ray_start); + if (use_back_depth) { + copy_v3_v3(out->back_location, ray_normal); + if (srd.back_hit) { + mul_v3_fl(out->back_location, srd.back_depth); + } + else { + mul_v3_fl(out->back_location, srd.depth); + } + add_v3_v3(out->back_location, ray_start); + } + /* Option to return the face normal directly for performance o accuracy reasons. */ if (!use_sampled_normal) { copy_v3_v3(out->normal, srd.face_normal); @@ -9814,7 +9846,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven float mouse[2]; mouse[0] = event->mval[0]; mouse[1] = event->mval[1]; - SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false); SCULPT_undo_push_begin(ob, "Mask by color"); diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index 1a6ff117dc7..6cd351ed3fe 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -1657,7 +1657,7 @@ static int sculpt_cloth_filter_invoke(bContext *C, wmOperator *op, const wmEvent SculptCursorGeometryInfo sgi; mouse[0] = event->mval[0]; mouse[1] = event->mval[1]; - SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false); SCULPT_vertex_random_access_ensure(ss); diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c index aa1d407dc24..fcf281cb44d 100644 --- a/source/blender/editors/sculpt_paint/sculpt_detail.c +++ b/source/blender/editors/sculpt_paint/sculpt_detail.c @@ -180,7 +180,7 @@ static void sample_detail_voxel(bContext *C, ViewContext *vc, int mx, int my) /* Update the active vertex. */ const float mouse[2] = {mx, my}; - SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false); BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false); /* Average the edge length of the connected edges to the active vertex. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index d5ecef86e59..e3d4eed8ce1 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -1137,7 +1137,7 @@ static int sculpt_expand_target_vertex_update_and_get(bContext *C, { SculptSession *ss = ob->sculpt; SculptCursorGeometryInfo sgi; - if (SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false)) { + if (SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false)) { return SCULPT_active_vertex_get(ss); } else { diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c index 5842a47075e..a00694ef07a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.c +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c @@ -111,7 +111,7 @@ int ED_sculpt_face_sets_active_update_and_get(bContext *C, Object *ob, const flo } SculptCursorGeometryInfo gi; - if (!SCULPT_cursor_geometry_info_update(C, &gi, mval, false)) { + if (!SCULPT_cursor_geometry_info_update(C, &gi, mval, false, false)) { return SCULPT_FACE_SET_NONE; } @@ -963,7 +963,7 @@ static int sculpt_face_sets_change_visibility_invoke(bContext *C, mouse[0] = event->mval[0]; mouse[1] = event->mval[1]; SCULPT_vertex_random_access_ensure(ss); - SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false); return sculpt_face_sets_change_visibility_exec(C, op); } @@ -1668,10 +1668,12 @@ static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEven * tool without brush cursor. */ SculptCursorGeometryInfo sgi; const float mouse[2] = {event->mval[0], event->mval[1]}; - if (!SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false)) { + + if (!SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false)) { /* The cursor is not over the mesh. Cancel to avoid editing the last updated Face Set ID. */ return OPERATOR_CANCELLED; } + const int active_face_set = SCULPT_active_face_set_get(ss); switch (mode) { diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c index 76a6b05cdff..f2d7613eefb 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c @@ -275,7 +275,7 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent SculptCursorGeometryInfo sgi; mouse[0] = event->mval[0]; mouse[1] = event->mval[1]; - SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false); } /* Disable for multires and dyntopo for now */ diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c index 12a179ef0bb..ba0d1f86489 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c @@ -745,7 +745,7 @@ static int sculpt_mesh_filter_invoke(bContext *C, wmOperator *op, const wmEvent SculptCursorGeometryInfo sgi; mouse[0] = event->mval[0]; mouse[1] = event->mval[1]; - SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false); } SCULPT_vertex_random_access_ensure(ss); diff --git a/source/blender/editors/sculpt_paint/sculpt_gradient.c b/source/blender/editors/sculpt_paint/sculpt_gradient.c index daa4680cd38..73ec4d3dcd2 100644 --- a/source/blender/editors/sculpt_paint/sculpt_gradient.c +++ b/source/blender/editors/sculpt_paint/sculpt_gradient.c @@ -197,7 +197,7 @@ static void sculpt_gradient_context_init_common(bContext *C, /* Depth */ SculptCursorGeometryInfo sgi; float mouse[2] = {event->mval[0], event->mval[1]}; - const bool hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + const bool hit = SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false); if (hit) { copy_v3_v3(gcontext->depth_point, sgi.location); } diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 380e78595fe..26653362235 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -74,6 +74,7 @@ void SCULPT_tag_update_overlays(bContext *C); typedef struct SculptCursorGeometryInfo { float location[3]; + float back_location[3]; float normal[3]; float active_vertex_co[3]; } SculptCursorGeometryInfo; @@ -82,7 +83,8 @@ bool SCULPT_stroke_get_location(struct bContext *C, float out[3], const float mo bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mouse[2], - bool use_sampled_normal); + bool use_sampled_normal, + bool use_back_depth); void SCULPT_geometry_preview_lines_update(bContext *C, struct SculptSession *ss, float radius); void SCULPT_stroke_modifiers_check(const bContext *C, Object *ob, const Brush *brush); diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c index 5e229e020ad..7a966568076 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c @@ -188,7 +188,7 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * float mouse[2]; mouse[0] = event->mval[0]; mouse[1] = event->mval[1]; - if (SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false)) { + if (SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false)) { /* The cursor is over the mesh, get the update iteration from the updated active vertex. */ mask_expand_update_it = ss->filter_cache->mask_update_it[(int)SCULPT_active_vertex_get(ss)]; } @@ -368,7 +368,7 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent op->customdata = MEM_mallocN(sizeof(float[2]), "initial mouse position"); copy_v2_v2(op->customdata, mouse); - SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false); + SCULPT_cursor_geometry_info_update(C, &sgi, mouse, false, false); BKE_sculpt_update_object_for_edit(depsgraph, ob, true, true, false);