[Bf-blender-cvs] [247abdbf414] master: LineArt: Cached calculation for modifiers in the same stack.

YimingWu noreply at git.blender.org
Wed Jun 16 16:40:51 CEST 2021


Commit: 247abdbf4148843daf469285a6a63ab9cd0aeef9
Author: YimingWu
Date:   Wed Jun 16 22:38:47 2021 +0800
Branches: master
https://developer.blender.org/rB247abdbf4148843daf469285a6a63ab9cd0aeef9

LineArt: Cached calculation for modifiers in the same stack.

This allows line art to run only once for each modifier stacks,
with an option to toggle a specific line art modifier should
use cache or re-do their own calculations.

Reviewed By: Sebastian Parborg (zeddb), Hans Goudey (HooglyBoogly)

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

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

M	source/blender/blenkernel/BKE_gpencil_modifier.h
M	source/blender/blenkernel/intern/gpencil_modifier.c
M	source/blender/gpencil_modifiers/MOD_gpencil_lineart.h
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/gpencil_modifiers/intern/lineart/lineart_ops.c
M	source/blender/makesdna/DNA_gpencil_modifier_types.h
M	source/blender/makesdna/DNA_gpencil_types.h
M	source/blender/makesrna/intern/rna_gpencil_modifier.c
M	source/tools

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

diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h
index c6406c8478c..8fbc2112c77 100644
--- a/source/blender/blenkernel/BKE_gpencil_modifier.h
+++ b/source/blender/blenkernel/BKE_gpencil_modifier.h
@@ -294,6 +294,22 @@ bool BKE_gpencil_has_geometry_modifiers(struct Object *ob);
 bool BKE_gpencil_has_time_modifiers(struct Object *ob);
 bool BKE_gpencil_has_transform_modifiers(struct Object *ob);
 
+/* Stores the maximum calculation range in the whole modifier stack for line art so the cache can
+ * cover everything that will be visible. */
+typedef struct GpencilLineartLimitInfo {
+  char min_level;
+  char max_level;
+  short edge_types;
+} GpencilLineartLimitInfo;
+
+GpencilLineartLimitInfo BKE_gpencil_get_lineart_modifier_limits(const struct Object *ob);
+
+void BKE_gpencil_set_lineart_modifier_limits(struct GpencilModifierData *md,
+                                             const struct GpencilLineartLimitInfo *info,
+                                             const bool is_first_lineart);
+bool BKE_gpencil_is_first_lineart_in_stack(const struct Object *ob,
+                                           const struct GpencilModifierData *md);
+
 void BKE_gpencil_lattice_init(struct Object *ob);
 void BKE_gpencil_lattice_clear(struct Object *ob);
 
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index 16386cac029..5ac85ad3aaf 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -55,6 +55,7 @@
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_query.h"
 
+#include "MOD_gpencil_lineart.h"
 #include "MOD_gpencil_modifiertypes.h"
 
 #include "BLO_read_write.h"
@@ -202,6 +203,62 @@ bool BKE_gpencil_has_transform_modifiers(Object *ob)
   return false;
 }
 
+GpencilLineartLimitInfo BKE_gpencil_get_lineart_modifier_limits(const Object *ob)
+{
+  GpencilLineartLimitInfo info = {0};
+  bool is_first = true;
+  LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
+    if (md->type == eGpencilModifierType_Lineart) {
+      LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
+      if (is_first || (lmd->flags & LRT_GPENCIL_USE_CACHE)) {
+        info.min_level = MIN2(info.min_level, lmd->level_start);
+        info.max_level = MAX2(info.max_level,
+                              (lmd->use_multiple_levels ? lmd->level_end : lmd->level_start));
+        info.edge_types |= lmd->edge_types;
+      }
+    }
+  }
+  return info;
+}
+
+void BKE_gpencil_set_lineart_modifier_limits(GpencilModifierData *md,
+                                             const GpencilLineartLimitInfo *info,
+                                             const bool is_first_lineart)
+{
+  BLI_assert(md->type == eGpencilModifierType_Lineart);
+  LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md;
+  if (is_first_lineart || lmd->flags & LRT_GPENCIL_USE_CACHE) {
+    lmd->level_start_override = info->min_level;
+    lmd->level_end_override = info->max_level;
+    lmd->edge_types_override = info->edge_types;
+  }
+  else {
+    lmd->level_start_override = lmd->level_start;
+    lmd->level_end_override = lmd->level_end;
+    lmd->edge_types_override = lmd->edge_types;
+  }
+}
+
+bool BKE_gpencil_is_first_lineart_in_stack(const Object *ob, const GpencilModifierData *md)
+{
+  if (md->type != eGpencilModifierType_Lineart) {
+    return false;
+  }
+  LISTBASE_FOREACH (GpencilModifierData *, gmd, &ob->greasepencil_modifiers) {
+    if (gmd->type == eGpencilModifierType_Lineart) {
+      if (gmd == md) {
+        return true;
+      }
+      else {
+        return false;
+      }
+    }
+  }
+  /* If we reach here it means md is not in ob's modifier stack. */
+  BLI_assert(false);
+  return false;
+}
+
 /* apply time modifiers */
 static int gpencil_time_modifier(
     Depsgraph *depsgraph, Scene *scene, Object *ob, bGPDlayer *gpl, int cfra, bool is_render)
