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>2022-05-18 10:23:43 +0300
committerYimingWu <xp8110@outlook.com>2022-05-18 10:34:34 +0300
commit2719869a2a98e8a0cb8d229f0efe7b9ec5138720 (patch)
tree2700dd989bbd32f823e00000e164e6cdc26e6e5e /source/blender/gpencil_modifiers/intern
parentc8edc458d13c0483907d0fe6f44f6e2887263b57 (diff)
LineArt: Prioritize connecting chains from the same contour loop
This change allows the chaining function to select edges from the same contour loop first, thus reduced rouge chain connections (connected different objects instead of chaining inside the same object first) and improved chaining quality. This patch also included the default value change for chain split threshold (Now don't split by default to make initial result as smooth as possible) Reviewed By: Sebastian Parborg (zeddb) Differential Revision: https://developer.blender.org/D14950
Diffstat (limited to 'source/blender/gpencil_modifiers/intern')
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h2
-rw-r--r--source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c45
2 files changed, 41 insertions, 6 deletions
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 9e44990cfca..8ce36bc0254 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -158,6 +158,8 @@ typedef struct LineartEdgeChain {
/** Chain now only contains one type of segments */
int type;
+ /** Will only connect chains that has the same loop id. */
+ int loop_id;
unsigned char material_mask_bits;
unsigned char intersection_mask;
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
index 28fd8ff01b9..0ee990e0f77 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
@@ -617,9 +617,14 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
rb->chains.last = rb->chains.first = NULL;
+ int loop_id = 0;
while ((ec = BLI_pophead(&swap)) != NULL) {
ec->next = ec->prev = NULL;
BLI_addtail(&rb->chains, ec);
+
+ ec->loop_id = loop_id;
+ loop_id++;
+
LineartEdgeChainItem *first_eci = (LineartEdgeChainItem *)ec->chain.first;
int fixed_occ = first_eci->occlusion;
unsigned char fixed_mask = first_eci->material_mask_bits;
@@ -651,6 +656,7 @@ void MOD_lineart_chain_split_for_fixed_occlusion(LineartRenderBuffer *rb)
new_ec = lineart_chain_create(rb);
new_ec->chain.first = eci;
new_ec->chain.last = ec->chain.last;
+ new_ec->loop_id = loop_id;
ec->chain.last = eci->prev;
((LineartEdgeChainItem *)ec->chain.last)->next = 0;
eci->prev = 0;
@@ -743,6 +749,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
int occlusion,
unsigned char material_mask_bits,
unsigned char isec_mask,
+ int loop_id,
float dist,
float *result_new_len,
LineartBoundingArea *caller_ba)
@@ -791,7 +798,11 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
float new_len = rb->use_geometry_space_chain ? len_v3v3(cre->eci->gpos, eci->gpos) :
len_v2v2(cre->eci->pos, eci->pos);
- if (new_len < dist) {
+ /* Even if the vertex is not from the same contour loop, we try to chain it still if the
+ * distance is small enough. This way we can better chain smaller loops and smooth them out
+ * later. */
+ if (((cre->ec->loop_id == loop_id) && (new_len < dist)) ||
+ ((cre->ec->loop_id != loop_id) && (new_len < dist / 10))) {
closest_cre = cre;
dist = new_len;
if (result_new_len) {
@@ -815,6 +826,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
occlusion, \
material_mask_bits, \
isec_mask, \
+ loop_id, \
dist, \
&adjacent_new_len, \
ba); \
@@ -844,7 +856,7 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
LineartChainRegisterEntry *closest_cre_l, *closest_cre_r, *closest_cre;
float dist = rb->chaining_image_threshold;
float dist_l, dist_r;
- int occlusion, reverse_main;
+ int occlusion, reverse_main, loop_id;
unsigned char material_mask_bits, isec_mask;
ListBase swap = {0};
@@ -863,6 +875,7 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
continue;
}
BLI_addtail(&rb->chains, ec);
+ loop_id = ec->loop_id;
if (ec->type == LRT_EDGE_FLAG_LOOSE && (!rb->use_loose_edge_chain)) {
continue;
@@ -876,10 +889,28 @@ void MOD_lineart_chain_connect(LineartRenderBuffer *rb)
eci_r = ec->chain.last;
while ((ba_l = lineart_bounding_area_get_end_point(rb, eci_l)) &&
(ba_r = lineart_bounding_area_get_end_point(rb, eci_r))) {
- closest_cre_l = lineart_chain_get_closest_cre(
- rb, ba_l, ec, eci_l, occlusion, material_mask_bits, isec_mask, dist, &dist_l, NULL);
- closest_cre_r = lineart_chain_get_closest_cre(
- rb, ba_r, ec, eci_r, occlusion, material_mask_bits, isec_mask, dist, &dist_r, NULL);
+ closest_cre_l = lineart_chain_get_closest_cre(rb,
+ ba_l,
+ ec,
+ eci_l,
+ occlusion,
+ material_mask_bits,
+ isec_mask,
+ loop_id,
+ dist,
+ &dist_l,
+ NULL);
+ closest_cre_r = lineart_chain_get_closest_cre(rb,
+ ba_r,
+ ec,
+ eci_r,
+ occlusion,
+ material_mask_bits,
+ isec_mask,
+ loop_id,
+ dist,
+ &dist_r,
+ NULL);
if (closest_cre_l && closest_cre_r) {
if (dist_l < dist_r) {
closest_cre = closest_cre_l;
@@ -1192,6 +1223,8 @@ void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshol
new_ec->object_ref = ec->object_ref;
new_ec->type = ec->type;
new_ec->level = ec->level;
+ new_ec->loop_id = ec->loop_id;
+ new_ec->intersection_mask = ec->intersection_mask;
new_ec->material_mask_bits = ec->material_mask_bits;
ec = new_ec;
}