Merge branch 'arcpatch-D9622' into sculpt-dev
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user