@@ -771,6 +828,8 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
   BKE_gpencil_lattice_init(ob);
 
   const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
+  bool is_first_lineart = true;
+  GpencilLineartLimitInfo info = BKE_gpencil_get_lineart_modifier_limits(ob);
 
   LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
 
@@ -781,6 +840,11 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
         continue;
       }
 
+      if (md->type == eGpencilModifierType_Lineart) {
+        BKE_gpencil_set_lineart_modifier_limits(md, &info, is_first_lineart);
+        is_first_lineart = false;
+      }
+
       /* Apply geometry modifiers (add new geometry). */
       if (mti && mti->generateStrokes) {
         mti->generateStrokes(md, depsgraph, ob);
@@ -806,6 +870,8 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
 
   /* Clear any lattice data. */
   BKE_gpencil_lattice_clear(ob);
+
+  MOD_lineart_clear_cache(&gpd->runtime.lineart_cache);
 }
 
 void BKE_gpencil_modifier_blend_write(BlendWriter *writer, ListBase *modbase)
diff --git a/source/blender/gpencil_modifiers/MOD_gpencil_lineart.h b/source/blender/gpencil_modifiers/MOD_gpencil_lineart.h
index 685f0cb36cb..7d75ed5804e 100644
--- a/source/blender/gpencil_modifiers/MOD_gpencil_lineart.h
+++ b/source/blender/gpencil_modifiers/MOD_gpencil_lineart.h
@@ -29,3 +29,7 @@ void OBJECT_OT_lineart_clear(struct wmOperatorType *ot);
 void OBJECT_OT_lineart_clear_all(struct wmOperatorType *ot);
 
 void WM_operatortypes_lineart(void);
+
+struct LineartCache;
+
+void MOD_lineart_clear_cache(struct LineartCache **lc);
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
index 7d2efaebd01..f0aae7e4498 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillineart.c
@@ -38,6 +38,7 @@
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 
+#include "MOD_gpencil_lineart.h"
 #include "lineart/MOD_lineart.h"
 
 #include "BKE_collection.h"
@@ -88,7 +89,7 @@ static void generate_strokes_actual(
   }
 
   MOD_lineart_gpencil_generate(
-      lmd->render_buffer,
+      lmd->cache,
       depsgraph,
       ob,
       gpl,
@@ -156,11 +157,31 @@ static void generateStrokes(GpencilModifierData *md, Depsgraph *depsgraph, Objec
     return;
   }
 
-  MOD_lineart_compute_feature_lines(depsgraph, lmd);
+  LineartCache *local_lc = gpd->runtime.lineart_cache;
+  if (!gpd->runtime.lineart_cache) {
+    MOD_lineart_compute_feature_lines(depsgraph, lmd, &gpd->runtime.lineart_cache);
+    MOD_lineart_destroy_render_data(lmd);
+  }
+  else {
+    if (!(lmd->flags & LRT_GPENCIL_USE_CACHE)) {
+      MOD_lineart_compute_feature_lines(depsgraph, lmd, &local_lc);
+      MOD_lineart_destroy_render_data(lmd);
+    }
+    MOD_lineart_chain_clear_picked_flag(local_lc);
+    lmd->cache = local_lc;
+  }
 
   generate_strokes_actual(md, depsgraph, ob, gpl, gpf);
 
-  MOD_lineart_destroy_render_data(lmd);
+  if (!(lmd->flags & LRT_GPENCIL_USE_CACHE)) {
+    /* Clear local cache. */
+    if (local_lc != gpd->runtime.lineart_cache) {
+      MOD_lineart_clear_cache(&local_lc);
+    }
+    /* Restore the original cache pointer so the modifiers below still have access to the "global"
+     * cache. */
+    lmd->cache = gpd->runtime.lineart_cache;
+  }
 
   WM_main_add_notifier(NA_EDITED | NC_GPENCIL, NULL);
 }
