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:
authorYimingWu <xp8110@outlook.com>2021-09-26 14:43:12 +0300
committerYimingWu <xp8110@outlook.com>2021-09-26 14:43:12 +0300
commit80f7bc6d8e7e7a5e543df5418313c04df5140c43 (patch)
tree5dc395993dd4761e3bf9282e5e3a0fadb5ae2806 /source/blender/gpencil_modifiers
parent505422220d6e172fddc8a40fabee47f5d35e0c7d (diff)
LineArt: Smooth tolerance value for chaining.
smooth out jaggy lines with a given threshold. For each point in a stroke, the ones with in a given distance of its previous segment will be removed, thus "zig-zag" artefacts can be cleaned up. Reviewed By: Antonio Vazquez (antoniov) Differential Revision: https://developer.blender.org/D12050
Diffstat (limited to 'source/blender/gpencil_modifiers')
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c1
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h3
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c28
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c10
4 files changed, 41 insertions, 1 deletions
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index 01488a8b2de..c5ccf1d8229 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -587,6 +587,7 @@ static void chaining_panel_draw(const bContext *UNUSED(C), Panel *panel)
is_geom ? IFACE_("Geometry Threshold") : NULL,
ICON_NONE);
+ uiItemR(layout, ptr, "smooth_tolerance", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
uiItemR(layout, ptr, "split_angle", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
}
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 134d9707ade..c00f34185dd 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -317,6 +317,8 @@ typedef struct LineartRenderBuffer {
float chaining_image_threshold;
float angle_splitting_threshold;
+ float chain_smooth_tolerance;
+
/* FIXME(Yiming): Temporary solution for speeding up calculation by not including lines that
* are not in the selected source. This will not be needed after we have a proper scene-wise
* cache running because multiple modifiers can then select results from that without further
@@ -592,6 +594,7 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb);
void MOD_lineart_chain_connect(LineartRenderBuffer *rb);
void MOD_lineart_chain_discard_short(LineartRenderBuffer *rb, const float threshold);
void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshold_rad);
+void MOD_lineart_smooth_chains(LineartRenderBuffer *rb, float tolerance);
int MOD_lineart_chain_count(const LineartEdgeChain *ec);
void MOD_lineart_chain_clear_picked_flag(LineartCache *lc);
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
index d86253e7fe0..8935bdd1870 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
@@ -924,6 +924,34 @@ void MOD_lineart_chain_clear_picked_flag(LineartCache *lc)
}
}
+void MOD_lineart_smooth_chains(LineartRenderBuffer *rb, float tolerance)
+{
+ LISTBASE_FOREACH (LineartEdgeChain *, rlc, &rb->chains) {
+ LineartEdgeChainItem *next_eci;
+ for (LineartEdgeChainItem *eci = rlc->chain.first; eci; eci = next_eci) {
+ next_eci = eci->next;
+ LineartEdgeChainItem *eci2, *eci3, *eci4;
+
+ /* Not enough point to do simplify. */
+ if ((!(eci2 = eci->next)) || (!(eci3 = eci2->next))) {
+ continue;
+ }
+
+ /* No need to care for different line types/occlusion and so on, because at this stage they
+ * are all the same within a chain. */
+
+ /* If p3 is within the p1-p2 segment of a width of "tolerance" */
+ if (dist_to_line_segment_v2(eci3->pos, eci->pos, eci2->pos) < tolerance) {
+ /* And if p4 is on the extension of p1-p2 , we remove p3. */
+ if ((eci4 = eci3->next) && (dist_to_line_v2(eci4->pos, eci->pos, eci2->pos) < tolerance)) {
+ BLI_remlink(&rlc->chain, eci3);
+ next_eci = eci;
+ }
+ }
+ }
+ }
+}
+
/**
* This should always be the last stage!, see the end of
* #MOD_lineart_chain_split_for_fixed_occlusion().
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 725cc0741f0..5b878a4326f 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -3056,8 +3056,9 @@ static LineartRenderBuffer *lineart_create_render_buffer(Scene *scene,
rb->shift_y /= (1 + rb->overscan);
rb->crease_threshold = cos(M_PI - lmd->crease_threshold);
- rb->angle_splitting_threshold = lmd->angle_splitting_threshold;
rb->chaining_image_threshold = lmd->chaining_image_threshold;
+ rb->angle_splitting_threshold = lmd->angle_splitting_threshold;
+ rb->chain_smooth_tolerance = lmd->chain_smooth_tolerance;
rb->fuzzy_intersections = (lmd->calculation_flags & LRT_INTERSECTION_AS_CONTOUR) != 0;
rb->fuzzy_everything = (lmd->calculation_flags & LRT_EVERYTHING_AS_CONTOUR) != 0;
@@ -4172,6 +4173,13 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
/* This configuration ensures there won't be accidental lost of short unchained segments. */
MOD_lineart_chain_discard_short(rb, MIN2(*t_image, 0.001f) - FLT_EPSILON);
+ if (rb->chain_smooth_tolerance > FLT_EPSILON) {
+ /* Keeping UI range of 0-1 for ease of read while scaling down the actual value for best
+ * effective range in image-space (Coordinate only goes from -1 to 1). This value is somewhat
+ * arbitrary, but works best for the moment. */
+ MOD_lineart_smooth_chains(rb, rb->chain_smooth_tolerance / 50);
+ }
+
if (rb->angle_splitting_threshold > FLT_EPSILON) {
MOD_lineart_chain_split_angle(rb, rb->angle_splitting_threshold);
}