[Bf-blender-cvs] [66fecfcda6f] blender-v3.3-release: LineArt: Fix (unreported) wrong index in weight transfer

YimingWu noreply at git.blender.org
Wed Aug 31 04:02:22 CEST 2022


Commit: 66fecfcda6f5e0dacf3d86091e08292e8624c895
Author: YimingWu
Date:   Thu Aug 18 20:46:04 2022 +0800
Branches: blender-v3.3-release
https://developer.blender.org/rB66fecfcda6f5e0dacf3d86091e08292e8624c895

LineArt: Fix (unreported) wrong index in weight transfer

Line art now uses global index for vertices but needs to have
local index in order to do correct weight transfer.

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

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/gpencil_modifiers/intern/lineart/lineart_intern.h

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

diff --git a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
index 8d34fb2ffb2..895ffcc7818 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/MOD_lineart.h
@@ -84,6 +84,7 @@ typedef struct LineartElementLinkNode {
 
   /* For edge element link nodes, used for shadow edge matching. */
   int obindex;
+  int global_index_offset;
 
   /** Per object value, always set, if not enabled by #ObjectLineArt, then it's set to global. */
   float crease_threshold;
@@ -205,6 +206,10 @@ typedef struct LineartEdgeChain {
   uint8_t intersection_mask;
   uint32_t shadow_mask_bits;
 
+  /* We need local index for correct weight transfer, line art index is global, thus
+   * local_index=lineart_index-index_offset. */
+  uint32_t index_offset;
+
   struct Object *object_ref;
   struct Object *silhouette_backdrop;
 } LineartEdgeChain;
@@ -864,6 +869,7 @@ void MOD_lineart_chain_find_silhouette_backdrop_objects(LineartData *ld);
 
 int MOD_lineart_chain_count(const LineartEdgeChain *ec);
 void MOD_lineart_chain_clear_picked_flag(LineartCache *lc);
+void MOD_lineart_finalize_chains(LineartData *ld);
 
 /**
  * This is the entry point of all line art calculations.
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
index 7c8e0c5a6f5..f32141a31eb 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_chain.c
@@ -1051,6 +1051,38 @@ void MOD_lineart_chain_clear_picked_flag(LineartCache *lc)
   }
 }
 
+LineartElementLinkNode *lineart_find_matching_eln_obj(ListBase *elns, struct Object *obj)
+{
+  LISTBASE_FOREACH (LineartElementLinkNode *, eln, elns) {
+    if (eln->object_ref == obj) {
+      return eln;
+    }
+  }
+  return NULL;
+}
+
+void MOD_lineart_finalize_chains(LineartData *ld)
+{
+  LISTBASE_FOREACH (LineartEdgeChain *, ec, &ld->chains) {
+    if (ELEM(ec->type,
+             LRT_EDGE_FLAG_INTERSECTION,
+             LRT_EDGE_FLAG_PROJECTED_SHADOW,
+             LRT_EDGE_FLAG_LIGHT_CONTOUR)) {
+      continue;
+    }
+    LineartElementLinkNode *eln = lineart_find_matching_eln_obj(&ld->geom.vertex_buffer_pointers,
+                                                                ec->object_ref);
+    BLI_assert(eln != NULL);
+    if (LIKELY(eln)) {
+      LISTBASE_FOREACH (LineartEdgeChainItem *, eci, &ec->chain) {
+        if (eci->index > eln->global_index_offset) {
+          eci->index -= eln->global_index_offset;
+        }
+      }
+    }
+  }
+}
+
 void MOD_lineart_smooth_chains(LineartData *ld, float tolerance)
 {
   LISTBASE_FOREACH (LineartEdgeChain *, ec, &ld->chains) {
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
index 2bc59d318c7..d0b1efa183d 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c
@@ -2651,6 +2651,7 @@ void lineart_main_load_geometries(Depsgraph *depsgraph,
       }
       LineartVert *v = (LineartVert *)obi->v_eln->pointer;
       int v_count = obi->v_eln->element_count;
+      obi->v_eln->global_index_offset = global_i;
       for (int vi = 0; vi < v_count; vi++) {
         v[vi].index += global_i;
       }
@@ -5106,6 +5107,8 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
 
     /* At last, we need to clear flags so we don't confuse GPencil generation calls. */
     MOD_lineart_chain_clear_picked_flag(lc);
+
+    MOD_lineart_finalize_chains(ld);
   }
 
   lineart_mem_destroy(&lc->shadow_data_pool);
diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h
index 3668f1dc6d7..947586aaec4 100644
--- a/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h
+++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_intern.h
@@ -133,6 +133,7 @@ void lineart_main_transform_and_add_shadow(struct LineartData *ld,
                                            struct LineartElementLinkNode *eeln);
 
 LineartElementLinkNode *lineart_find_matching_eln(struct ListBase *shadow_elns, int obindex);
+LineartElementLinkNode *lineart_find_matching_eln_obj(struct ListBase *elns, struct Object *ob);
 LineartEdge *lineart_find_matching_edge(struct LineartElementLinkNode *shadow_eln,
                                         uint64_t edge_identifier);
 void lineart_register_shadow_cuts(struct LineartData *ld,



More information about the Bf-blender-cvs mailing list