[Bf-blender-cvs] [2719869a2a9] master: LineArt: Prioritize connecting chains from the same contour loop

YimingWu noreply at git.blender.org
Wed May 18 09:35:26 CEST 2022


Commit: 2719869a2a98e8a0cb8d229f0efe7b9ec5138720
Author: YimingWu
Date:   Wed May 18 15:23:43 2022 +0800
Branches: master
https://developer.blender.org/rB2719869a2a98e8a0cb8d229f0efe7b9ec5138720

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

===================================================================

M	source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
M	source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
M	source/blender/makesdna/DNA_gpencil_modifier_defaults.h

===================================================================

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;
       }
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
index 750f97bb3c6..b35d6e750f4 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_defaults.h
@@ -303,7 +303,7 @@
     .crease_threshold = DEG2RAD(140.0f), \
     .calculation_flags = LRT_ALLOW_DUPLI_OBJECTS | LRT_ALLOW_CLIPPING_BOUNDARIES | \
                          LRT_USE_CREASE_ON_SHARP_EDGES | LRT_FILTER_FACE_MARK_KEEP_CONTOUR, \
-    .angle_splitting_threshold = DEG2RAD(60.0f), \
+    .angle_splitting_threshold = 0.0f, /* Do not split by default, this is for better chaining quality. */ \ 
     .chaining_image_threshold = 0.001f, \
     .chain_smooth_tolerance = 0.2f,\
     .stroke_depth_offset = 0.05,\



More information about the Bf-blender-cvs mailing list