[Bf-blender-cvs] [154fa8b8536] greasepencil-refactor: GPencil: Refactor: Move iterator to BKE
Clément Foucault
noreply at git.blender.org
Tue Jan 7 15:31:19 CET 2020
Commit: 154fa8b85367e39aaea2ce38a47f289a5e20b4b6
Author: Clément Foucault
Date: Mon Jan 6 11:31:10 2020 +0100
Branches: greasepencil-refactor
https://developer.blender.org/rB154fa8b85367e39aaea2ce38a47f289a5e20b4b6
GPencil: Refactor: Move iterator to BKE
===================================================================
M source/blender/blenkernel/BKE_gpencil.h
M source/blender/blenkernel/intern/gpencil.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
===================================================================
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 30cafdcc4f5..dce44a514da 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -302,6 +302,20 @@ bool BKE_gpencil_from_image(struct SpaceImage *sima,
const float size,
const bool mask);
+/* Iterator */
+/* frame & stroke are NULL if it is a layer callback. */
+typedef void (*gpIterCb)(struct bGPDlayer *layer,
+ struct bGPDframe *frame,
+ struct bGPDstroke *stroke,
+ void *thunk);
+
+void BKE_gpencil_visible_stroke_iter(struct Object *ob,
+ gpIterCb layer_cb,
+ gpIterCb stroke_cb,
+ void *thunk,
+ bool do_onion,
+ int cfra);
+
extern void (*BKE_gpencil_batch_cache_dirty_tag_cb)(struct bGPdata *gpd);
extern void (*BKE_gpencil_batch_cache_free_cb)(struct bGPdata *gpd);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index ab37efc1f61..823f75de3f3 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -3688,3 +3688,135 @@ bool BKE_gpencil_from_image(SpaceImage *sima, bGPDframe *gpf, const float size,
return done;
}
+
+/* -------------------------------------------------------------------- */
+/** \name Iterators
+ *
+ * Iterate over all visible stroke of all visible layers inside a gpObject.
+ * Also take into account onion skining.
+ *
+ * \{ */
+
+void BKE_gpencil_visible_stroke_iter(
+ Object *ob, gpIterCb layer_cb, gpIterCb stroke_cb, void *thunk, bool do_onion, int cfra)
+{
+ bGPdata *gpd = (bGPdata *)ob->data;
+ const bool is_multiedit = GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const bool is_onion = do_onion && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0);
+
+ /* Onion skinning. */
+ const bool onion_mode_abs = (gpd->onion_mode == GP_ONION_MODE_ABSOLUTE);
+ const bool onion_mode_sel = (gpd->onion_mode == GP_ONION_MODE_SELECTED);
+ const bool onion_loop = (gpd->onion_flag & GP_ONION_LOOP) != 0;
+ const short onion_keytype = gpd->onion_keytype;
+
+ int idx_eval = 0;
+
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ bGPDframe *act_gpf = gpl->actframe;
+ bGPDframe *sta_gpf = act_gpf;
+ bGPDframe *end_gpf = act_gpf ? act_gpf->next : NULL;
+
+ if (gpl->flag & GP_LAYER_HIDE) {
+ idx_eval++;
+ continue;
+ }
+
+ if (is_onion && (gpl->onion_flag & GP_LAYER_ONIONSKIN)) {
+ if (act_gpf) {
+ bGPDframe *last_gpf = gpl->frames.last;
+
+ int frame_len = 0;
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ gpf->runtime.frameid = frame_len++;
+ }
+
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ bool is_wrong_keytype = (onion_keytype > -1) && (gpf->key_type != onion_keytype);
+ bool is_in_range;
+ int delta = (onion_mode_abs) ? (gpf->framenum - cfra) :
+ (gpf->runtime.frameid - act_gpf->runtime.frameid);
+
+ if (onion_mode_sel) {
+ is_in_range = (gpf->flag & GP_FRAME_SELECT) != 0;
+ }
+ else {
+ is_in_range = (-delta <= gpd->gstep) && (delta <= gpd->gstep_next);
+
+ if (onion_loop && !is_in_range) {
+ /* We wrap the value using the last frame and 0 as reference. */
+ /* FIXME: This might not be good for animations not starting at 0. */
+ int shift = (onion_mode_abs) ? last_gpf->framenum : last_gpf->runtime.frameid;
+ delta += (delta < 0) ? (shift + 1) : -(shift + 1);
+ /* Test again with wrapped value. */
+ is_in_range = (-delta <= gpd->gstep) && (delta <= gpd->gstep_next);
+ }
+ }
+ /* Mask frames that have wrong keytype of are not in range. */
+ gpf->runtime.onion_id = (is_wrong_keytype || !is_in_range) ? INT_MAX : delta;
+ }
+ /* Active frame is always shown. */
+ act_gpf->runtime.onion_id = 0;
+ }
+
+ sta_gpf = gpl->frames.first;
+ end_gpf = NULL;
+ }
+ else if (is_multiedit) {
+ sta_gpf = end_gpf = NULL;
+ /* Check the whole range and tag the editable frames. */
+ LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
+ if (gpf == act_gpf || (gpf->flag & GP_FRAME_SELECT)) {
+ gpf->runtime.onion_id = 0;
+ if (sta_gpf == NULL) {
+ sta_gpf = gpf;
+ }
+ end_gpf = gpf->next;
+ }
+ else {
+ gpf->runtime.onion_id = INT_MAX;
+ }
+ }
+ }
+ else {
+ /* Bypass multiedit/onion skinning. */
+ end_gpf = sta_gpf = NULL;
+ }
+
+ if (sta_gpf == NULL && act_gpf == NULL) {
+ continue;
+ }
+
+ /* Draw multiedit/onion skinning first */
+ for (bGPDframe *gpf = sta_gpf; gpf && gpf != end_gpf; gpf = gpf->next) {
+ if (gpf->runtime.onion_id == INT_MAX || gpf == act_gpf) {
+ continue;
+ }
+
+ if (layer_cb) {
+ layer_cb(gpl, gpf, NULL, thunk);
+ }
+
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ stroke_cb(gpl, gpf, gps, thunk);
+ }
+ }
+ /* Draw Active frame on top. */
+ /* Use evaluated frame (with modifiers for active stroke)/ */
+ act_gpf = &ob->runtime.gpencil_evaluated_frames[idx_eval];
+ act_gpf->runtime.onion_id = 0;
+ if (act_gpf) {
+ if (layer_cb) {
+ layer_cb(gpl, act_gpf, NULL, thunk);
+ }
+
+ LISTBASE_FOREACH (bGPDstroke *, gps, &act_gpf->strokes) {
+ stroke_cb(gpl, act_gpf, gps, thunk);
+ }
+ }
+
+ idx_eval++;
+ }
+}
+
+/** \} */
\ No newline at end of file
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index a0544dc4827..84ae3f02137 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -191,7 +191,7 @@ static void gp_object_verts_count_cb(bGPDlayer *UNUSED(gpl),
iter->tri_len += gps->tot_triangles;
}
-static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache)
+static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache, int cfra)
{
bGPdata *gpd = (bGPdata *)ob->data;
@@ -213,7 +213,7 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache)
.vert_len = 1, /* Start at 1 for the gl_InstanceID trick to work (see vert shader). */
.tri_len = 0,
};
- gpencil_object_visible_stroke_iter(ob, NULL, gp_object_verts_count_cb, &iter, do_onion);
+ BKE_gpencil_visible_stroke_iter(ob, NULL, gp_object_verts_count_cb, &iter, do_onion, cfra);
/* Create VBO. */
GPUVertFormat *format = gpencil_stroke_format();
@@ -225,7 +225,7 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache)
GPU_indexbuf_init(&iter.ibo, GPU_PRIM_TRIS, iter.tri_len, iter.vert_len);
/* Fill buffers with data. */
- gpencil_object_visible_stroke_iter(ob, NULL, gpencil_stroke_iter_cb, &iter, do_onion);
+ BKE_gpencil_visible_stroke_iter(ob, NULL, gpencil_stroke_iter_cb, &iter, do_onion, cfra);
/* Finish the IBO. */
cache->ibo = GPU_indexbuf_build(&iter.ibo);
@@ -243,7 +243,7 @@ static void gpencil_batches_ensure(Object *ob, GpencilBatchCache *cache)
GPUBatch *GPENCIL_batch_cache_strokes(Object *ob, int cfra)
{
GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra);
- gpencil_batches_ensure(ob, cache);
+ gpencil_batches_ensure(ob, cache, cfra);
return cache->stroke_batch;
}
@@ -251,7 +251,7 @@ GPUBatch *GPENCIL_batch_cache_strokes(Object *ob, int cfra)
GPUBatch *GPENCIL_batch_cache_fills(Object *ob, int cfra)
{
GpencilBatchCache *cache = gpencil_batch_cache_get(ob, cfra);
- gpencil_batches_ensure(ob, cache);
+ gpencil_batches_ensure(ob, cache, cfra);
return cache->fill_batch;
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index da21aab6e8d..fe1ef42c120 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -50,145 +50,6 @@
#include "UI_resources.h"
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name Iterators
- *
- * Iterate over all visible stroke of all visible layers inside a gpObject.
- * Also take into account onion skining.
- *
- * \{ */
-
-void gpencil_object_visible_stroke_iter(
- Object *ob, gpIterCb layer_cb, gpIterCb stroke_cb, void *thunk, bool do_onion)
-{
- bGPdata *gpd = (bGPdata *)ob->data;
- const bool is_multiedit = GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- const bool is_onion = do_onion && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0);
-
- /* Onion skinning. */
- const bool onion_mode_abs = (gpd->onion_mode == GP_ONION_MODE_ABSOLUTE);
- const bool onion_mode_sel = (gpd->onion_mode == GP_ONION_MODE_SELECTED);
- const bool onion_loop = (gpd->onion_flag & GP_ONION_LOOP) != 0;
- const short onion_keytype = gpd->onion_keytype;
- int ctime = 0;
- if (onion_mode_abs) {
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ctime = DEG_get_ctime(draw_ctx->depsgraph);
- }
-
- int idx_eval = 0;
-
- LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
- bGPDframe *act_gpf = gpl->actframe;
- bGPDframe *sta_gpf = act_gpf;
- bGPDframe *end_gpf = act_gpf ? act_gpf->next : NULL;
-
- if (gpl->flag & GP_LAYER_HIDE) {
- idx_eval++;
- continue;
- }
-
- if (is_onion && (gpl->onion_flag & GP_LAYER_ONIONSKIN)) {
- if (act_gpf) {
- bGPDframe *last_gpf = gpl->frames.last;
-
- int frame_len = 0;
- LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
- gpf->runtime.frameid = frame_len++;
- }
-
- LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
-
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list