[Bf-blender-cvs] [62c2b377fd2] temp-lineart-contained: LineArt: Better smoothing algo.

YimingWu noreply at git.blender.org
Sat Sep 11 11:14:01 CEST 2021


Commit: 62c2b377fd26e255c340a89695ae6c9a4c63fc7a
Author: YimingWu
Date:   Sat Sep 11 17:13:45 2021 +0800
Branches: temp-lineart-contained
https://developer.blender.org/rB62c2b377fd26e255c340a89695ae6c9a4c63fc7a

LineArt: Better smoothing algo.

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

M	release/datafiles/locale
M	release/scripts/addons
M	release/scripts/addons_contrib
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
M	source/tools

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

diff --git a/release/datafiles/locale b/release/datafiles/locale
index 8a05b618f03..4833954c0ac 160000
--- a/release/datafiles/locale
+++ b/release/datafiles/locale
@@ -1 +1 @@
-Subproject commit 8a05b618f031582c006c6f62b9e60619ab3eef8b
+Subproject commit 4833954c0ac85cc407e1d5a153aa11b1d1823ec0
diff --git a/release/scripts/addons b/release/scripts/addons
index 67f1fbca148..f86f25e6221 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 67f1fbca1482d9d9362a4001332e785c3fd5d230
+Subproject commit f86f25e62217264495d05f116ccb09d575fe9841
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
index ef6ef414d22..5a82baad9f9 160000
--- a/release/scripts/addons_contrib
+++ b/release/scripts/addons_contrib
@@ -1 +1 @@
-Subproject commit ef6ef414d22c2578fad99327743b925ab640a99c
+Subproject commit 5a82baad9f986722104280e8354a4427d8e9eab1
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 6f01e3a2fa8..a5860698cba 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -174,6 +174,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 e798477d70b..e9afc88813d 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
@@ -582,9 +582,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;
@@ -609,6 +614,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;
@@ -699,6 +705,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)
@@ -747,7 +754,10 @@ 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) {
+    /* If the vertex is not from the same contour loop, then we tighten up the range, this way we
+     * could chain small loops better and later smooth out. */
+    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) {
@@ -771,6 +781,7 @@ static LineartChainRegisterEntry *lineart_chain_get_closest_cre(LineartRenderBuf
                                                        occlusion, \
                                                        material_mask_bits, \
                                                        isec_mask, \
+                                                       loop_id, \
                                                        dist, \
                                                        &adjacent_new_len, \
                                                        ba); \
@@ -805,7 +816,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};
 
@@ -824,6 +835,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;
@@ -837,10 +849,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;
@@ -932,27 +962,50 @@ void MOD_lineart_chain_clear_picked_flag(LineartCache *lc)
 void MOD_lineart_smooth_chains(LineartRenderBuffer *rb, float tolerance)
 {
   LISTBASE_FOREACH (LineartEdgeChain *, ec, &rb->chains) {
-    LineartEdgeChainItem *next_eci;
-    for (LineartEdgeChainItem *eci = ec->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;
-      }
+    for (int times = 0; times < 2; times++) {
+      for (LineartEdgeChainItem *eci = ec->chain.first, *next_eci = eci->next; eci;
+           eci = next_eci) {
+        LineartEdgeChainItem *eci2, *eci3, *eci4;
 
-      /* No need to care for different line types/occlusion and so on, because at this stage they
-       * are all the same within a chain. */
+        /* Not enough point to do simplify. */
+        if ((!(eci2 = eci->next)) || (!(eci3 = eci2->next))) {
+          next_eci = eci->next;
+          continue;
+        }
 
-      /* 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(&ec->chain, eci3);
-          next_eci = eci;
+        /* 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) {
+          float vec2[2], vec3[2], v2n[2], ratio, len2;
+          sub_v2_v2v2(vec2, eci2->pos, eci->pos);
+          sub_v2_v2v2(vec3, eci3->pos, eci->pos);
+          normalize_v2_v2(v2n, vec2);
+          ratio = dot_v2v2(v2n, vec3);
+          len2 = len_v2(vec2);
+          /* Don't remove a feature when the sharp turn stretches far behind. */
+          if (ratio < len2 && ratio > -len2 * 10) {
+            /* 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(&ec->chain, eci3);
+              next_eci = eci;
+              continue;
+            }
+            if (!eci4) {
+              /* See if the last segment's direction is reversed, if so remove that. */
+              if (len_v2(vec2) > len_v2(vec3)) {
+                BLI_remlink(&ec->chain, eci3);
+              }
+              next_eci = NULL;
+              continue;
+            }
+          }
         }
+        next_eci = eci->next;
       }
+      BLI_listbase_revers

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list