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,\

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to