@@ -182,11 +203,12 @@ static void bakeModifier(Main *UNUSED(bmain),
     return;
   }
 
-  MOD_lineart_compute_feature_lines(depsgraph, lmd);
+  if (!gpd->runtime.lineart_cache) {
+    MOD_lineart_compute_feature_lines(depsgraph, lmd, &gpd->runtime.lineart_cache);
+    MOD_lineart_destroy_render_data(lmd);
+  }
 
   generate_strokes_actual(md, depsgraph, ob, gpl, gpf);
-
-  MOD_lineart_destroy_render_data(lmd);
 }
 
 static bool isDisabled(GpencilModifierData *md, int UNUSED(userRenderParams))
@@ -258,10 +280,16 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
 
   const int source_type = RNA_enum_get(ptr, "source_type");
   const bool is_baked = RNA_boolean_get(ptr, "is_baked");
+  const bool use_cache = RNA_boolean_get(ptr, "use_cache");
+  const bool is_first = BKE_gpencil_is_first_lineart_in_stack(ob_ptr.data, ptr->data);
 
   uiLayoutSetPropSep(layout, true);
   uiLayoutSetEnabled(layout, !is_baked);
 
+  if (!BKE_gpencil_is_first_lineart_in_stack(ob_ptr.data, ptr->data)) {
+    uiItemR(layout, ptr, "use_cache", 0, NULL, ICON_NONE);
+  }
+
   uiItemR(layout, ptr, "source_type", 0, NULL, ICON_NONE);
 
   if (source_type == LRT_SOURCE_OBJECT) {
@@ -280,12 +308,17 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
   uiItemR(col, ptr, "use_material", 0, IFACE_("Material Borders"), ICON_NONE);
   uiItemR(col, ptr, "use_edge_mark", 0, IFACE_("Edge Marks"), ICON_NONE);
   uiItemR(col, ptr, "use_intersection", 0, IFACE_("Intersections"), ICON_NONE);
-  uiItemR(col, ptr, "use_crease", 0, IFACE_("Crease"), ICON_NONE);
-  uiLayout *sub = uiLayoutRow(col, true);
-  uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_crease"));
-  uiLayoutSetPropSep(sub, true);
 
-  uiItemR(sub, ptr, "crease_threshold", UI_ITEM_R_SLIDER, " ", ICON_NONE);
+  uiLayout *sub = uiLayoutRowWithHeading(col, false, IFACE_("Crease"));
+  uiItemR(sub, ptr, "use_crease", 0, "", ICON_NONE);
+  uiLayout *entry = uiLayoutRow(sub, false);
+  uiLayoutSetActive(entry, RNA_boolean_get(ptr, "use_crease") || is_first);
+  if (use_cache && !is_first) {
+    uiItemL(entry, IFACE_("Angle Cached"), ICON_INFO);
+  }
+  else {
+    uiItemR(entry, ptr, "crease_threshold", UI_ITEM_R_SLIDER, " ", ICON_NONE);
+  }
 
   uiItemPointerR(layout, ptr, "target_layer", &obj_data_ptr, "layers", NULL, ICON_GREASEPENCIL);
 
@@ -308,14 +341,35 @@ static void panel_draw(const bContext *UNUSED(C), Panel *panel)
                  NULL,
                  material_valid ? ICON_SHADING_TEXTURE : ICON_ERROR);
 
-  uiItemR(layout, ptr, "use_remove_doubles", 0, NULL, ICON_NONE);
-  uiItemR(layout, ptr, "use_edge_overlap", 0, IFACE_(

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list