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:
authorAntonio Vazquez <blendergit@gmail.com>2021-09-03 16:24:01 +0300
committerAntonio Vazquez <blendergit@gmail.com>2021-09-03 16:24:13 +0300
commitae334532cffb2dd9074454b9a7ba095430f18735 (patch)
treea417085b903fb1849b14a70946225a08a479f786 /source/blender/blenkernel
parentf9ccd26b037d43f2490d1f0263e45e775d30473d (diff)
GPencil: Smooth thickness when joining strokes
When joining two strokes in paint mode using the auto merge option, the join was very hard if the thickness was too different. This patch adds a smooth to the join in order to get better transition. Also fixed the problem to join existing strokes very far from actual stroke. Some cleanup and rename of old code is included in order to make code more readable. Reviewed By: pepeland Differential Revision: https://developer.blender.org/D12362
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_gpencil_geom.h5
-rw-r--r--source/blender/blenkernel/intern/gpencil_geom.cc40
2 files changed, 41 insertions, 4 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). */