[Bf-blender-cvs] [ee4ec69b280] master: Fix T66924 : Move GPencil Modifiers evaluation to Depsgraph

Antonio Vazquez noreply at git.blender.org
Fri Aug 23 23:14:04 CEST 2019


Commit: ee4ec69b28047629a1c153af356757a8fac5cee9
Author: Antonio Vazquez
Date:   Fri Aug 23 23:10:41 2019 +0200
Branches: master
https://developer.blender.org/rBee4ec69b28047629a1c153af356757a8fac5cee9

Fix T66924 : Move GPencil Modifiers evaluation to Depsgraph

Before, the evaluation of modifers were done in draw manager. The reason of the old design was grease pencil was designed before depsgraph was in place.

This commit moves this logic to depsgraph to follow general design and reduce Draw Manager complexity. Also, this is required in order to use modifiers in Edit modes.

Really, there is nothing really new in the creation of derived data, only the logic has been moved to depsgraph, but the main logic is the same. In order to get a reference to the original stroke and points, a pointer is added to Runtime data as part of the evaluated data. These pointers allow to know and use the original data.

As the modifiers now are evaluated in Depsgraph, the evaluated stroke is usable in Edit modes, so now it's possible to work with the evaluated version instead to use a "ghost" of the final image over the original geometry as work today.

Reviewed By: brecht

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

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

M	source/blender/blenkernel/BKE_gpencil.h
M	source/blender/blenkernel/BKE_gpencil_modifier.h
M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/blenkernel/intern/gpencil_modifier.c
M	source/blender/blenkernel/intern/object_update.c
M	source/blender/draw/engines/gpencil/gpencil_cache_utils.c
M	source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
M	source/blender/draw/engines/gpencil/gpencil_draw_utils.c
M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/editors/gpencil/gpencil_data.c
M	source/blender/makesdna/DNA_gpencil_types.h
M	source/blender/makesdna/DNA_object_types.h

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

diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 997f1fc82e1..d9c46cdfd10 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -24,6 +24,7 @@
  * \ingroup bke
  */
 
+struct Scene;
 struct ArrayGpencilModifierData;
 struct BoundBox;
 struct Brush;
@@ -49,6 +50,23 @@ struct bGPdata;
 struct MDeformVert;
 struct MDeformWeight;
 
+#define GPENCIL_SIMPLIFY(scene) ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE))
+#define GPENCIL_SIMPLIFY_ONPLAY(playing) \
+  (((playing == true) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY)) || \
+   ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY) == 0))
+#define GPENCIL_SIMPLIFY_FILL(scene, playing) \
+  ((GPENCIL_SIMPLIFY_ONPLAY(playing) && (GPENCIL_SIMPLIFY(scene)) && \
+    (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FILL)))
+#define GPENCIL_SIMPLIFY_MODIF(scene, playing) \
+  ((GPENCIL_SIMPLIFY_ONPLAY(playing) && (GPENCIL_SIMPLIFY(scene)) && \
+    (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_MODIFIER)))
+#define GPENCIL_SIMPLIFY_FX(scene, playing) \
+  ((GPENCIL_SIMPLIFY_ONPLAY(playing) && (GPENCIL_SIMPLIFY(scene)) && \
+    (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FX)))
+#define GPENCIL_SIMPLIFY_BLEND(scene, playing) \
+  ((GPENCIL_SIMPLIFY_ONPLAY(playing) && (GPENCIL_SIMPLIFY(scene)) && \
+    (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_BLEND)))
+
 /* ------------ Grease-Pencil API ------------------ */
 
 void BKE_gpencil_free_point_weights(struct MDeformVert *dvert);
@@ -57,7 +75,7 @@ void BKE_gpencil_free_stroke(struct bGPDstroke *gps);
 bool BKE_gpencil_free_strokes(struct bGPDframe *gpf);
 void BKE_gpencil_free_frames(struct bGPDlayer *gpl);
 void BKE_gpencil_free_layers(struct ListBase *list);
-bool BKE_gpencil_free_frame_runtime_data(struct bGPDframe *derived_gpf);
+bool BKE_gpencil_free_frame_runtime_data(struct bGPDframe *eval_gpf);
 void BKE_gpencil_free(struct bGPdata *gpd, bool free_all);
 
 void BKE_gpencil_batch_cache_dirty_tag(struct bGPdata *gpd);
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h
index 7f55ee2beb4..c2a4462dcbd 100644
--- a/source/blender/blenkernel/BKE_gpencil_modifier.h
+++ b/source/blender/blenkernel/BKE_gpencil_modifier.h
@@ -27,7 +27,6 @@
 struct BMEditMesh;
 struct DepsNodeHandle;
 struct Depsgraph;
