Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_stroke.c')
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c70
1 files changed, 49 insertions, 21 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 210cffcbcda..88e7a786a47 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -79,6 +79,8 @@ typedef struct PaintStroke {
float last_mouse_position[2];
float last_world_space_position[3];
+ float last_scene_spacing_delta[3];
+
bool stroke_over_mesh;
/* space distance covered so far */
float stroke_distance;
@@ -120,6 +122,8 @@ typedef struct PaintStroke {
StrokeUpdateStep update_step;
StrokeRedraw redraw;
StrokeDone done;
+
+ bool original; /* Raycast original mesh at start of stroke */
} PaintStroke;
/*** Cursors ***/
@@ -243,6 +247,11 @@ static bool paint_stroke_use_scene_spacing(Brush *brush, ePaintMode mode)
return false;
}
+static bool paint_tool_raycast_original(Brush *brush, ePaintMode UNUSED(mode))
+{
+ return brush->flag & BRUSH_ANCHORED;
+}
+
static bool paint_tool_require_inbetween_mouse_events(Brush *brush, ePaintMode mode)
{
if (brush->flag & BRUSH_ANCHORED) {
@@ -392,7 +401,7 @@ static bool paint_brush_update(bContext *C,
halfway[1] = dy * 0.5f + stroke->initial_mouse[1];
if (stroke->get_location) {
- if (stroke->get_location(C, r_location, halfway)) {
+ if (stroke->get_location(C, r_location, halfway, stroke->original)) {
hit = true;
location_sampled = true;
location_success = true;
@@ -466,7 +475,7 @@ static bool paint_brush_update(bContext *C,
if (!location_sampled) {
if (stroke->get_location) {
- if (stroke->get_location(C, r_location, mouse)) {
+ if (stroke->get_location(C, r_location, mouse, stroke->original)) {
location_success = true;
*r_location_is_set = true;
}
@@ -506,7 +515,7 @@ static bool paint_stroke_use_jitter(ePaintMode mode, Brush *brush, bool invert)
/* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */
static void paint_brush_stroke_add_step(
- bContext *C, wmOperator *op, PaintStroke *stroke, const float mouse_in[2], float pressure)
+ bContext *C, wmOperator *op, PaintStroke *stroke, const float mval[2], float pressure)
{
Scene *scene = CTX_data_scene(C);
Paint *paint = BKE_paint_get_active_from_context(C);
@@ -546,12 +555,20 @@ static void paint_brush_stroke_add_step(
/* copy last position -before- jittering, or space fill code
* will create too many dabs */
- copy_v2_v2(stroke->last_mouse_position, mouse_in);
+ copy_v2_v2(stroke->last_mouse_position, mval);
stroke->last_pressure = pressure;
if (paint_stroke_use_scene_spacing(brush, mode)) {
- SCULPT_stroke_get_location(C, stroke->last_world_space_position, stroke->last_mouse_position);
- mul_m4_v3(stroke->vc.obact->obmat, stroke->last_world_space_position);
+ float world_space_position[3];
+
+ if (SCULPT_stroke_get_location(
+ C, world_space_position, stroke->last_mouse_position, stroke->original)) {
+ copy_v3_v3(stroke->last_world_space_position, world_space_position);
+ mul_m4_v3(stroke->vc.obact->obmat, stroke->last_world_space_position);
+ }
+ else {
+ add_v3_v3(stroke->last_world_space_position, stroke->last_scene_spacing_delta);
+ }
}
if (paint_stroke_use_jitter(mode, brush, stroke->stroke_mode == BRUSH_STROKE_INVERT)) {
@@ -562,24 +579,24 @@ static void paint_brush_stroke_add_step(
factor *= pressure;
}
- BKE_brush_jitter_pos(scene, brush, mouse_in, mouse_out);
+ BKE_brush_jitter_pos(scene, brush, mval, mouse_out);
/* XXX: meh, this is round about because
* BKE_brush_jitter_pos isn't written in the best way to
* be reused here */
if (factor != 1.0f) {
- sub_v2_v2v2(delta, mouse_out, mouse_in);
+ sub_v2_v2v2(delta, mouse_out, mval);
mul_v2_fl(delta, factor);
- add_v2_v2v2(mouse_out, mouse_in, delta);
+ add_v2_v2v2(mouse_out, mval, delta);
}
}
else {
- copy_v2_v2(mouse_out, mouse_in);
+ copy_v2_v2(mouse_out, mval);
}
bool is_location_is_set;
ups->last_hit = paint_brush_update(
- C, brush, mode, stroke, mouse_in, mouse_out, pressure, location, &is_location_is_set);
+ C, brush, mode, stroke, mval, mouse_out, pressure, location, &is_location_is_set);
if (is_location_is_set) {
copy_v3_v3(ups->last_location, location);
}
@@ -605,7 +622,7 @@ static void paint_brush_stroke_add_step(
/* Mouse coordinates modified by the stroke type options. */
RNA_float_set_array(&itemptr, "mouse", mouse_out);
/* Original mouse coordinates. */
- RNA_float_set_array(&itemptr, "mouse_event", mouse_in);
+ RNA_float_set_array(&itemptr, "mouse_event", mval);
RNA_boolean_set(&itemptr, "pen_flip", stroke->pen_flip);
RNA_float_set(&itemptr, "pressure", pressure);
RNA_float_set(&itemptr, "x_tilt", stroke->x_tilt);
@@ -698,7 +715,7 @@ static float paint_space_stroke_spacing(bContext *C,
spacing *= stroke->zoom_2d;
if (paint_stroke_use_scene_spacing(brush, mode)) {
- return max_ff(0.001f, size_clamp * spacing / 50.0f);
+ return size_clamp * spacing / 50.0f;
}
return max_ff(stroke->zoom_2d, size_clamp * spacing / 50.0f);
}
@@ -807,7 +824,7 @@ static int paint_space_stroke(bContext *C,
if (use_scene_spacing) {
float world_space_position[3];
- bool hit = SCULPT_stroke_get_location(C, world_space_position, final_mouse);
+ bool hit = SCULPT_stroke_get_location(C, world_space_position, final_mouse, stroke->original);
mul_m4_v3(stroke->vc.obact->obmat, world_space_position);
if (hit && stroke->stroke_over_mesh) {
sub_v3_v3v3(d_world_space_position, world_space_position, stroke->last_world_space_position);
@@ -838,6 +855,8 @@ static int paint_space_stroke(bContext *C,
stroke->last_world_space_position,
final_world_space_position);
ED_view3d_project_v2(region, final_world_space_position, mouse);
+
+ mul_v3_v3fl(stroke->last_scene_spacing_delta, d_world_space_position, spacing);
}
else {
mouse[0] = stroke->last_mouse_position[0] + dmouse[0] * spacing;
@@ -896,6 +915,8 @@ PaintStroke *paint_stroke_new(bContext *C,
stroke->ups = ups;
stroke->stroke_mode = RNA_enum_get(op->ptr, "mode");
+ stroke->original = paint_tool_raycast_original(br, BKE_paintmode_get_active_from_context(C));
+
get_imapaint_zoom(C, &zoomx, &zoomy);
stroke->zoom_2d = max_ff(zoomx, zoomy);
@@ -912,8 +933,13 @@ PaintStroke *paint_stroke_new(bContext *C,
rv3d->rflag |= RV3D_PAINTING;
}
- zero_v3(ups->average_stroke_accum);
- ups->average_stroke_counter = 0;
+ /* Preserve location from last stroke while applying and resetting
+ * ups->average_stroke_counter to 1.
+ */
+ if (ups->average_stroke_counter) {
+ mul_v3_fl(ups->average_stroke_accum, 1.0f / (float)ups->average_stroke_counter);
+ ups->average_stroke_counter = 1;
+ }
/* initialize here to avoid initialization conflict with threaded strokes */
BKE_curvemapping_init(br->curve);
@@ -990,7 +1016,7 @@ static void stroke_done(bContext *C, wmOperator *op, PaintStroke *stroke)
static bool curves_sculpt_brush_uses_spacing(const eBrushCurvesSculptTool tool)
{
- return ELEM(tool, CURVES_SCULPT_TOOL_ADD);
+ return ELEM(tool, CURVES_SCULPT_TOOL_ADD, CURVES_SCULPT_TOOL_DENSITY);
}
bool paint_space_stroke_enabled(Brush *br, ePaintMode mode)
@@ -1186,8 +1212,10 @@ static void paint_line_strokes_spacing(bContext *C,
copy_v2_v2(stroke->last_mouse_position, old_pos);
if (use_scene_spacing) {
- bool hit_old = SCULPT_stroke_get_location(C, world_space_position_old, old_pos);
- bool hit_new = SCULPT_stroke_get_location(C, world_space_position_new, new_pos);
+ bool hit_old = SCULPT_stroke_get_location(
+ C, world_space_position_old, old_pos, stroke->original);
+ bool hit_new = SCULPT_stroke_get_location(
+ C, world_space_position_new, new_pos, stroke->original);
mul_m4_v3(stroke->vc.obact->obmat, world_space_position_old);
mul_m4_v3(stroke->vc.obact->obmat, world_space_position_new);
if (hit_old && hit_new && stroke->stroke_over_mesh) {
@@ -1331,7 +1359,7 @@ static bool paint_stroke_curve_end(bContext *C, wmOperator *op, PaintStroke *str
if (paint_stroke_use_scene_spacing(br, BKE_paintmode_get_active_from_context(C))) {
stroke->stroke_over_mesh = SCULPT_stroke_get_location(
- C, stroke->last_world_space_position, data + 2 * j);
+ C, stroke->last_world_space_position, data + 2 * j, stroke->original);
mul_m4_v3(stroke->vc.obact->obmat, stroke->last_world_space_position);
}
@@ -1463,7 +1491,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, const wmEvent *event, PaintS
copy_v2_v2(stroke->last_mouse_position, sample_average.mouse);
if (paint_stroke_use_scene_spacing(br, mode)) {
stroke->stroke_over_mesh = SCULPT_stroke_get_location(
- C, stroke->last_world_space_position, sample_average.mouse);
+ C, stroke->last_world_space_position, sample_average.mouse, stroke->original);
mul_m4_v3(stroke->vc.obact->obmat, stroke->last_world_space_position);
}
stroke->stroke_started = stroke->test_start(C, op, sample_average.mouse);