diff options
-rw-r--r-- | source/blender/blenkernel/BKE_gpencil.h | 20 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_gpencil_modifier.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/gpencil.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/gpencil_modifier.c | 141 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object_update.c | 4 | ||||
-rw-r--r-- | source/blender/draw/engines/gpencil/gpencil_cache_utils.c | 31 | ||||
-rw-r--r-- | source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c | 66 | ||||
-rw-r--r-- | source/blender/draw/engines/gpencil/gpencil_draw_utils.c | 158 | ||||
-rw-r--r-- | source/blender/draw/engines/gpencil/gpencil_engine.c | 8 | ||||
-rw-r--r-- | source/blender/draw/engines/gpencil/gpencil_engine.h | 44 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_data.c | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_gpencil_types.h | 24 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 5 |
13 files changed, 298 insertions, 218 deletions
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) || (simplify_modif)) { + idx++; + continue; + } + + /* Apply geometry modifiers (create new geometry). */ + if (BKE_gpencil_has_geometry_modifiers(ob)) { + BKE_gpencil_geometry_modifiers(depsgraph, ob, gpl, eval_gpf, is_render); + } + + /* Loop all strokes and deform them. */ + for (bGPDstroke *gps = eval_gpf->strokes.first; gps; gps = gps->next) { + /* Apply modifiers that only deform geometry */ + BKE_gpencil_stroke_modifiers(depsgraph, ob, gpl, eval_gpf, gps, is_render); + } + + idx++; + } + + /* Clear any lattice data. */ + if (ob->greasepencil_modifiers.first) { + BKE_gpencil_lattice_clear(ob); + } +} diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c index 49f5aa35f93..3a330ea0d5a 100644 --- a/source/blender/blenkernel/intern/object_update.c +++ b/source/blender/blenkernel/intern/object_update.c @@ -43,6 +43,7 @@ #include "BKE_displist.h" #include "BKE_editmesh.h" #include "BKE_effect.h" +#include "BKE_gpencil_modifier.h" #include "BKE_image.h" #include "BKE_key.h" #include "BKE_layer.h" @@ -215,6 +216,9 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o case OB_LATTICE: BKE_lattice_modifiers_calc(depsgraph, scene, ob); break; + case OB_GPENCIL: + BKE_gpencil_modifiers_calc(depsgraph, scene, ob); + break; } /* particles */ diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c index 67ffe62f3c6..ea806c3da90 100644 --- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c @@ -274,11 +274,6 @@ static GpencilBatchCache *gpencil_batch_cache_init(Object *ob, int cfra) cache->cache_frame = cfra; - /* create array of derived frames equal to number of layers */ - cache->tot_layers = BLI_listbase_count(&gpd->layers); - CLAMP_MIN(cache->tot_layers, 1); - cache->derived_array = MEM_callocN(sizeof(struct bGPDframe) * cache->tot_layers, "Derived GPF"); - return cache; } @@ -301,18 +296,16 @@ static void gpencil_batch_cache_clear(GpencilBatchCache *cache) MEM_SAFE_FREE(cache->b_edit.batch); MEM_SAFE_FREE(cache->b_edlin.batch); + /* internal format data */ + MEM_SAFE_FREE(cache->b_stroke.format); + MEM_SAFE_FREE(cache->b_point.format); + MEM_SAFE_FREE(cache->b_fill.format); + MEM_SAFE_FREE(cache->b_edit.format); + MEM_SAFE_FREE(cache->b_edlin.format); + MEM_SAFE_FREE(cache->grp_cache); cache->grp_size = 0; cache->grp_used = 0; - - /* clear all frames derived data */ - for (int i = 0; i < cache->tot_layers; i++) { - bGPDframe *derived_gpf = &cache->derived_array[i]; - BKE_gpencil_free_frame_runtime_data(derived_gpf); - derived_gpf = NULL; - } - cache->tot_layers = 0; - MEM_SAFE_FREE(cache->derived_array); } /* get cache */ @@ -355,4 +348,14 @@ void DRW_gpencil_freecache(struct Object *ob) gpd->flag |= GP_DATA_CACHE_IS_DIRTY; } } + + /* clear all frames evaluated data */ + for (int i = 0; i < ob->runtime.gpencil_tot_layers; i++) { + bGPDframe *eval_gpf = &ob->runtime.gpencil_evaluated_frames[i]; + BKE_gpencil_free_frame_runtime_data(eval_gpf); + eval_gpf = NULL; + } + + ob->runtime.gpencil_tot_layers = 0; + MEM_SAFE_FREE(ob->runtime.gpencil_evaluated_frames); } 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 d5f8d062593..1ec02cac109 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c @@ -129,6 +129,13 @@ static void gpencil_vbo_ensure_size(GpencilBatchCacheElem *be, int totvertex) } } +static void gpencil_elem_format_ensure(GpencilBatchCacheElem *be) +{ + if (be->format == NULL) { + be->format = MEM_callocN(sizeof(GPUVertFormat), __func__); + } +} + /* create batch geometry data for points stroke shader */ void gpencil_get_point_geom(GpencilBatchCacheElem *be, bGPDstroke *gps, @@ -138,16 +145,17 @@ void gpencil_get_point_geom(GpencilBatchCacheElem *be, { int totvertex = gps->totpoints; if (be->vbo == NULL) { - be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + gpencil_elem_format_ensure(be); + be->pos_id = GPU_vertformat_attr_add(be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + be->color_id = GPU_vertformat_attr_add(be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); be->thickness_id = GPU_vertformat_attr_add( - &be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); be->uvdata_id = GPU_vertformat_attr_add( - &be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); be->prev_pos_id = GPU_vertformat_attr_add( - &be->format, "prev_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + be->format, "prev_pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->vbo = GPU_vertbuf_create_with_format(&be->format); + be->vbo = GPU_vertbuf_create_with_format(be->format); GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex); be->vbo_len = 0; } @@ -223,14 +231,15 @@ void gpencil_get_stroke_geom(struct GpencilBatchCacheElem *be, int totvertex = totpoints + cyclic_add + 2; if (be->vbo == NULL) { - be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + gpencil_elem_format_ensure(be); + be->pos_id = GPU_vertformat_attr_add(be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + be->color_id = GPU_vertformat_attr_add(be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); be->thickness_id = GPU_vertformat_attr_add( - &be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + be->format, "thickness", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); be->uvdata_id = GPU_vertformat_attr_add( - &be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + be->format, "uvdata", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - be->vbo = GPU_vertbuf_create_with_format(&be->format); + be->vbo = GPU_vertbuf_create_with_format(be->format); GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex); be->vbo_len = 0; } @@ -336,12 +345,13 @@ void gpencil_get_fill_geom(struct GpencilBatchCacheElem *be, int totvertex = gps->tot_triangles * 3; if (be->vbo == NULL) { - be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + gpencil_elem_format_ensure(be); + be->pos_id = GPU_vertformat_attr_add(be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + be->color_id = GPU_vertformat_attr_add(be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); be->uvdata_id = GPU_vertformat_attr_add( - &be->format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + be->format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - be->vbo = GPU_vertbuf_create_with_format(&be->format); + be->vbo = GPU_vertbuf_create_with_format(be->format); GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex); be->vbo_len = 0; } @@ -703,6 +713,7 @@ void gpencil_get_edit_geom(struct GpencilBatchCacheElem *be, Object *ob = draw_ctx->obact; bGPdata *gpd = ob->data; const bool is_weight_paint = (gpd) && (gpd->flag & GP_DATA_STROKE_WEIGHTMODE); + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); int vgindex = ob->actdef - 1; if (!BLI_findlink(&ob->defbase, vgindex)) { @@ -733,13 +744,17 @@ void gpencil_get_edit_geom(struct GpencilBatchCacheElem *be, UI_GetThemeColor3fv(TH_GP_VERTEX, unselectColor); unselectColor[3] = alpha; + float linecolor[4]; + copy_v4_v4(linecolor, gpd->line_color); + if (be->vbo == NULL) { - be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + gpencil_elem_format_ensure(be); + be->pos_id = GPU_vertformat_attr_add(be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + be->color_id = GPU_vertformat_attr_add(be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); be->thickness_id = GPU_vertformat_attr_add( - &be->format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + be->format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - be->vbo = GPU_vertbuf_create_with_format(&be->format); + be->vbo = GPU_vertbuf_create_with_format(be->format); GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex); be->vbo_len = 0; } @@ -776,6 +791,12 @@ void gpencil_get_edit_geom(struct GpencilBatchCacheElem *be, ARRAY_SET_ITEMS(fcolor, 1.0f, 0.0f, 0.0f, 1.0f); fsize = vsize + 1; } + else if ((!is_multiedit) && (pt->runtime.pt_orig == NULL)) { + ARRAY_SET_ITEMS(fcolor, linecolor[0], linecolor[1], linecolor[2], selectColor[3]); + mul_v4_fl(fcolor, 0.9f); + copy_v4_v4(fcolor, fcolor); + fsize = vsize * 0.8f; + } else if (pt->flag & GP_SPOINT_SELECT) { copy_v4_v4(fcolor, selectColor); fsize = vsize; @@ -819,10 +840,11 @@ void gpencil_get_edlin_geom(struct GpencilBatchCacheElem *be, copy_v4_v4(linecolor, gpd->line_color); if (be->vbo == NULL) { - be->pos_id = GPU_vertformat_attr_add(&be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - be->color_id = GPU_vertformat_attr_add(&be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); + gpencil_elem_format_ensure(be); + be->pos_id = GPU_vertformat_attr_add(be->format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + be->color_id = GPU_vertformat_attr_add(be->format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT); - be->vbo = GPU_vertbuf_create_with_format(&be->format); + be->vbo = GPU_vertbuf_create_with_format(be->format); GPU_vertbuf_data_alloc(be->vbo, be->tot_vertex); be->vbo_len = 0; } diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index 2892d0dbbaa..1dd1fa87612 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -61,10 +61,6 @@ #define TEXTURE 4 #define PATTERN 5 -#define GP_SET_SRC_GPS(src_gps) \ - if (src_gps) \ - src_gps = src_gps->next - /* Get number of vertex for using in GPU VBOs */ static void gpencil_calc_vertex(GPENCIL_StorageList *stl, tGPencilObjectCache *cache_ob, @@ -88,16 +84,17 @@ static void gpencil_calc_vertex(GPENCIL_StorageList *stl, const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && overlay && main_onion && gpencil_onion_active(gpd) && !playing; - const bool time_remap = BKE_gpencil_has_time_modifiers(ob); const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); cache_ob->tot_vertex = 0; cache_ob->tot_triangles = 0; + int eval_idx = 0; for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { bGPDframe *init_gpf = NULL; const bool is_onion = ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN)); if (gpl->flag & GP_LAYER_HIDE) { + eval_idx++; continue; } @@ -106,15 +103,7 @@ static void gpencil_calc_vertex(GPENCIL_StorageList *stl, init_gpf = gpl->frames.first; } else { - /* verify time modifiers */ - if ((time_remap) && (!stl->storage->simplify_modif)) { - int remap_cfra = BKE_gpencil_time_modifier( - draw_ctx->depsgraph, draw_ctx->scene, ob, gpl, cfra_eval, stl->storage->is_render); - init_gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV); - } - else { - init_gpf = gpl->actframe; - } + init_gpf = &ob->runtime.gpencil_evaluated_frames[eval_idx]; } if (init_gpf == NULL) { @@ -130,6 +119,7 @@ static void gpencil_calc_vertex(GPENCIL_StorageList *stl, break; } } + eval_idx++; } cache->b_fill.tot_vertex = cache_ob->tot_triangles * 3; @@ -1009,8 +999,7 @@ static void gpencil_draw_strokes(GpencilBatchCache *cache, Object *ob, bGPdata *gpd, bGPDlayer *gpl, - bGPDframe *src_gpf, - bGPDframe *derived_gpf, + bGPDframe *gpf, const float opacity, const float tintcolor[4], const bool custonion, @@ -1021,7 +1010,7 @@ static void gpencil_draw_strokes(GpencilBatchCache *cache, const DRWContextState *draw_ctx = DRW_context_state_get(); Scene *scene = draw_ctx->scene; View3D *v3d = draw_ctx->v3d; - bGPDstroke *gps, *src_gps; + bGPDstroke *gps; const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); const bool playing = stl->storage->is_playing; const bool is_render = (bool)stl->storage->is_render; @@ -1036,42 +1025,24 @@ static void gpencil_draw_strokes(GpencilBatchCache *cache, /* get parent matrix and save as static data */ if ((cache_ob != NULL) && (cache_ob->is_dup_ob)) { - copy_m4_m4(derived_gpf->runtime.parent_obmat, cache_ob->obmat); - } - else { - ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, derived_gpf->runtime.parent_obmat); - } - - /* apply geometry modifiers */ - if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) { - if (!stl->storage->simplify_modif) { - if (BKE_gpencil_has_geometry_modifiers(ob)) { - BKE_gpencil_geometry_modifiers(depsgraph, ob, gpl, derived_gpf, stl->storage->is_render); - } - } - } - - if (src_gpf) { - src_gps = src_gpf->strokes.first; + copy_m4_m4(gpf->runtime.parent_obmat, cache_ob->obmat); } else { - src_gps = NULL; + ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, gpf->runtime.parent_obmat); } - for (gps = derived_gpf->strokes.first; gps; gps = gps->next) { + for (gps = gpf->strokes.first; gps; gps = gps->next) { MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); /* check if stroke can be drawn */ if (gpencil_can_draw_stroke(gp_style, gps, false, is_mat_preview) == false) { - GP_SET_SRC_GPS(src_gps); continue; } /* be sure recalc all cache in source stroke to avoid recalculation when frame change * and improve fps */ - if (src_gps) { - gpencil_recalc_geometry_caches(ob, gpl, gp_style, src_gps); - } + gpencil_recalc_geometry_caches( + ob, gpl, gp_style, (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps); /* if the fill has any value, it's considered a fill and is not drawn if simplify fill is * enabled */ @@ -1080,32 +1051,19 @@ static void gpencil_draw_strokes(GpencilBatchCache *cache, if ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || (gp_style->fill_style > GP_STYLE_FILL_STYLE_SOLID) || (gpl->blend_mode != eGplBlendMode_Regular)) { - GP_SET_SRC_GPS(src_gps); + continue; } } - if ((gpl->actframe->framenum == derived_gpf->framenum) || (!is_multiedit) || - (overlay_multiedit)) { - /* copy color to temp fields to apply temporal changes in the stroke */ - copy_v4_v4(gps->runtime.tmp_stroke_rgba, gp_style->stroke_rgba); - copy_v4_v4(gps->runtime.tmp_fill_rgba, gp_style->fill_rgba); - - /* apply modifiers (only modify geometry, but not create ) */ - if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) { - if (!stl->storage->simplify_modif) { - BKE_gpencil_stroke_modifiers( - depsgraph, ob, gpl, derived_gpf, gps, stl->storage->is_render); - } - } - + if ((gpl->actframe->framenum == gpf->framenum) || (!is_multiedit) || (overlay_multiedit)) { /* hide any blend layer */ if ((!stl->storage->simplify_blend) || (gpl->blend_mode == eGplBlendMode_Regular)) { /* fill */ if ((gp_style->flag & GP_STYLE_FILL_SHOW) && (!stl->storage->simplify_fill) && ((gps->flag & GP_STROKE_NOFILL) == 0)) { gpencil_add_fill_vertexdata( - cache, ob, gpl, derived_gpf, gps, opacity, tintcolor, false, custonion); + cache, ob, gpl, gpf, gps, opacity, tintcolor, false, custonion); } /* stroke */ /* No fill strokes, must show stroke always */ @@ -1118,14 +1076,13 @@ static void gpencil_draw_strokes(GpencilBatchCache *cache, } gpencil_add_stroke_vertexdata( - cache, ob, gpl, derived_gpf, gps, opacity, tintcolor, false, custonion); + cache, ob, gpl, gpf, gps, opacity, tintcolor, false, custonion); } } } /* edit points (only in edit mode and not play animation not render) */ - if ((draw_ctx->obact == ob) && (src_gps) && (!playing) && (!is_render) && - (!cache_ob->is_dup_ob)) { + if ((draw_ctx->obact == ob) && (!playing) && (!is_render) && (!cache_ob->is_dup_ob)) { if ((gpl->flag & GP_LAYER_LOCKED) == 0) { if (!stl->g_data->shgrps_edit_line) { stl->g_data->shgrps_edit_line = DRW_shgroup_create(e_data->gpencil_line_sh, @@ -1138,11 +1095,9 @@ static void gpencil_draw_strokes(GpencilBatchCache *cache, DRW_shgroup_uniform_vec2(stl->g_data->shgrps_edit_point, "Viewport", viewport_size, 1); } - gpencil_add_editpoints_vertexdata(cache, ob, gpd, gpl, derived_gpf, src_gps); + gpencil_add_editpoints_vertexdata(cache, ob, gpd, gpl, gpf, gps); } } - - GP_SET_SRC_GPS(src_gps); } } @@ -1356,25 +1311,6 @@ static void gpencil_draw_onionskins(GpencilBatchCache *cache, } } -static void gpencil_copy_frame(bGPDframe *gpf, bGPDframe *derived_gpf) -{ - derived_gpf->prev = gpf->prev; - derived_gpf->next = gpf->next; - derived_gpf->framenum = gpf->framenum; - derived_gpf->flag = gpf->flag; - derived_gpf->key_type = gpf->key_type; - derived_gpf->runtime = gpf->runtime; - copy_m4_m4(derived_gpf->runtime.parent_obmat, gpf->runtime.parent_obmat); - - /* copy strokes */ - BLI_listbase_clear(&derived_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); - BLI_addtail(&derived_gpf->strokes, gps_dst); - } -} - /* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was * modified) */ void gpencil_triangulate_stroke_fill(Object *ob, bGPDstroke *gps) @@ -1881,7 +1817,6 @@ void gpencil_populate_multiedit(GPENCIL_e_data *e_data, gpd, gpl, gpf, - gpf, gpl->opacity, gpl->tintcolor, false, @@ -1899,7 +1834,6 @@ void gpencil_populate_multiedit(GPENCIL_e_data *e_data, gpd, gpl, gpf, - gpf, gpl->opacity, gpl->tintcolor, false, @@ -1915,28 +1849,6 @@ void gpencil_populate_multiedit(GPENCIL_e_data *e_data, cache->is_dirty = false; } -/* ensure there is a derived frame */ -static void gpencil_ensure_derived_frame(bGPdata *gpd, - bGPDlayer *gpl, - bGPDframe *gpf, - GpencilBatchCache *cache, - bGPDframe **derived_gpf) -{ - /* create derived frames array data or expand */ - int derived_idx = BLI_findindex(&gpd->layers, gpl); - *derived_gpf = &cache->derived_array[derived_idx]; - - /* if no derived frame or dirty cache, create a new one */ - if ((*derived_gpf == NULL) || (cache->is_dirty)) { - if (*derived_gpf != NULL) { - /* first clear temp data */ - BKE_gpencil_free_frame_runtime_data(*derived_gpf); - } - /* create new data (do not assign new memory)*/ - gpencil_copy_frame(gpf, *derived_gpf); - } -} - /* helper for populate a complete grease pencil datablock */ void gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, @@ -1948,12 +1860,14 @@ void gpencil_populate_datablock(GPENCIL_e_data *e_data, const ViewLayer *view_layer = DEG_get_evaluated_view_layer(draw_ctx->depsgraph); Scene *scene = draw_ctx->scene; - bGPdata *gpd = (bGPdata *)ob->data; + /* Use original data to shared in edit/transform operators */ + bGPdata *gpd_eval = (bGPdata *)ob->data; + bGPdata *gpd = (bGPdata *)DEG_get_original_id(&gpd_eval->id); View3D *v3d = draw_ctx->v3d; int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph); - bGPDframe *derived_gpf = NULL; + bGPDframe *eval_gpf = NULL; const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true; const bool time_remap = BKE_gpencil_has_time_modifiers(ob); @@ -1975,12 +1889,6 @@ void gpencil_populate_datablock(GPENCIL_e_data *e_data, /* calc max size of VBOs */ gpencil_calc_vertex(stl, cache_ob, cache, gpd, cfra_eval); - /* init general modifiers data */ - if (!stl->storage->simplify_modif) { - if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { - BKE_gpencil_lattice_init(ob); - } - } /* draw normal strokes */ for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { /* don't draw layer if hidden */ @@ -2028,8 +1936,9 @@ void gpencil_populate_datablock(GPENCIL_e_data *e_data, opacity = opacity * v3d->overlay.gpencil_fade_layer; } - /* create derived frames array data or expand */ - gpencil_ensure_derived_frame(gpd, gpl, gpf, cache, &derived_gpf); + /* Get evaluated frames array data */ + int eval_idx = BLI_findindex(&gpd->layers, gpl); + eval_gpf = &ob->runtime.gpencil_evaluated_frames[eval_idx]; /* draw onion skins */ if (!ID_IS_LINKED(&gpd->id)) { @@ -2043,23 +1952,8 @@ void gpencil_populate_datablock(GPENCIL_e_data *e_data, } } /* draw normal strokes */ - gpencil_draw_strokes(cache, - e_data, - vedata, - ob, - gpd, - gpl, - gpf, - derived_gpf, - opacity, - gpl->tintcolor, - false, - cache_ob); - } - - /* clear any lattice data */ - if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { - BKE_gpencil_lattice_clear(ob); + gpencil_draw_strokes( + cache, e_data, vedata, ob, gpd, gpl, eval_gpf, opacity, gpl->tintcolor, false, cache_ob); } /* create batchs and shading groups */ diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index efe67e1ead0..9efae54b376 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -405,10 +405,10 @@ void GPENCIL_cache_init(void *vedata) } /* save simplify flags (can change while drawing, so it's better to save) */ - stl->storage->simplify_fill = GP_SIMPLIFY_FILL(scene, stl->storage->is_playing); - stl->storage->simplify_modif = GP_SIMPLIFY_MODIF(scene, stl->storage->is_playing); - stl->storage->simplify_fx = GP_SIMPLIFY_FX(scene, stl->storage->is_playing); - stl->storage->simplify_blend = GP_SIMPLIFY_BLEND(scene, stl->storage->is_playing); + stl->storage->simplify_fill = GPENCIL_SIMPLIFY_FILL(scene, stl->storage->is_playing); + stl->storage->simplify_modif = GPENCIL_SIMPLIFY_MODIF(scene, stl->storage->is_playing); + stl->storage->simplify_fx = GPENCIL_SIMPLIFY_FX(scene, stl->storage->is_playing); + stl->storage->simplify_blend = GPENCIL_SIMPLIFY_BLEND(scene, stl->storage->is_playing); /* xray mode */ if (v3d) { diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h index bc83136fece..6c2c9583979 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.h +++ b/source/blender/draw/engines/gpencil/gpencil_engine.h @@ -35,6 +35,10 @@ struct RenderLayer; struct bGPDstroke; struct tGPspoint; +struct GPUBatch; +struct GPUVertBuf; +struct GPUVertFormat; + #define GPENCIL_CACHE_BLOCK_SIZE 8 #define GPENCIL_MAX_SHGROUPS 65536 #define GPENCIL_GROUPS_BLOCK_SIZE 1024 @@ -46,23 +50,6 @@ struct tGPspoint; #define GPENCIL_COLOR_TEXTURE 1 #define GPENCIL_COLOR_PATTERN 2 -#define GP_SIMPLIFY(scene) ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ENABLE)) -#define GP_SIMPLIFY_ONPLAY(playing) \ - (((playing == true) && (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY)) || \ - ((scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_ON_PLAY) == 0)) -#define GP_SIMPLIFY_FILL(scene, playing) \ - ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && \ - (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FILL))) -#define GP_SIMPLIFY_MODIF(scene, playing) \ - ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && \ - (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_MODIFIER))) -#define GP_SIMPLIFY_FX(scene, playing) \ - ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && \ - (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_FX))) -#define GP_SIMPLIFY_BLEND(scene, playing) \ - ((GP_SIMPLIFY_ONPLAY(playing) && (GP_SIMPLIFY(scene)) && \ - (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_BLEND))) - #define GP_IS_CAMERAVIEW ((rv3d != NULL) && (rv3d->persp == RV3D_CAMOB && v3d->camera)) /* *********** OBJECTS CACHE *********** */ @@ -341,13 +328,13 @@ typedef struct GPENCIL_e_data { } GPENCIL_e_data; /* Engine data */ -/* GPUBatch Cache */ +/* GPUBatch Cache Element */ typedef struct GpencilBatchCacheElem { GPUBatch *batch; GPUVertBuf *vbo; int vbo_len; /* attr ids */ - GPUVertFormat format; + GPUVertFormat *format; uint pos_id; uint color_id; uint thickness_id; @@ -358,6 +345,7 @@ typedef struct GpencilBatchCacheElem { int tot_vertex; } GpencilBatchCacheElem; +/* Defines each batch group to define later the shgroup */ typedef struct GpencilBatchGroup { struct bGPDlayer *gpl; /* reference to original layer */ struct bGPDframe *gpf; /* reference to original frame */ @@ -375,6 +363,7 @@ typedef enum GpencilBatchGroup_Type { eGpencilBatchGroupType_Edlin = 5, } GpencilBatchGroup_Type; +/* Runtime data for GPU and evaluated frames after applying modifiers */ typedef struct GpencilBatchCache { GpencilBatchCacheElem b_stroke; GpencilBatchCacheElem b_point; @@ -382,18 +371,19 @@ typedef struct GpencilBatchCache { GpencilBatchCacheElem b_edit; GpencilBatchCacheElem b_edlin; - /* settings to determine if cache is invalid */ + /** Cache is dirty */ bool is_dirty; + /** Edit mode flag */ bool is_editmode; + /** Last cache frame */ int cache_frame; - /* data with the shading groups */ - int grp_used; /* total groups in arrays */ - int grp_size; /* max size of the array */ - struct GpencilBatchGroup *grp_cache; /* array of elements */ - - int tot_layers; - struct bGPDframe *derived_array; /* runtime data created by modifiers */ + /** Total groups in arrays */ + int grp_used; + /** Max size of the array */ + int grp_size; + /** Array of cache elements */ + struct GpencilBatchGroup *grp_cache; } GpencilBatchCache; /* general drawing functions */ diff --git a/source/blender/editors/gpencil/gpencil_data.c b/source/blender/editors/gpencil/gpencil_data.c index e4d6a3e983d..c22e3bda0b1 100644 --- a/source/blender/editors/gpencil/gpencil_data.c +++ b/source/blender/editors/gpencil/gpencil_data.c @@ -2886,7 +2886,7 @@ static int gpencil_color_select_exec(bContext *C, wmOperator *op) CTX_DATA_END; /* copy on write tag is needed, or else no refresh happens */ - DEG_id_tag_update(&gpd->id, ID_RECALC_COPY_ON_WRITE); + DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE); /* notifiers */ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL); diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h index 9682fa1d13b..58a7bf8f8b4 100644 --- a/source/blender/makesdna/DNA_gpencil_types.h +++ b/source/blender/makesdna/DNA_gpencil_types.h @@ -51,6 +51,14 @@ typedef struct bGPDcontrolpoint { int size; } bGPDcontrolpoint; +typedef struct bGPDspoint_Runtime { + /** Original point (used to dereference evaluated data) */ + struct bGPDspoint *pt_orig; + /** Original index array position */ + int idx_orig; + char _pad0[4]; +} bGPDspoint_Runtime; + /* Grease-Pencil Annotations - 'Stroke Point' * -> Coordinates may either be 2d or 3d depending on settings at the time * -> Coordinates of point on stroke, in proportions of window size @@ -72,6 +80,10 @@ typedef struct bGPDspoint { float uv_fac; /** Uv rotation for dot mode. */ float uv_rot; + + /** Runtime data */ + char _pad2[4]; + bGPDspoint_Runtime runtime; } bGPDspoint; /* bGPDspoint->flag */ @@ -156,15 +168,21 @@ typedef enum eGPDpalette_Flag { /* Runtime temp data for bGPDstroke */ typedef struct bGPDstroke_Runtime { - /* runtime final colors (result of original colors and modifiers) */ + /** runtime final colors (result of original colors and modifiers) */ float tmp_stroke_rgba[4]; + + /** runtime final fill colors (result of original colors and modifiers) */ float tmp_fill_rgba[4]; - /* temporary layer name only used during copy/paste to put the stroke in the original layer */ + /** temporary layer name only used during copy/paste to put the stroke in the original layer */ char tmp_layerinfo[128]; /** Runtime falloff factor (only for transform). */ float multi_frame_falloff; + char _pad[4]; + + /** Original stroke (used to dereference evaluated data) */ + struct bGPDstroke *gps_orig; } bGPDstroke_Runtime; /* Grease-Pencil Annotations - 'Stroke' @@ -210,7 +228,6 @@ typedef struct bGPDstroke { void *_pad3; bGPDstroke_Runtime runtime; - char _pad2[4]; } bGPDstroke; /* bGPDstroke->flag */ @@ -468,7 +485,6 @@ typedef struct bGPdata { ListBase layers; /** Settings for this data-block. */ int flag; - char _pad1[4]; /* Palettes */ diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index d9487f4338f..1b82e7463c1 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -176,6 +176,11 @@ typedef struct Object_Runtime { /** Runtime grease pencil drawing data */ struct GpencilBatchCache *gpencil_cache; + /** Runtime grease pencil total layers used for evaluated data created by modifiers */ + int gpencil_tot_layers; + char _pad4[4]; + /** Runtime grease pencil evaluated data created by modifiers */ + struct bGPDframe *gpencil_evaluated_frames; void *_pad2; /* Padding is here for win32s unconventional struct alignment rules. */ } Object_Runtime; |