-struct DerivedMesh;
 struct GpencilModifierData;
 struct ID;
 struct ListBase;
@@ -328,4 +327,8 @@ int BKE_gpencil_time_modifier(struct Depsgraph *depsgraph,
 void BKE_gpencil_lattice_init(struct Object *ob);
 void BKE_gpencil_lattice_clear(struct Object *ob);
 
+void BKE_gpencil_modifiers_calc(struct Depsgraph *depsgraph,
+                                struct Scene *scene,
+                                struct Object *ob);
+
 #endif /* __BKE_GPENCIL_MODIFIER_H__ */
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 0354aeaf0ca..2faeb0ea8c4 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -148,19 +148,19 @@ bool BKE_gpencil_free_strokes(bGPDframe *gpf)
 }
 
 /* Free strokes and colors belonging to a gp-frame */
-bool BKE_gpencil_free_frame_runtime_data(bGPDframe *derived_gpf)
+bool BKE_gpencil_free_frame_runtime_data(bGPDframe *eval_gpf)
 {
   bGPDstroke *gps_next;
-  if (!derived_gpf) {
+  if (!eval_gpf) {
     return false;
   }
 
   /* free strokes */
-  for (bGPDstroke *gps = derived_gpf->strokes.first; gps; gps = gps_next) {
+  for (bGPDstroke *gps = eval_gpf->strokes.first; gps; gps = gps_next) {
     gps_next = gps->next;
     BKE_gpencil_free_stroke(gps);
   }
-  BLI_listbase_clear(&derived_gpf->strokes);
+  BLI_listbase_clear(&eval_gpf->strokes);
 
   return true;
 }
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index f1ad801b951..354dddec11f 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -43,6 +43,7 @@
 #include "BKE_library_query.h"
 #include "BKE_gpencil.h"
 #include "BKE_lattice.h"
+#include "BKE_material.h"
 #include "BKE_gpencil_modifier.h"
 #include "BKE_object.h"
 
@@ -446,14 +447,6 @@ void BKE_gpencil_eval_geometry(Depsgraph *depsgraph, bGPdata *gpd)
     gpl->actframe = BKE_gpencil_layer_getframe(gpl, ctime, GP_GETFRAME_USE_PREV);
   }
 
-  /* TODO: Move "derived_gpf" logic here from DRW_gpencil_populate_datablock()?
-   * This would be better than inventing our own logic for this stuff...
-   */
-
-  /* TODO: Move the following code to "BKE_gpencil_eval_done()" (marked as an exit node)
-   * later when there's more happening here. For now, let's just keep this in here to avoid
-   * needing to have one more node slowing down evaluation...
-   */
   if (DEG_is_active(depsgraph)) {
     bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&gpd->id);
 
@@ -714,6 +707,8 @@ void BKE_gpencil_subdivide(bGPDstroke *gps, int level, int flag)
       pt_final->strength = pt->strength;
       pt_final->time = pt->time;
       pt_final->flag = pt->flag;
+      pt_final->runtime.pt_orig = pt->runtime.pt_orig;
+      pt_final->runtime.idx_orig = pt->runtime.idx_orig;
 
       if (gps->dvert != NULL) {
         dvert = &temp_dverts[i];
@@ -736,6 +731,7 @@ void BKE_gpencil_subdivide(bGPDstroke *gps, int level, int flag)
       pt_final->strength = interpf(pt->strength, next->strength, 0.5f);
       CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f);
       pt_final->time = interpf(pt->time, next->time, 0.5f);
+      pt_final->runtime.pt_orig = NULL;
 
       if (gps->dvert != NULL) {
         dvert = &temp_dverts[i];
@@ -781,3 +777,132 @@ void BKE_gpencil_subdivide(bGPDstroke *gps, int level, int flag)
     }
   }
 }
