[Bf-blender-cvs] [ec831ce5df8] master: LineArt: Trimming edges right at the image border

YimingWu noreply at git.blender.org
Tue Oct 26 18:11:23 CEST 2021


Commit: ec831ce5df86cbdbed8030d8a056f8a9b4eb0273
Author: YimingWu
Date:   Wed Oct 27 00:10:25 2021 +0800
Branches: master
https://developer.blender.org/rBec831ce5df86cbdbed8030d8a056f8a9b4eb0273

LineArt: Trimming edges right at the image border

This option allows the edge to end right at the border
instead of extending beyond.
Useful when having multiple camera setup where you
want the border to be clean.
Also moved overscan option down inside "Composition" sub panel
so it makes more sense.

Reviewed By: Antonio Vazquez (antoniov)

Differential Revision: https://developer.blender.org/D12126

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

M	source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
M	source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
M	source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
M	source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
M	source/blender/makesdna/DNA_lineart_types.h
M	source/blender/makesrna/intern/rna_gpencil_modifier.c

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

diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index 4ce1a903269..c6bc5a9e53e 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -406,7 +406,7 @@ static void options_panel_draw(const bContext *UNUSED(C), Panel *panel)
   uiItemR(col, ptr, "use_object_instances", 0, NULL, ICON_NONE);
   uiItemR(col, ptr, "use_clip_plane_boundaries", 0, NULL, ICON_NONE);
   uiItemR(col, ptr, "use_crease_on_smooth", 0, IFACE_("Crease On Smooth"), ICON_NONE);
-  uiItemR(layout, ptr, "use_crease_on_sharp", 0, IFACE_("Crease On Sharp"), ICON_NONE);
+  uiItemR(col, ptr, "use_crease_on_sharp", 0, IFACE_("Crease On Sharp"), ICON_NONE);
 }
 
 static void style_panel_draw(const bContext *UNUSED(C), Panel *panel)
@@ -692,6 +692,9 @@ static void composition_panel_draw(const bContext *UNUSED(C), Panel *panel)
 
   uiLayoutSetPropSep(layout, true);
 
+  uiItemR(layout, ptr, "overscan", 0, NULL, ICON_NONE);
+  uiItemR(layout, ptr, "use_image_boundary_trimming", 0, NULL, ICON_NONE);
+
   if (show_in_front) {
     uiItemL(layout, IFACE_("Object is shown in front"), ICON_ERROR);
   }
diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 727de381fa4..d8926a63307 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -182,9 +182,9 @@ typedef struct LineartEdgeChain {
 
 typedef struct LineartEdgeChainItem {
   struct LineartEdgeChainItem *next, *prev;
-  /** Need z value for fading */
-  float pos[3];
-  /** For restoring position to 3d space */
+  /** Need z value for fading, w value for image frame clipping. */
+  float pos[4];
+  /** For restoring position to 3d space. */
   float gpos[3];
   float normal[3];
   unsigned char line_type;
@@ -299,6 +299,7 @@ typedef struct LineartRenderBuffer {
   bool use_loose_as_contour;
   bool use_loose_edge_chain;
   bool use_geometry_space_chain;
+  bool use_image_boundary_trimming;
 
   bool filter_face_mark;
   bool filter_face_mark_invert;
@@ -594,6 +595,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb);
 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_clip_at_border(LineartRenderBuffer *rb);
 void MOD_lineart_chain_split_angle(LineartRenderBuffer *rb, float angle_threshold_rad);
 void MOD_lineart_smooth_chains(LineartRenderBuffer *rb, float tolerance);
 void MOD_lineart_chain_offset_towards_camera(LineartRenderBuffer *rb,
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
index 8b7f53b8a36..85b801eece2 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
@@ -126,7 +126,7 @@ static LineartEdgeChainItem *lineart_chain_append_point(LineartRenderBuffer *rb,
 
   eci = lineart_mem_acquire(rb->chain_data_pool, sizeof(LineartEdgeChainItem));
 
-  copy_v2_v2(eci->pos, fbcoord);
+  copy_v4_v4(eci->pos, fbcoord);
   copy_v3_v3(eci->gpos, gpos);
   eci->index = index;
   copy_v3_v3(eci->normal, normal);
@@ -156,7 +156,7 @@ static LineartEdgeChainItem *lineart_chain_prepend_point(LineartRenderBuffer *rb
 
   eci = lineart_mem_acquire(rb->chain_data_pool, sizeof(LineartEdgeChainItem));
 
-  copy_v2_v2(eci->pos, fbcoord);
+  copy_v4_v4(eci->pos, fbcoord);
   copy_v3_v3(eci->gpos, gpos);
   eci->index = index;
   copy_v3_v3(eci->normal, normal);
@@ -177,15 +177,15 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
   int last_occlusion;
   unsigned char last_transparency;
   /* Used when converting from double. */
-  float use_fbcoord[2];
+  float use_fbcoord[4];
   float use_gpos[3];
 
 #define VERT_COORD_TO_FLOAT(a) \
-  copy_v2fl_v2db(use_fbcoord, (a)->fbcoord); \
+  copy_v4fl_v4db(use_fbcoord, (a)->fbcoord); \
   copy_v3fl_v3db(use_gpos, (a)->gloc);
 
 #define POS_TO_FLOAT(lpos, gpos) \
-  copy_v2fl_v2db(use_fbcoord, lpos); \
+  copy_v3fl_v3db(use_fbcoord, lpos); \
   copy_v3fl_v3db(use_gpos, gpos);
 
   LRT_ITER_ALL_LINES_BEGIN
@@ -262,6 +262,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
           double global_at = lfb[3] * es->at / (es->at * lfb[3] + (1 - es->at) * rfb[3]);
           interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, es->at);
           interp_v3_v3v3_db(gpos, new_e->v1->gloc, new_e->v2->gloc, global_at);
+          use_fbcoord[3] = interpf(new_e->v2->fbcoord[3], new_e->v1->fbcoord[3], global_at);
           POS_TO_FLOAT(lpos, gpos)
           lineart_chain_prepend_point(rb,
                                       ec,
@@ -287,6 +288,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
           double global_at = lfb[3] * es->at / (es->at * lfb[3] + (1 - es->at) * rfb[3]);
           interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, es->at);
           interp_v3_v3v3_db(gpos, new_e->v1->gloc, new_e->v2->gloc, global_at);
+          use_fbcoord[3] = interpf(new_e->v2->fbcoord[3], new_e->v1->fbcoord[3], global_at);
           POS_TO_FLOAT(lpos, gpos)
           lineart_chain_prepend_point(rb,
                                       ec,
@@ -340,6 +342,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
       double global_at = lfb[3] * es->at / (es->at * lfb[3] + (1 - es->at) * rfb[3]);
       interp_v3_v3v3_db(lpos, e->v1->fbcoord, e->v2->fbcoord, es->at);
       interp_v3_v3v3_db(gpos, e->v1->gloc, e->v2->gloc, global_at);
+      use_fbcoord[3] = interpf(e->v2->fbcoord[3], e->v1->fbcoord[3], global_at);
       POS_TO_FLOAT(lpos, gpos)
       lineart_chain_append_point(rb,
                                  ec,
@@ -403,6 +406,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
           double global_at = lfb[3] * es->at / (es->at * lfb[3] + (1 - es->at) * rfb[3]);
           interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, es->at);
           interp_v3_v3v3_db(gpos, new_e->v1->gloc, new_e->v2->gloc, global_at);
+          use_fbcoord[3] = interpf(new_e->v2->fbcoord[3], new_e->v1->fbcoord[3], global_at);
           last_occlusion = es->prev ? es->prev->occlusion : last_occlusion;
           last_transparency = es->prev ? es->prev->material_mask_bits : last_transparency;
           POS_TO_FLOAT(lpos, gpos)
@@ -430,6 +434,7 @@ void MOD_lineart_chain_feature_lines(LineartRenderBuffer *rb)
           double global_at = lfb[3] * es->at / (es->at * lfb[3] + (1 - es->at) * rfb[3]);
           interp_v3_v3v3_db(lpos, new_e->v1->fbcoord, new_e->v2->fbcoord, es->at);
           interp_v3_v3v3_db(gpos, new_e->v1->gloc, new_e->v2->gloc, global_at);
+          use_fbcoord[3] = interpf(new_e->v2->fbcoord[3], new_e->v1->fbcoord[3], global_at);
           POS_TO_FLOAT(lpos, gpos)
           lineart_chain_append_point(rb,
                                      ec,
@@ -952,6 +957,118 @@ void MOD_lineart_smooth_chains(LineartRenderBuffer *rb, float tolerance)
   }
 }
 
+static LineartEdgeChainItem *lineart_chain_create_crossing_point(LineartRenderBuffer *rb,
+                                                                 LineartEdgeChainItem *eci_inside,
+                                                                 LineartEdgeChainItem *eci_outside)
+{
+  float isec[2];
+  float LU[2] = {-1.0f, 1.0f}, LB[2] = {-1.0f, -1.0f}, RU[2] = {1.0f, 1.0f}, RB[2] = {1.0f, -1.0f};
+  bool found = false;
+  LineartEdgeChainItem *eci2 = eci_outside, *eci1 = eci_inside;
+  if (eci2->pos[0] < -1.0f) {
+    found = (isect_seg_seg_v2_point(eci1->pos, eci2->pos, LU, LB, isec) > 0);
+  }
+  if (!found && eci2->pos[0] > 1.0f) {
+    found = (isect_seg_seg_v2_point(eci1->pos, eci2->pos, RU, RB, isec) > 0);
+  }
+  if (!found && eci2->pos[1] < -1.0f) {
+    found = (isect_seg_seg_v2_point(eci1->pos, eci2->pos, LB, RB, isec) > 0);
+  }
+  if (!found && eci2->pos[1] > 1.0f) {
+    found = (isect_seg_seg_v2_point(eci1->pos, eci2->pos, LU, RU, isec) > 0);
+  }
+
+  if (UNLIKELY(!found)) {
+    return NULL;
+  }
+
+  float ratio = (fabs(eci2->pos[0] - eci1->pos[0]) > fabs(eci2->pos[1] - eci1->pos[1])) ?
+                    ratiof(eci1->pos[0], eci2->pos[0], isec[0]) :
+                    ratiof(eci1->pos[1], eci2->pos[1], isec[1]);
+  float gratio = eci1->pos[3] * ratio / (ratio * eci1->pos[3] + (1 - ratio) * eci2->pos[3]);
+
+  LineartEdgeChainItem *eci = lineart_mem_acquire(rb->chain_data_pool,
+                                                  sizeof(LineartEdgeChainItem));
+  memcpy(eci, eci1, sizeof(LineartEdgeChainItem));
+  interp_v3_v3v3(eci->gpos, eci1->gpos, eci2->gpos, gratio);
+  interp_v3_v3v3(eci->pos, eci1->pos, eci2->pos, ratio);
+  eci->pos[3] = interpf(eci2->pos[3], eci1->pos[3], gratio);
+  eci->next = eci->prev = NULL;
+  return eci;
+}
+
+#define LRT_ECI_INSIDE(eci) \
+  ((eci)->pos[0] >= -1.0f && (eci)->pos[0] <= 1.0f && (eci)->pos[1] >= -1.0f && \
+   (eci)->pos[1] <= 1.0f)
+
+void MOD_lineart_chain_clip_at_border(LineartRenderBuffer *rb)
+{
+  LineartEdgeChain *ec;
+  LineartEdgeChainItem *eci, *next_eci, *prev_eci, *new_eci;
+  bool is_inside, new_inside;
+  ListBase swap = {0};
+  swap.first = rb->chains.first;
+  swap.last = rb->chains.last;
+
+  rb->chains.last = rb->chains.first = NULL;
+  while ((ec = BLI_pophead(&swap)) != NULL) {
+    bool ec_added = false;
+    LineartEdgeChainItem *first_eci = (LineartEdgeChainItem *)ec->chain.first;
+    is_inside = LRT_ECI_INSIDE(first_eci) ? true : false;
+    if (!is_inside) {
+      ec->picked = true;
+    }
+    for (eci = first_eci->next; eci; eci = next_eci) {
+      next_eci = eci->next;
+      prev_eci = eci->prev;
+
+      /* We only need to do something if the edge crossed from outside to the inside or from inside
+       * to the outside. */
+      if ((new_inside = LRT_ECI_INSIDE(eci)) != is_inside) {
+        if (new_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list