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:
-rw-r--r--source/blender/blenkernel/BKE_gpencil_geom.h5
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.cc40
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c4
-rw-r--r--source/blender/editors/gpencil/gpencil_fill.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c21
-rw-r--r--source/blender/editors/gpencil/gpencil_primitive.c16
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c27
-rw-r--r--source/blender/editors/include/ED_gpencil.h7
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c2
11 files changed, 111 insertions, 17 deletions
diff --git a/source/blender/blenkernel/BKE_gpencil_geom.h b/source/blender/blenkernel/BKE_gpencil_geom.h
index 29e3a74b1b2..d472fd6f02b 100644
--- a/source/blender/blenkernel/BKE_gpencil_geom.h
+++ b/source/blender/blenkernel/BKE_gpencil_geom.h
@@ -101,7 +101,7 @@ bool BKE_gpencil_stroke_sample(struct bGPdata *gpd,
struct bGPDstroke *gps,
const float dist,
const bool select);
-bool BKE_gpencil_stroke_smooth(struct bGPDstroke *gps, int i, float inf);
+bool BKE_gpencil_stroke_smooth_point(struct bGPDstroke *gps, int i, float inf);
bool BKE_gpencil_stroke_smooth_strength(struct bGPDstroke *gps, int point_index, float influence);
bool BKE_gpencil_stroke_smooth_thickness(struct bGPDstroke *gps, int point_index, float influence);
bool BKE_gpencil_stroke_smooth_uv(struct bGPDstroke *gps, int point_index, float influence);
@@ -151,7 +151,8 @@ void BKE_gpencil_stroke_set_random_color(struct bGPDstroke *gps);
void BKE_gpencil_stroke_join(struct bGPDstroke *gps_a,
struct bGPDstroke *gps_b,
const bool leave_gaps,
- const bool fit_thickness);
+ const bool fit_thickness,
+ const bool smooth);
void BKE_gpencil_stroke_copy_to_keyframes(struct bGPdata *gpd,
struct bGPDlayer *gpl,
struct bGPDframe *gpf,
diff --git a/source/blender/blenkernel/intern/gpencil_geom.cc b/source/blender/blenkernel/intern/gpencil_geom.cc
index 5bca20ecd44..8ff026231f5 100644
--- a/source/blender/blenkernel/intern/gpencil_geom.cc
+++ b/source/blender/blenkernel/intern/gpencil_geom.cc
@@ -800,7 +800,7 @@ bool BKE_gpencil_stroke_shrink(bGPDstroke *gps, const float dist, const short mo
* \param i: Point index
* \param inf: Amount of smoothing to apply
*/
-bool BKE_gpencil_stroke_smooth(bGPDstroke *gps, int i, float inf)
+bool BKE_gpencil_stroke_smooth_point(bGPDstroke *gps, int i, float inf)
{
bGPDspoint *pt = &gps->points[i];
float sco[3] = {0.0f};
@@ -3248,7 +3248,8 @@ static void gpencil_stroke_copy_point(bGPDstroke *gps,
void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
bGPDstroke *gps_b,
const bool leave_gaps,
- const bool fit_thickness)
+ const bool fit_thickness,
+ const bool smooth)
{
bGPDspoint point;
bGPDspoint *pt;
@@ -3326,16 +3327,51 @@ void BKE_gpencil_stroke_join(bGPDstroke *gps_a,
gpencil_stroke_copy_point(gps_a, nullptr, &point, delta, 0.0f, 0.0f, deltatime);
}
+ /* Ratio to apply in the points to keep the same thickness in the joined stroke using the
+ * destination stroke thickness. */
const float ratio = (fit_thickness && gps_a->thickness > 0.0f) ?
(float)gps_b->thickness / (float)gps_a->thickness :
1.0f;
/* 3rd: add all points */
+ const int totpoints_a = gps_a->totpoints;
for (i = 0, pt = gps_b->points; i < gps_b->totpoints && pt; i++, pt++) {
MDeformVert *dvert = (gps_b->dvert) ? &gps_b->dvert[i] : nullptr;
gpencil_stroke_copy_point(
gps_a, dvert, pt, delta, pt->pressure * ratio, pt->strength, deltatime);
}
+ /* Smooth the join to avoid hard thickness changes. */
+ if (smooth) {
+ const int sample_points = 8;
+ /* Get the segment to smooth using n points on each side of the join. */
+ int start = MAX2(0, totpoints_a - sample_points);
+ int end = MIN2(gps_a->totpoints - 1, start + (sample_points * 2));
+ const int len = (end - start);
+ float step = 1.0f / ((len / 2) + 1);
+
+ /* Calc the average pressure. */
+ float avg_pressure = 0.0f;
+ for (i = start; i < end; i++) {
+ pt = &gps_a->points[i];
+ avg_pressure += pt->pressure;
+ }
+ avg_pressure = avg_pressure / len;
+
+ /* Smooth segment thickness and position. */
+ float ratio = step;
+ for (i = start; i < end; i++) {
+ pt = &gps_a->points[i];
+ pt->pressure += (avg_pressure - pt->pressure) * ratio;
+ BKE_gpencil_stroke_smooth_point(gps_a, i, ratio * 0.6f);
+
+ ratio += step;
+ /* In the center, reverse the ratio. */
+ if (ratio > 1.0f) {
+ ratio = ratio - step - step;
+ step *= -1.0f;
+ }
+ }
+ }
}
/* Copy the stroke of the frame to all frames selected (except current). */
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 8d1f841da6c..aa3178ddc2c 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -3618,7 +3618,7 @@ static int gpencil_stroke_join_exec(bContext *C, wmOperator *op)
}
elem = &strokes_list[i];
/* Join new_stroke and stroke B. */
- BKE_gpencil_stroke_join(gps_new, elem->gps, leave_gaps, true);
+ BKE_gpencil_stroke_join(gps_new, elem->gps, leave_gaps, true, false);
elem->used = true;
}
@@ -3967,7 +3967,7 @@ static void gpencil_smooth_stroke(bContext *C, wmOperator *op)
/* perform smoothing */
if (smooth_position) {
- BKE_gpencil_stroke_smooth(gps, i, factor);
+ BKE_gpencil_stroke_smooth_point(gps, i, factor);
}
if (smooth_strength) {
BKE_gpencil_stroke_smooth_strength(gps, i, factor);
diff --git a/source/blender/editors/gpencil/gpencil_fill.c b/source/blender/editors/gpencil/gpencil_fill.c
index 0c88d678ef4..f5474a7cdc3 100644
--- a/source/blender/editors/gpencil/gpencil_fill.c
+++ b/source/blender/editors/gpencil/gpencil_fill.c
@@ -1569,7 +1569,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
float smoothfac = 1.0f;
for (int r = 0; r < 1; r++) {
for (int i = 0; i < gps->totpoints; i++) {
- BKE_gpencil_stroke_smooth(gps, i, smoothfac - reduce);
+ BKE_gpencil_stroke_smooth_point(gps, i, smoothfac - reduce);
}
reduce += 0.25f; /* reduce the factor */
}
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index a8bd3b11bb1..fdd9f44605e 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -333,7 +333,7 @@ static void gpencil_interpolate_smooth_stroke(bGPDstroke *gps,
float reduce = 0.0f;
for (int r = 0; r < smooth_steps; r++) {
for (int i = 0; i < gps->totpoints - 1; i++) {
- BKE_gpencil_stroke_smooth(gps, i, smooth_factor - reduce);
+ BKE_gpencil_stroke_smooth_point(gps, i, smooth_factor - reduce);
BKE_gpencil_stroke_smooth_strength(gps, i, smooth_factor);
}
reduce += 0.25f; /* reduce the factor */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 28a22633742..9b157224178 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -1209,7 +1209,8 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
float reduce = 0.0f;
for (int r = 0; r < brush->gpencil_settings->draw_smoothlvl; r++) {
for (i = 0; i < gps->totpoints - 1; i++) {
- BKE_gpencil_stroke_smooth(gps, i, brush->gpencil_settings->draw_smoothfac - reduce);
+ BKE_gpencil_stroke_smooth_point(
+ gps, i, brush->gpencil_settings->draw_smoothfac - reduce);
BKE_gpencil_stroke_smooth_strength(gps, i, brush->gpencil_settings->draw_smoothfac);
}
reduce += 0.25f; /* reduce the factor */
@@ -1221,7 +1222,7 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
float ifac = (float)brush->gpencil_settings->input_samples / 10.0f;
float sfac = interpf(1.0f, 0.2f, ifac);
for (i = 0; i < gps->totpoints - 1; i++) {
- BKE_gpencil_stroke_smooth(gps, i, sfac);
+ BKE_gpencil_stroke_smooth_point(gps, i, sfac);
BKE_gpencil_stroke_smooth_strength(gps, i, sfac);
}
}
@@ -1288,11 +1289,23 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
/* Join with existing strokes. */
if (ts->gpencil_flags & GP_TOOL_FLAG_AUTOMERGE_STROKE) {
if (gps->prev != NULL) {
+ BKE_gpencil_stroke_boundingbox_calc(gps);
+ float diff_mat[4][4], ctrl1[2], ctrl2[2];
+ BKE_gpencil_layer_transform_matrix_get(depsgraph, p->ob, gpl, diff_mat);
+ ED_gpencil_stroke_extremes_to2d(&p->gsc, diff_mat, gps, ctrl1, ctrl2);
+
int pt_index = 0;
bool doit = true;
while (doit && gps) {
- bGPDstroke *gps_target = ED_gpencil_stroke_nearest_to_ends(
- p->C, &p->gsc, gpl, gpl->actframe, gps, GPENCIL_MINIMUM_JOIN_DIST, &pt_index);
+ bGPDstroke *gps_target = ED_gpencil_stroke_nearest_to_ends(p->C,
+ &p->gsc,
+ gpl,
+ gpl->actframe,
+ gps,
+ ctrl1,
+ ctrl2,
+ GPENCIL_MINIMUM_JOIN_DIST,
+ &pt_index);
if (gps_target != NULL) {
gps = ED_gpencil_stroke_join_and_trim(p->gpd, p->gpf, gps, gps_target, pt_index);
}
diff --git a/source/blender/editors/gpencil/gpencil_primitive.c b/source/blender/editors/gpencil/gpencil_primitive.c
index 5ecb6d9a212..f8cfc130e35 100644
--- a/source/blender/editors/gpencil/gpencil_primitive.c
+++ b/source/blender/editors/gpencil/gpencil_primitive.c
@@ -1382,11 +1382,23 @@ static void gpencil_primitive_interaction_end(bContext *C,
if (ts->gpencil_flags & GP_TOOL_FLAG_AUTOMERGE_STROKE) {
if (ELEM(tgpi->type, GP_STROKE_ARC, GP_STROKE_LINE, GP_STROKE_CURVE, GP_STROKE_POLYLINE)) {
if (gps->prev != NULL) {
+ BKE_gpencil_stroke_boundingbox_calc(gps);
+ float diff_mat[4][4], ctrl1[2], ctrl2[2];
+ BKE_gpencil_layer_transform_matrix_get(tgpi->depsgraph, tgpi->ob, tgpi->gpl, diff_mat);
+ ED_gpencil_stroke_extremes_to2d(&tgpi->gsc, diff_mat, gps, ctrl1, ctrl2);
+
int pt_index = 0;
bool doit = true;
while (doit && gps) {
- bGPDstroke *gps_target = ED_gpencil_stroke_nearest_to_ends(
- C, &tgpi->gsc, tgpi->gpl, gpf, gps, GPENCIL_MINIMUM_JOIN_DIST, &pt_index);
+ bGPDstroke *gps_target = ED_gpencil_stroke_nearest_to_ends(C,
+ &tgpi->gsc,
+ tgpi->gpl,
+ gpf,
+ gps,
+ ctrl1,
+ ctrl2,
+ GPENCIL_MINIMUM_JOIN_DIST,
+ &pt_index);
if (gps_target != NULL) {
gps = ED_gpencil_stroke_join_and_trim(tgpi->gpd, gpf, gps, gps_target, pt_index);
}
diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
index 869254cef3b..e9a6beab798 100644
--- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c
+++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c
@@ -337,7 +337,7 @@ static bool gpencil_brush_smooth_apply(tGP_BrushEditData *gso,
/* perform smoothing */
if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_POSITION) {
- BKE_gpencil_stroke_smooth(gps, pt_index, inf);
+ BKE_gpencil_stroke_smooth_point(gps, pt_index, inf);
}
if (gso->brush->gpencil_settings->sculpt_mode_flag & GP_SCULPT_FLAGMODE_APPLY_STRENGTH) {
BKE_gpencil_stroke_smooth_strength(gps, pt_index, inf);
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 5cc52303cd6..72d10d840fa 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -3213,11 +3213,28 @@ bool ED_gpencil_stroke_point_is_inside(const bGPDstroke *gps,
return hit;
}
+/* Get extremes of stroke in 2D using current view. */
+void ED_gpencil_stroke_extremes_to2d(const GP_SpaceConversion *gsc,
+ const float diff_mat[4][4],
+ bGPDstroke *gps,
+ float r_ctrl1[2],
+ float r_ctrl2[2])
+{
+ bGPDspoint pt_dummy_ps;
+
+ gpencil_point_to_parent_space(&gps->points[0], diff_mat, &pt_dummy_ps);
+ gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &r_ctrl1[0], &r_ctrl1[1]);
+ gpencil_point_to_parent_space(&gps->points[gps->totpoints - 1], diff_mat, &pt_dummy_ps);
+ gpencil_point_to_xy_fl(gsc, gps, &pt_dummy_ps, &r_ctrl2[0], &r_ctrl2[1]);
+}
+
bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
const GP_SpaceConversion *gsc,
bGPDlayer *gpl,
bGPDframe *gpf,
bGPDstroke *gps,
+ const float ctrl1[2],
+ const float ctrl2[2],
const float radius,
int *r_index)
{
@@ -3267,6 +3284,14 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
gpencil_point_to_parent_space(pt, diff_mat, &pt_parent);
gpencil_point_to_xy_fl(gsc, gps, &pt_parent, &pt2d_target_end[0], &pt2d_target_end[1]);
+ /* If the distance to the original stroke extremes is too big, the stroke must not be joined. */
+ if ((len_squared_v2v2(ctrl1, pt2d_target_start) > radius_sqr) &&
+ (len_squared_v2v2(ctrl1, pt2d_target_end) > radius_sqr) &&
+ (len_squared_v2v2(ctrl2, pt2d_target_start) > radius_sqr) &&
+ (len_squared_v2v2(ctrl2, pt2d_target_end) > radius_sqr)) {
+ continue;
+ }
+
if ((len_squared_v2v2(pt2d_start, pt2d_target_start) > radius_sqr) &&
(len_squared_v2v2(pt2d_start, pt2d_target_end) > radius_sqr) &&
(len_squared_v2v2(pt2d_end, pt2d_target_start) > radius_sqr) &&
@@ -3350,7 +3375,7 @@ bGPDstroke *ED_gpencil_stroke_join_and_trim(
/* Join both strokes. */
int totpoint = gps_final->totpoints;
- BKE_gpencil_stroke_join(gps_final, gps, false, true);
+ BKE_gpencil_stroke_join(gps_final, gps, false, true, true);
/* Select the join points and merge if the distance is very small. */
pt = &gps_final->points[totpoint - 1];
diff --git a/source/blender/editors/include/ED_gpencil.h b/source/blender/editors/include/ED_gpencil.h
index 8a8d91a570c..c760b661373 100644
--- a/source/blender/editors/include/ED_gpencil.h
+++ b/source/blender/editors/include/ED_gpencil.h
@@ -391,8 +391,15 @@ struct bGPDstroke *ED_gpencil_stroke_nearest_to_ends(struct bContext *C,
struct bGPDlayer *gpl,
struct bGPDframe *gpf,
struct bGPDstroke *gps,
+ const float ctrl1[2],
+ const float ctrl2[2],
const float radius,
int *r_index);
+void ED_gpencil_stroke_extremes_to2d(const struct GP_SpaceConversion *gsc,
+ const float diff_mat[4][4],
+ struct bGPDstroke *gps,
+ float r_ctrl1[2],
+ float r_ctrl2[2]);
struct bGPDstroke *ED_gpencil_stroke_join_and_trim(struct bGPdata *gpd,
struct bGPDframe *gpf,
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
index 4142a1c02dc..b00db1ba2d2 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c
@@ -132,7 +132,7 @@ static void deformStroke(GpencilModifierData *md,
const float val = mmd->factor * weight;
/* perform smoothing */
if (mmd->flag & GP_SMOOTH_MOD_LOCATION) {
- BKE_gpencil_stroke_smooth(gps, i, val);
+ BKE_gpencil_stroke_smooth_point(gps, i, val);
}
if (mmd->flag & GP_SMOOTH_MOD_STRENGTH) {
BKE_gpencil_stroke_smooth_strength(gps, i, val);