+
+/* Copy frame but do not assign new memory */
+static void gpencil_frame_copy_noalloc(Object *ob, bGPDframe *gpf, bGPDframe *eval_gpf)
+{
+  eval_gpf->prev = gpf->prev;
+  eval_gpf->next = gpf->next;
+  eval_gpf->framenum = gpf->framenum;
+  eval_gpf->flag = gpf->flag;
+  eval_gpf->key_type = gpf->key_type;
+  eval_gpf->runtime = gpf->runtime;
+  copy_m4_m4(eval_gpf->runtime.parent_obmat, gpf->runtime.parent_obmat);
+
+  /* copy strokes */
+  BLI_listbase_clear(&eval_gpf->strokes);
+  for (bGPDstroke *gps_src = gpf->strokes.first; gps_src; gps_src = gps_src->next) {
+    /* make copy of source stroke */
+    bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps_src);
+
+    /* copy color to temp fields to apply temporal changes in the stroke */
+    MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps_src->mat_nr + 1);
+    copy_v4_v4(gps_dst->runtime.tmp_stroke_rgba, gp_style->stroke_rgba);
+    copy_v4_v4(gps_dst->runtime.tmp_fill_rgba, gp_style->fill_rgba);
+
+    /* Save original pointers for using in edit and select operators. */
+    gps_dst->runtime.gps_orig = gps_src;
+    for (int i = 0; i < gps_src->totpoints; i++) {
+      bGPDspoint *pt_dst = &gps_dst->points[i];
+      pt_dst->runtime.pt_orig = &gps_src->points[i];
+      pt_dst->runtime.idx_orig = i;
+    }
+
+    BLI_addtail(&eval_gpf->strokes, gps_dst);
+  }
+}
+
+/* Ensure there is a evaluated frame */
+static void gpencil_evaluated_frame_ensure(
+    int idx, Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bGPDframe **eval_gpf)
+{
+  /* Create evaluated frames array data or expand. */
+  bGPDframe *evaluated_frames = ob->runtime.gpencil_evaluated_frames;
+  *eval_gpf = &evaluated_frames[idx];
+
+  /* If already exist a evaluated frame create a new one. */
+  if (*eval_gpf != NULL) {
+    /* first clear temp data */
+    BKE_gpencil_free_frame_runtime_data(*eval_gpf);
+  }
+  /* Copy data (do not assign new memory). */
+  gpencil_frame_copy_noalloc(ob, gpf, *eval_gpf);
+}
+
+/* Calculate gpencil modifiers */
+void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
+{
+  /* use original data to set reference pointers to original data */
+  Object *ob_orig = DEG_get_original_object(ob);
+  bGPdata *gpd = (bGPdata *)ob_orig->data;
+  const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+  const bool simplify_modif = GPENCIL_SIMPLIFY_MODIF(scene, false);
+  const bool is_render = (bool)(DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+  const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
+  int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
+  /* Create array of evaluated frames equal to number of layers. */
+  ob->runtime.gpencil_tot_layers = BLI_listbase_count(&gpd->layers);
+  CLAMP_MIN(ob->runtime.gpencil_tot_layers, 1);
+  if (ob->runtime.gpencil_evaluated_frames == NULL) {
+    ob->runtime.gpencil_evaluated_frames = MEM_callocN(
+        sizeof(struct bGPDframe) * ob->runtime.gpencil_tot_layers, __func__);
+  }
+  else {
+    ob->runtime.gpencil_evaluated_frames = MEM_recallocN(ob->runtime.gpencil_evaluated_frames,
+                                                         sizeof(struct bGPDframe) *
+                                                             ob->runtime.gpencil_tot_layers);
+  }
+
+  /* Init general modifiers data. */
+  if (ob->greasepencil_modifiers.first) {
+    BKE_gpencil_lattice_init(ob);
+  }
+
+  /* *****************************************************************
+   * Loop all layers, duplicate data and apply modifiers.
+   *
+   * ******************************************************************/
+  int idx = 0;
+  for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+    /* Remap frame (Time modifier) */
+    int remap_cfra = cfra_eval;
+    if ((time_remap) && (!simplify_modif)) {
+      remap_cfra = BKE_gpencil_time_modifier(depsgraph, scene, ob, gpl, cfra_eval, is_render);
+    }
+    bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
+
+    if (gpf == NULL) {
+      idx++;
+      continue;
+    }
+
+    /* Create a duplicate data set of stroke to modify. */
+    bGPDframe *eval_gpf = NULL;
+    gpencil_evaluated_frame_ensure(idx, ob, gpl, gpf, &eval_gpf);
+
+    /* Skip all if some disable flag is enabled. */
+    if ((ob->greasepencil_modifiers.first == NULL) || (is_multiedit) || (simp

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list