[Bf-blender-cvs] [924e5042f6e] lineart-shadow: LineArt: Image boundary trimming.

YimingWu noreply at git.blender.org
Wed Aug 4 10:50:14 CEST 2021


Commit: 924e5042f6efeaf8219120054a155314192eef6b
Author: YimingWu
Date:   Wed Aug 4 16:15:42 2021 +0800
Branches: lineart-shadow
https://developer.blender.org/rB924e5042f6efeaf8219120054a155314192eef6b

LineArt: Image boundary trimming.

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

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 10b65e927c3..f7cacc19b26 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -438,8 +438,6 @@ static void options_panel_draw(const bContext *UNUSED(C), Panel *panel)
   uiLayoutSetPropSep(subrow, true);
   uiItemR(subrow, ptr, "source_camera", 0, "", ICON_OBJECT_DATA);
 
-  uiItemR(layout, ptr, "overscan", 0, NULL, ICON_NONE);
-
   uiItemR(layout, ptr, "use_remove_doubles", 0, NULL, ICON_NONE);
   uiItemR(layout, ptr, "use_edge_overlap", 0, IFACE_("Overlapping Edges As Contour"), ICON_NONE);
   uiItemR(layout, ptr, "use_object_instances", 0, NULL, ICON_NONE);
@@ -751,6 +749,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 1f2979ac30f..23a47ad7bf0 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -216,9 +216,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;
@@ -356,6 +356,7 @@ typedef struct LineartRenderBuffer {
   bool use_loose_edge_chain;
   bool use_geometry_space_chain;
   bool use_back_face_culling;
+  bool use_image_boundary_trimming;
 
   bool filter_face_mark;
   bool filter_face_mark_invert;
@@ -759,6 +760,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 ba6dd749fb0..7efb7c6dc2c 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_inside == false) {
+          /* Stroke goes out. */
+          new_eci = l

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list