Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_data_gpencil.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_data_modifier.py1
-rw-r--r--source/blender/blenkernel/intern/library.c8
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_cache_utils.c65
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c34
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c184
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.c200
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h42
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_shader_fx.c49
-rw-r--r--source/blender/editors/object/object_add.c6
-rw-r--r--source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c127
-rw-r--r--source/blender/makesdna/DNA_gpencil_modifier_types.h1
-rw-r--r--source/blender/makesdna/DNA_gpencil_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_gpencil_modifier.c5
14 files changed, 308 insertions, 421 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_gpencil.py b/release/scripts/startup/bl_ui/properties_data_gpencil.py
index 90dc86a20bb..effa527e6db 100644
--- a/release/scripts/startup/bl_ui/properties_data_gpencil.py
+++ b/release/scripts/startup/bl_ui/properties_data_gpencil.py
@@ -266,7 +266,10 @@ class DATA_PT_gpencil_onionpanel(Panel):
layout = self.layout
layout.use_property_split = True
- layout.enabled = gpd.use_onion_skinning
+ layout.enabled = gpd.use_onion_skinning and gpd.users <= 1
+
+ if gpd.use_onion_skinning and gpd.users > 1:
+ layout.label("Multiuser datablock not supported", icon='ERROR')
GreasePencilOnionPanel.draw_settings(layout, gpd)
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index f865a7f7226..45af80c0a62 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -1843,7 +1843,6 @@ class DATA_PT_gpencil_modifiers(ModifierButtonsPanel, Panel):
col = layout.column()
col.prop(md, "count")
- col.prop(md, "use_make_objects")
split = layout.split()
col = split.column()
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index d81dddb2b98..08d68f4a480 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -785,6 +785,14 @@ bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
RNA_property_pointer_set(ptr, prop, idptr);
RNA_property_update(C, ptr, prop);
+ /* tag grease pencil datablock and disable onion */
+ if (GS(id->name) == ID_GD) {
+ DEG_id_tag_update(id, OB_RECALC_OB | OB_RECALC_DATA);
+ DEG_id_tag_update(newid, OB_RECALC_OB | OB_RECALC_DATA);
+ bGPdata *gpd = (bGPdata *)newid;
+ gpd->flag &= ~GP_DATA_SHOW_ONIONSKINS;
+ }
+
return true;
}
}
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index e8bb27b2724..4c427a672d2 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -37,9 +37,44 @@
#include "draw_cache_impl.h"
+static bool gpencil_check_ob_duplicated(tGPencilObjectCache *cache_array, int gp_cache_used, Object *ob)
+{
+ if (gp_cache_used == 0) {
+ return false;
+ }
+
+ for (int i = 0; i < gp_cache_used + 1; i++) {
+ tGPencilObjectCache *cache_elem = &cache_array[i];
+ if (STREQ(cache_elem->ob_name, ob->id.name) &&
+ (cache_elem->is_dup_ob == false))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool gpencil_check_datablock_duplicated(tGPencilObjectCache *cache_array, int gp_cache_used,
+ Object *ob, bGPdata *gpd)
+{
+ if (gp_cache_used == 0) {
+ return false;
+ }
+
+ for (int i = 0; i < gp_cache_used + 1; i++) {
+ tGPencilObjectCache *cache_elem = &cache_array[i];
+ if (!STREQ(cache_elem->ob_name, ob->id.name) &&
+ (cache_elem->gpd == gpd))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
/* add a gpencil object to cache to defer drawing */
tGPencilObjectCache *gpencil_object_cache_add(
- tGPencilObjectCache *cache_array, Object *ob, bool is_temp,
+ tGPencilObjectCache *cache_array, Object *ob,
int *gp_cache_size, int *gp_cache_used)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -61,16 +96,26 @@ tGPencilObjectCache *gpencil_object_cache_add(
}
cache_array = p;
}
-
/* zero out all pointers */
cache_elem = &cache_array[*gp_cache_used];
memset(cache_elem, 0, sizeof(*cache_elem));
- /* save object */
- cache_elem->ob = ob;
- cache_elem->temp_ob = is_temp;
+ cache_elem->is_dup_ob = gpencil_check_ob_duplicated(cache_array, *gp_cache_used, ob);
+
+ sprintf(cache_elem->ob_name, "%s", ob->id.name);
+ cache_elem->gpd = (bGPdata *)ob->data;
+
+ copy_v3_v3(cache_elem->loc, ob->loc);
+ copy_m4_m4(cache_elem->obmat, ob->obmat);
cache_elem->idx = *gp_cache_used;
+ cache_elem->is_dup_onion = gpencil_check_datablock_duplicated(cache_array, *gp_cache_used,
+ ob, cache_elem->gpd);
+
+ /* save FXs */
+ cache_elem->pixfactor = cache_elem->gpd->pixfactor;
+ cache_elem->shader_fx = ob->shader_fx;
+
cache_elem->init_grp = 0;
cache_elem->end_grp = -1;
@@ -203,7 +248,7 @@ static void gpencil_batch_cache_init(Object *ob, int cfra)
}
/* clear cache */
-static void gpencil_batch_cache_clear(GpencilBatchCache *cache, bGPdata *gpd)
+static void gpencil_batch_cache_clear(GpencilBatchCache *cache)
{
if (!cache) {
return;
@@ -213,10 +258,6 @@ static void gpencil_batch_cache_clear(GpencilBatchCache *cache, bGPdata *gpd)
return;
}
- if (G.debug_value >= 664) {
- printf("gpencil_batch_cache_clear: %s\n", gpd->id.name);
- }
-
if (cache->cache_size > 0) {
for (int i = 0; i < cache->cache_size; i++) {
GPU_BATCH_DISCARD_SAFE(cache->batch_stroke[i]);
@@ -245,7 +286,7 @@ GpencilBatchCache *gpencil_batch_cache_get(Object *ob, int cfra)
GpencilBatchCache *cache = gpencil_batch_get_element(ob);
if (cache) {
- gpencil_batch_cache_clear(cache, gpd);
+ gpencil_batch_cache_clear(cache);
BLI_ghash_remove(gpd->runtime.batch_cache_data, ob->id.name, NULL, NULL);
}
gpencil_batch_cache_init(ob, cfra);
@@ -283,7 +324,7 @@ void DRW_gpencil_batch_cache_free(bGPdata *gpd)
while (!BLI_ghashIterator_done(ihash)) {
GpencilBatchCache *cache = (GpencilBatchCache *)BLI_ghashIterator_getValue(ihash);
if (cache) {
- gpencil_batch_cache_clear(cache, gpd);
+ gpencil_batch_cache_clear(cache);
}
BLI_ghashIterator_step(ihash);
}
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 83a52e077ca..2102f255f75 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -52,12 +52,11 @@
/* Helper to add stroke point to vbo */
static void gpencil_set_stroke_point(
- GPUVertBuf *vbo, float matrix[4][4], const bGPDspoint *pt, int idx,
+ GPUVertBuf *vbo, const bGPDspoint *pt, int idx,
uint pos_id, uint color_id,
uint thickness_id, uint uvdata_id, short thickness,
const float ink[4])
{
- float viewfpt[3];
float alpha = ink[3] * pt->strength;
CLAMP(alpha, GPENCIL_STRENGTH_MIN, 1.0f);
@@ -71,7 +70,6 @@ static void gpencil_set_stroke_point(
GPU_vertbuf_attr_set(vbo, uvdata_id, idx, uvdata);
/* the thickness of the stroke must be affected by zoom, so a pixel scale is calculated */
- mul_v3_m4v3(viewfpt, matrix, &pt->x);
float thick = max_ff(pt->pressure * thickness, 1.0f);
GPU_vertbuf_attr_set(vbo, thickness_id, idx, &thick);
@@ -132,7 +130,7 @@ GPUBatch *DRW_gpencil_get_point_geom(bGPDstroke *gps, short thickness, const flo
}
/* create batch geometry data for stroke shader */
-GPUBatch *DRW_gpencil_get_stroke_geom(bGPDframe *gpf, bGPDstroke *gps, short thickness, const float ink[4])
+GPUBatch *DRW_gpencil_get_stroke_geom(bGPDstroke *gps, short thickness, const float ink[4])
{
bGPDspoint *points = gps->points;
int totpoints = gps->totpoints;
@@ -159,20 +157,20 @@ GPUBatch *DRW_gpencil_get_stroke_geom(bGPDframe *gpf, bGPDstroke *gps, short thi
if (i == 0) {
if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) {
gpencil_set_stroke_point(
- vbo, gpf->runtime.viewmatrix, &points[totpoints - 1], idx,
+ vbo, &points[totpoints - 1], idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, ink);
idx++;
}
else {
gpencil_set_stroke_point(
- vbo, gpf->runtime.viewmatrix, &points[1], idx,
+ vbo, &points[1], idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, ink);
idx++;
}
}
/* set point */
gpencil_set_stroke_point(
- vbo, gpf->runtime.viewmatrix, pt, idx,
+ vbo, pt, idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, ink);
idx++;
}
@@ -180,19 +178,19 @@ GPUBatch *DRW_gpencil_get_stroke_geom(bGPDframe *gpf, bGPDstroke *gps, short thi
if (gps->flag & GP_STROKE_CYCLIC && totpoints > 2) {
/* draw line to first point to complete the cycle */
gpencil_set_stroke_point(
- vbo, gpf->runtime.viewmatrix, &points[0], idx,
+ vbo, &points[0], idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, ink);
idx++;
/* now add adjacency point (not drawn) */
gpencil_set_stroke_point(
- vbo, gpf->runtime.viewmatrix, &points[1], idx,
+ vbo, &points[1], idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, ink);
idx++;
}
/* last adjacency point (not drawn) */
else {
gpencil_set_stroke_point(
- vbo, gpf->runtime.viewmatrix, &points[totpoints - 2], idx,
+ vbo, &points[totpoints - 2], idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, ink);
}
@@ -200,7 +198,7 @@ GPUBatch *DRW_gpencil_get_stroke_geom(bGPDframe *gpf, bGPDstroke *gps, short thi
}
/* create batch geometry data for current buffer stroke shader */
-GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, float matrix[4][4], short thickness)
+GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, short thickness)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
@@ -244,19 +242,19 @@ GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, float matrix[4][4], s
if (totpoints > 1) {
ED_gpencil_tpoint_to_point(ar, origin, &points[1], &pt2);
gpencil_set_stroke_point(
- vbo, matrix, &pt2, idx,
+ vbo, &pt2, idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
}
else {
gpencil_set_stroke_point(
- vbo, matrix, &pt, idx,
+ vbo, &pt, idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
}
idx++;
}
/* set point */
gpencil_set_stroke_point(
- vbo, matrix, &pt, idx,
+ vbo, &pt, idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
idx++;
}
@@ -265,12 +263,12 @@ GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, float matrix[4][4], s
if (totpoints > 2) {
ED_gpencil_tpoint_to_point(ar, origin, &points[totpoints - 2], &pt2);
gpencil_set_stroke_point(
- vbo, matrix, &pt2, idx,
+ vbo, &pt2, idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
}
else {
gpencil_set_stroke_point(
- vbo, matrix, &pt, idx,
+ vbo, &pt, idx,
pos_id, color_id, thickness_id, uvdata_id, thickness, gpd->runtime.scolor);
}
@@ -278,7 +276,7 @@ GPUBatch *DRW_gpencil_get_buffer_stroke_geom(bGPdata *gpd, float matrix[4][4], s
}
/* create batch geometry data for current buffer point shader */
-GPUBatch *DRW_gpencil_get_buffer_point_geom(bGPdata *gpd, float matrix[4][4], short thickness)
+GPUBatch *DRW_gpencil_get_buffer_point_geom(bGPdata *gpd, short thickness)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
Scene *scene = draw_ctx->scene;
@@ -319,7 +317,7 @@ GPUBatch *DRW_gpencil_get_buffer_point_geom(bGPdata *gpd, float matrix[4][4], sh
/* set point */
gpencil_set_stroke_point(
- vbo, matrix, &pt, idx,
+ vbo, &pt, idx,
pos_id, color_id, thickness_id, uvdata_id,
thickness, gpd->runtime.scolor);
idx++;
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index 401934b35a7..16412dda3f8 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -587,7 +587,8 @@ static void gpencil_add_fill_shgroup(
/* add stroke shading group to pass */
static void gpencil_add_stroke_shgroup(GpencilBatchCache *cache, DRWShadingGroup *strokegrp,
Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *gps,
- const float opacity, const float tintcolor[4], const bool onion, const bool custonion)
+ const float opacity, const float tintcolor[4], const bool onion,
+ const bool custonion)
{
float tcolor[4];
float ink[4];
@@ -622,7 +623,7 @@ static void gpencil_add_stroke_shgroup(GpencilBatchCache *cache, DRWShadingGroup
if (cache->is_dirty) {
gpencil_batch_cache_check_free_slots(ob);
if ((gps->totpoints > 1) && (gp_style->mode == GP_STYLE_MODE_LINE)) {
- cache->batch_stroke[cache->cache_idx] = DRW_gpencil_get_stroke_geom(gpf, gps, sthickness, ink);
+ cache->batch_stroke[cache->cache_idx] = DRW_gpencil_get_stroke_geom(gps, sthickness, ink);
}
else {
cache->batch_stroke[cache->cache_idx] = DRW_gpencil_get_point_geom(gps, sthickness, ink);
@@ -742,7 +743,8 @@ static void gpencil_draw_onion_strokes(
static void gpencil_draw_strokes(
GpencilBatchCache *cache, GPENCIL_e_data *e_data, void *vedata, ToolSettings *ts, Object *ob,
bGPdata *gpd, bGPDlayer *gpl, bGPDframe *src_gpf, bGPDframe *derived_gpf,
- const float opacity, const float tintcolor[4], const bool custonion)
+ const float opacity, const float tintcolor[4],
+ const bool custonion, tGPencilObjectCache *cache_ob)
{
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
@@ -769,6 +771,10 @@ static void gpencil_draw_strokes(
ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, viewmatrix);
copy_m4_m4(derived_gpf->runtime.viewmatrix, viewmatrix);
+ if ((cache_ob != NULL) && (cache_ob->is_dup_ob)) {
+ copy_m4_m4(derived_gpf->runtime.viewmatrix, cache_ob->obmat);
+ }
+
/* apply geometry modifiers */
if ((cache->is_dirty) && (ob->greasepencil_modifiers.first) && (!is_multiedit)) {
if (!stl->storage->simplify_modif) {
@@ -797,7 +803,7 @@ static void gpencil_draw_strokes(
continue;
}
- /* be sure recalc all chache in source stroke to avoid recalculation when frame change
+ /* be sure recalc all cache in source stroke to avoid recalculation when frame change
* and improve fps */
if (src_gps) {
DRW_gpencil_recalc_geometry_caches(ob, gp_style, src_gps);
@@ -859,17 +865,21 @@ static void gpencil_draw_strokes(
/* fill */
if ((fillgrp) && (!stl->storage->simplify_fill)) {
gpencil_add_fill_shgroup(
- cache, fillgrp, ob, gpl, derived_gpf, gps, tintcolor, false, custonion);
+ cache, fillgrp, ob, gpl, derived_gpf, gps,
+ tintcolor, false, custonion);
}
/* stroke */
if (strokegrp) {
gpencil_add_stroke_shgroup(
- cache, strokegrp, ob, gpl, derived_gpf, gps, opacity, tintcolor, false, custonion);
+ cache, strokegrp, ob, gpl, derived_gpf, gps,
+ opacity, tintcolor, false, custonion);
}
}
/* edit points (only in edit mode and not play animation not render) */
- if ((src_gps) && (!playing) && (!is_render)) {
+ if ((draw_ctx->obact == ob) && (src_gps) &&
+ (!playing) && (!is_render) && (!cache_ob->is_dup_ob))
+ {
if (!stl->g_data->shgrps_edit_line) {
stl->g_data->shgrps_edit_line = DRW_shgroup_create(e_data->gpencil_line_sh, psl->edit_pass);
}
@@ -942,11 +952,11 @@ void DRW_gpencil_populate_buffer_strokes(GPENCIL_e_data *e_data, void *vedata, T
/* use unit matrix because the buffer is in screen space and does not need conversion */
if (gpd->runtime.mode == GP_STYLE_MODE_LINE) {
e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_stroke_geom(
- gpd, stl->storage->unit_matrix, lthick);
+ gpd, lthick);
}
else {
e_data->batch_buffer_stroke = DRW_gpencil_get_buffer_point_geom(
- gpd, stl->storage->unit_matrix, lthick);
+ gpd, lthick);
}
DRW_shgroup_call_add(
@@ -1146,8 +1156,10 @@ static void gpencil_draw_onionskins(
}
/* populate a datablock for multiedit (no onions, no modifiers) */
-void DRW_gpencil_populate_multiedit(GPENCIL_e_data *e_data, void *vedata, Scene *scene, Object *ob, bGPdata *gpd)
+void DRW_gpencil_populate_multiedit(GPENCIL_e_data *e_data, void *vedata, Scene *scene, Object *ob,
+ tGPencilObjectCache *cache_ob)
{
+ bGPdata *gpd = (bGPdata *)ob->data;
bGPDframe *gpf = NULL;
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
@@ -1172,7 +1184,7 @@ void DRW_gpencil_populate_multiedit(GPENCIL_e_data *e_data, void *vedata, Scene
if ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)) {
gpencil_draw_strokes(
cache, e_data, vedata, ts, ob, gpd, gpl, gpf, gpf,
- gpl->opacity, gpl->tintcolor, false);
+ gpl->opacity, gpl->tintcolor, false, cache_ob);
}
}
}
@@ -1181,7 +1193,7 @@ void DRW_gpencil_populate_multiedit(GPENCIL_e_data *e_data, void *vedata, Scene
if (gpf) {
gpencil_draw_strokes(
cache, e_data, vedata, ts, ob, gpd, gpl, gpf, gpf,
- gpl->opacity, gpl->tintcolor, false);
+ gpl->opacity, gpl->tintcolor, false, cache_ob);
}
}
@@ -1191,16 +1203,20 @@ void DRW_gpencil_populate_multiedit(GPENCIL_e_data *e_data, void *vedata, Scene
}
/* helper for populate a complete grease pencil datablock */
-void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, Scene *scene, Object *ob, bGPdata *gpd)
+void DRW_gpencil_populate_datablock(
+ GPENCIL_e_data *e_data, void *vedata,
+ Scene *scene, Object *ob,
+ tGPencilObjectCache *cache_ob)
{
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
+ bGPdata *gpd = (bGPdata *)ob->data;
View3D *v3d = draw_ctx->v3d;
int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
ToolSettings *ts = scene->toolsettings;
bGPDframe *derived_gpf = NULL;
- const bool main_onion = v3d != NULL ? ((v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) == 0) : true;
- const bool no_onion = (bool)(gpd->flag & GP_DATA_STROKE_WEIGHTMODE) || main_onion;
+ const bool main_onion = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : true;
+ const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && main_onion;
const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true;
/* check if playing animation */
@@ -1230,17 +1246,21 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, Scene
gpl->runtime.derived_data = (GHash *)BLI_ghash_str_new(gpl->info);
}
- if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) {
+ if (BLI_ghash_haskey(gpl->runtime.derived_data,ob->id.name)) {
derived_gpf = BLI_ghash_lookup(gpl->runtime.derived_data, ob->id.name);
}
else {
+ /* verify we have frame duplicated already */
+ if (cache_ob->is_dup_ob) {
+ continue;
+ }
derived_gpf = NULL;
}
if (derived_gpf == NULL) {
cache->is_dirty = true;
}
- if (cache->is_dirty) {
+ if ((!cache_ob->is_dup_ob) && (cache->is_dirty)) {
if (derived_gpf != NULL) {
/* first clear temp data */
if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) {
@@ -1258,24 +1278,36 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, Scene
BLI_ghash_reinsert(gpl->runtime.derived_data, ob->id.name, derived_gpf, NULL, NULL);
}
}
-
/* draw onion skins */
- if ((gpd->flag & GP_DATA_SHOW_ONIONSKINS) &&
- (!no_onion) && (overlay) &&
- (gpl->onion_flag & GP_LAYER_ONIONSKIN) &&
- ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)))
- {
- if ((!stl->storage->is_render) ||
- ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)))
+ if (!ID_IS_LINKED(&gpd->id)) {
+ ID *orig_id = gpd->id.orig_id;
+ /* GPXX: Now only a datablock with one use is allowed to be compatible
+ * with instances
+ */
+ if ((!cache_ob->is_dup_onion) && (gpd->flag & GP_DATA_SHOW_ONIONSKINS) &&
+ (do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN) &&
+ ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)) &&
+ (!cache_ob->is_dup_ob) && (orig_id->us <= 1))
{
- gpencil_draw_onionskins(cache, e_data, vedata, ob, gpd, gpl, gpf);
+ if (((!stl->storage->is_render) && (overlay)) ||
+ ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)))
+ {
+ gpencil_draw_onionskins(cache, e_data, vedata, ob, gpd, gpl, gpf);
+ }
}
}
-
/* draw normal strokes */
+ if (!cache_ob->is_dup_ob) {
+ /* save batch index */
+ gpl->runtime.batch_index = cache->cache_idx;
+ }
+ else {
+ cache->cache_idx = gpl->runtime.batch_index;
+ }
+
gpencil_draw_strokes(
cache, e_data, vedata, ts, ob, gpd, gpl, gpf, derived_gpf,
- gpl->opacity, gpl->tintcolor, false);
+ gpl->opacity, gpl->tintcolor, false, cache_ob);
}
@@ -1286,99 +1318,3 @@ void DRW_gpencil_populate_datablock(GPENCIL_e_data *e_data, void *vedata, Scene
cache->is_dirty = false;
}
-
-/* Helper for gpencil_instance_modifiers()
- * See also MOD_gpencilinstance.c -> bakeModifier()
- */
-static void gp_instance_modifier_make_instances(GPENCIL_StorageList *stl, Object *ob, InstanceGpencilModifierData *mmd)
-{
- /* reset random */
- mmd->rnd[0] = 1;
- int e = 0;
-
- /* Generate instances */
- for (int x = 0; x < mmd->count[0]; x++) {
- for (int y = 0; y < mmd->count[1]; y++) {
- for (int z = 0; z < mmd->count[2]; z++) {
- if ((x == 0) && (y == 0) && (z == 0)) {
- continue;
- }
-
- Object *newob = NULL;
- const int elem_idx[3] = {x, y, z};
- float mat[4][4];
- int sh;
-
- /* original strokes are at index = 0,0,0 */
- if ((x == 0) && (y == 0) && (z == 0)) {
- continue;
- }
-
- /* compute transform for instance */
- BKE_gpencil_instance_modifier_instance_tfm(mmd, elem_idx, mat);
-
- /* add object to cache */
- newob = MEM_dupallocN(ob);
-
- /* Create a unique name or the object hash used in draw will fail.
- * the name must be unique in the hash, not in the scene because
- * the object never is linked to scene and is removed after drawing.
- *
- * It uses special characters to be sure the name cannot be equal
- * to any existing name because UI limits the use of special characters.
- *
- * Name = OB\t_{pointer}_{index}
- */
- sprintf(newob->id.name, "OB\t_%p_%d", &ob, e++);
-
- mul_m4_m4m4(newob->obmat, ob->obmat, mat);
-
- /* apply scale */
- ARRAY_SET_ITEMS(newob->size, mat[0][0], mat[1][1], mat[2][2]);
-
- /* apply shift */
- sh = x;
- if (mmd->lock_axis == GP_LOCKAXIS_Y) {
- sh = y;
- }
- if (mmd->lock_axis == GP_LOCKAXIS_Z) {
- sh = z;
- }
- madd_v3_v3fl(newob->obmat[3], mmd->shift, sh);
-
- /* add temp object to cache */
- stl->g_data->gp_object_cache = gpencil_object_cache_add(
- stl->g_data->gp_object_cache, newob, true,
- &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used);
- }
- }
- }
-}
-
-/* create instances using instance modifiers */
-void gpencil_instance_modifiers(GPENCIL_StorageList *stl, Object *ob)
-{
- if ((ob) && (ob->data)) {
- bGPdata *gpd = ob->data;
- if (GPENCIL_ANY_EDIT_MODE(gpd)) {
- return;
- }
- }
-
- for (GpencilModifierData *md = ob->greasepencil_modifiers.first; md; md = md->next) {
- if (((md->mode & eGpencilModifierMode_Realtime) && (stl->storage->is_render == false)) ||
- ((md->mode & eGpencilModifierMode_Render) && (stl->storage->is_render == true)))
- {
- if (md->type == eGpencilModifierType_Instance) {
- InstanceGpencilModifierData *mmd = (InstanceGpencilModifierData *)md;
-
- /* Only add instances if the "Make Objects" flag is set
- * FIXME: This is a workaround for z-ordering weirdness when all instances are in the same object
- */
- if (mmd->flag & GP_INSTANCE_MAKE_OBJECTS) {
- gp_instance_modifier_make_instances(stl, ob, mmd);
- }
- }
- }
- }
-}
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c
index 2a4f2f999bc..90ef6fedd58 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.c
@@ -273,6 +273,9 @@ static void GPENCIL_engine_free(void)
GPU_BATCH_DISCARD_SAFE(e_data.batch_buffer_fill);
MEM_SAFE_FREE(e_data.batch_buffer_fill);
+ GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
+ MEM_SAFE_FREE(e_data.batch_grid);
+
/* effects */
GPENCIL_delete_fx_shaders(&e_data);
}
@@ -333,9 +336,16 @@ void GPENCIL_cache_init(void *vedata)
DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND);
/* detect if playing animation */
- stl->storage->is_playing = false;
if (draw_ctx->evil_C) {
- stl->storage->is_playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL;
+ bool playing = ED_screen_animation_playing(CTX_wm_manager(draw_ctx->evil_C)) != NULL;
+ if (playing != stl->storage->is_playing) {
+ stl->storage->reset_cache = true;
+ }
+ stl->storage->is_playing = playing;
+ }
+ else {
+ stl->storage->is_playing = false;
+ stl->storage->reset_cache = false;
}
/* save render state */
stl->storage->is_render = DRW_state_is_image_render();
@@ -477,6 +487,56 @@ void GPENCIL_cache_init(void *vedata)
}
}
+static void gpencil_add_draw_data(void *vedata, Object *ob)
+{
+ GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ Scene *scene = draw_ctx->scene;
+ bGPdata *gpd = (bGPdata *)ob->data;
+ bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+
+ int i = stl->g_data->gp_cache_used - 1;
+ tGPencilObjectCache *cache_ob = &stl->g_data->gp_object_cache[i];
+
+ if (cache_ob->is_dup_ob == false) {
+ /* save init shading group */
+ cache_ob->init_grp = stl->storage->shgroup_id;
+
+ /* fill shading groups */
+ if (!is_multiedit) {
+ DRW_gpencil_populate_datablock(&e_data, vedata, scene, ob, cache_ob);
+ }
+ else {
+ DRW_gpencil_populate_multiedit(&e_data, vedata, scene, ob, cache_ob);
+ }
+
+ /* save end shading group */
+ cache_ob->end_grp = stl->storage->shgroup_id - 1;
+ }
+ else {
+ /* save init shading group */
+ cache_ob->init_grp = stl->storage->shgroup_id;
+
+ DRW_gpencil_populate_datablock(&e_data, vedata, scene, ob,
+ cache_ob);
+
+ /* save end shading group */
+ cache_ob->end_grp = stl->storage->shgroup_id - 1;
+ }
+
+ /* FX passses */
+ cache_ob->has_fx = false;
+ if ((!stl->storage->simplify_fx) &&
+ (BKE_shaderfx_has_gpencil(ob)))
+ {
+ cache_ob->has_fx = true;
+ if ((!stl->storage->simplify_fx) && (!is_multiedit)) {
+ DRW_gpencil_fx_prepare(&e_data, vedata, cache_ob);
+ }
+ }
+
+}
+
void GPENCIL_cache_populate(void *vedata, Object *ob)
{
/* object must be visible */
@@ -489,31 +549,40 @@ void GPENCIL_cache_populate(void *vedata, Object *ob)
Scene *scene = draw_ctx->scene;
ToolSettings *ts = scene->toolsettings;
View3D *v3d = draw_ctx->v3d;
+ tGPencilObjectCache *cache_ob = NULL;
/* object datablock (this is not draw now) */
if (ob->type == OB_GPENCIL && ob->data) {
bGPdata *gpd = (bGPdata *)ob->data;
- if ((stl->g_data->session_flag & GP_DRW_PAINT_READY) == 0) {
- /* if render set as dirty */
- if (stl->storage->is_render == true) {
- gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
- }
+ /* when start/stop animation the cache must be set as dirty to reset all data */
+ if (stl->storage->reset_cache) {
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+ stl->storage->reset_cache = false;
+ }
- /* allocate memory for saving gp objects for drawing later */
+ /* is edit mode only current object, not instances */
+ if ((draw_ctx->obact != ob) && GPENCIL_ANY_EDIT_MODE(gpd)) {
+ return;
+ }
+
+ if ((stl->g_data->session_flag & GP_DRW_PAINT_READY) == 0) {
+
+ /* save gp objects for drawing later */
stl->g_data->gp_object_cache = gpencil_object_cache_add(
- stl->g_data->gp_object_cache, ob, false,
- &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used);
-
- /* generate instances as separate cache objects for instance modifiers
- * with the "Make as Objects" option enabled
- */
- if (!stl->storage->simplify_modif) {
- gpencil_instance_modifiers(stl, ob);
- }
+ stl->g_data->gp_object_cache, ob,
+ &stl->g_data->gp_cache_size, &stl->g_data->gp_cache_used);
+
+ cache_ob = &stl->g_data->gp_object_cache[stl->g_data->gp_cache_used - 1];
+
+ /* load drawing data */
+ gpencil_add_draw_data(vedata, ob);
}
+
/* draw current painting strokes */
- DRW_gpencil_populate_buffer_strokes(&e_data, vedata, ts, ob);
+ if (draw_ctx->obact == ob) {
+ DRW_gpencil_populate_buffer_strokes(&e_data, vedata, ts, ob);
+ }
/* grid */
if ((v3d) &&
@@ -521,57 +590,21 @@ void GPENCIL_cache_populate(void *vedata, Object *ob)
(v3d->gp_flag & V3D_GP_SHOW_GRID) &&
(ob->type == OB_GPENCIL) && (ob == draw_ctx->obact))
{
- stl->g_data->batch_grid = DRW_gpencil_get_grid();
+ GPU_BATCH_DISCARD_SAFE(e_data.batch_grid);
+ MEM_SAFE_FREE(e_data.batch_grid);
+
+ e_data.batch_grid = DRW_gpencil_get_grid();
DRW_shgroup_call_add(stl->g_data->shgrps_grid,
- stl->g_data->batch_grid,
- ob->obmat);
+ e_data.batch_grid,
+ ob->obmat);
}
}
}
-void GPENCIL_cache_finish(void *vedata)
+void GPENCIL_cache_finish(void *UNUSED(vedata))
{
- GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- Scene *scene = draw_ctx->scene;
- bool is_multiedit = false;
-
- /* if painting session, don't need to do more */
- if (stl->g_data->session_flag & GP_DRW_PAINT_PAINTING) {
- return;
- }
-
- /* Draw all pending objects */
- if (stl->g_data->gp_cache_used > 0) {
- for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
- Object *ob = stl->g_data->gp_object_cache[i].ob;
- bGPdata *gpd = ob->data;
-
- /* save init shading group */
- stl->g_data->gp_object_cache[i].init_grp = stl->storage->shgroup_id;
+ return;
- /* fill shading groups */
- is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- if (!is_multiedit) {
- DRW_gpencil_populate_datablock(&e_data, vedata, scene, ob, gpd);
- }
- else {
- DRW_gpencil_populate_multiedit(&e_data, vedata, scene, ob, gpd);
- }
-
- /* save end shading group */
- stl->g_data->gp_object_cache[i].end_grp = stl->storage->shgroup_id - 1;
- /* if render set to dirty to refresh viewport */
- if (stl->storage->is_render == true) {
- gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
- }
- /* FX passses */
- tGPencilObjectCache *cache = &stl->g_data->gp_object_cache[i];
- if ((!stl->storage->simplify_fx) && (!is_multiedit)) {
- DRW_gpencil_fx_prepare(&e_data, vedata, cache);
- }
- }
- }
}
/* helper function to sort inverse gpencil objects using qsort */
@@ -605,21 +638,8 @@ static void gpencil_prepare_fast_drawing(
}
}
-static void gpencil_free_obj_list(GPENCIL_StorageList *stl)
+static void gpencil_free_obj_runtime(GPENCIL_StorageList *stl)
{
- /* Clear temp objects created for display instances only. These objects are created
- * while the draw manager draw the scene, but only to hold the strokes data.
- * see: gp_instance_modifier_make_instances()
- *
- * the normal objects are not freed because they are not tagged as temp objects
- */
- for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
- Object *ob = stl->g_data->gp_object_cache[i].ob;
- if (stl->g_data->gp_object_cache[i].temp_ob) {
- MEM_SAFE_FREE(ob);
- }
- }
-
/* free the cache itself */
MEM_SAFE_FREE(stl->g_data->gp_object_cache);
}
@@ -636,7 +656,7 @@ void GPENCIL_draw_scene(void *ved)
GPENCIL_TextureList *txl = ((GPENCIL_Data *)vedata)->txl;
int init_grp, end_grp;
- tGPencilObjectCache *cache;
+ tGPencilObjectCache *cache_ob;
const float clearcol[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
const DRWContextState *draw_ctx = DRW_context_state_get();
@@ -667,7 +687,7 @@ void GPENCIL_draw_scene(void *ved)
MULTISAMPLE_GP_SYNC_DISABLE(stl->storage->multisamples, fbl, dfbl->default_fb, txl);
/* free memory */
- gpencil_free_obj_list(stl);
+ gpencil_free_obj_runtime(stl);
/* grid pass */
if ((!is_render) && (obact) && (obact->type == OB_GPENCIL)) {
@@ -699,11 +719,11 @@ void GPENCIL_draw_scene(void *ved)
sizeof(tGPencilObjectCache), gpencil_object_cache_compare_zdepth);
for (int i = 0; i < stl->g_data->gp_cache_used; i++) {
- cache = &stl->g_data->gp_object_cache[i];
- Object *ob = cache->ob;
- bGPdata *gpd = ob->data;
- init_grp = cache->init_grp;
- end_grp = cache->end_grp;
+ cache_ob = &stl->g_data->gp_object_cache[i];
+ bGPdata *gpd = cache_ob->gpd;
+ init_grp = cache_ob->init_grp;
+ end_grp = cache_ob->end_grp;
+
/* Render stroke in separated framebuffer */
GPU_framebuffer_bind(fbl->temp_fb_a);
GPU_framebuffer_clear_color_depth(fbl->temp_fb_a, clearcol, 1.0f);
@@ -724,15 +744,15 @@ void GPENCIL_draw_scene(void *ved)
}
/* Current buffer drawing */
- if ((!is_render) && (gpd->runtime.sbuffer_size > 0)) {
+ if ((!is_render) && (cache_ob->is_dup_ob == false))
+ {
DRW_draw_pass(psl->drawing_pass);
}
/* fx passes */
- if ((!stl->storage->simplify_fx) &&
- (BKE_shaderfx_has_gpencil(ob)))
+ if (cache_ob->has_fx == true)
{
stl->storage->tonemapping = 0;
- DRW_gpencil_fx_draw(&e_data, vedata, cache);
+ DRW_gpencil_fx_draw(&e_data, vedata, cache_ob);
}
e_data.input_depth_tx = e_data.temp_depth_tx_a;
@@ -754,6 +774,10 @@ void GPENCIL_draw_scene(void *ved)
if (!is_render) {
gpencil_prepare_fast_drawing(stl, dfbl, fbl, psl->mix_pass_noblend, clearcol);
}
+ else {
+ /* if render, the cache must be dirty for next loop */
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+ }
}
/* edit points */
if ((!is_render) && (!playing)) {
@@ -770,7 +794,7 @@ void GPENCIL_draw_scene(void *ved)
}
}
/* free memory */
- gpencil_free_obj_list(stl);
+ gpencil_free_obj_runtime(stl);
/* detach temp textures */
if (DRW_state_is_fbo()) {
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index 21ac6045792..40522f10b48 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -38,9 +38,6 @@ struct MaterialGPencilStyle;
struct RenderEngine;
struct RenderLayer;
- /* TODO: these could be system parameter in userprefs screen */
-#define GPENCIL_MAX_GP_OBJ 256
-
#define GPENCIL_CACHE_BLOCK_SIZE 8
#define GPENCIL_MAX_SHGROUPS 65536
#define GPENCIL_MIN_BATCH_SLOTS_CHUNK 16
@@ -59,13 +56,17 @@ struct RenderLayer;
/* *********** OBJECTS CACHE *********** */
- /* used to save gpencil objects */
+ /* used to save gpencil object data for drawing */
typedef struct tGPencilObjectCache {
- struct Object *ob;
+ struct bGPdata *gpd;
+ char ob_name[64];
int init_grp, end_grp;
int idx; /*original index, can change after sort */
/* effects */
+ bool has_fx;
+ ListBase shader_fx;
+ float pixfactor;
DRWShadingGroup *fx_wave_sh;
DRWShadingGroup *fx_blur_sh;
DRWShadingGroup *fx_colorize_sh;
@@ -75,8 +76,11 @@ typedef struct tGPencilObjectCache {
DRWShadingGroup *fx_flip_sh;
DRWShadingGroup *fx_light_sh;
+ float loc[3];
+ float obmat[4][4];
float zdepth; /* z-depth value to sort gp object */
- bool temp_ob; /* flag to tag temporary objects that must be removed after drawing loop */
+ bool is_dup_ob; /* flag to tag duplicate objects */
+ bool is_dup_onion; /* other object display onion already */
} tGPencilObjectCache;
/* *********** LISTS *********** */
@@ -108,6 +112,7 @@ typedef struct GPENCIL_Storage {
bool is_playing;
bool is_render;
bool is_mat_preview;
+ bool reset_cache;
bool buffer_stroke;
bool buffer_fill;
const float *pixsize;
@@ -191,9 +196,6 @@ typedef struct g_data {
struct DRWShadingGroup *shgrps_drawing_fill;
struct DRWShadingGroup *shgrps_grid;
- /* grid geometry */
- GPUBatch *batch_grid;
-
int gp_cache_used; /* total objects in cache */
int gp_cache_size; /* size of the cache */
struct tGPencilObjectCache *gp_object_cache;
@@ -259,6 +261,9 @@ typedef struct GPENCIL_e_data {
GPUBatch *batch_buffer_stroke;
GPUBatch *batch_buffer_fill;
+ /* grid geometry */
+ GPUBatch *batch_grid;
+
} GPENCIL_e_data; /* Engine data */
/* GPUBatch Cache */
@@ -286,35 +291,36 @@ typedef struct GpencilBatchCache {
struct DRWShadingGroup *DRW_gpencil_shgroup_stroke_create(
struct GPENCIL_e_data *e_data, struct GPENCIL_Data *vedata, struct DRWPass *pass, struct GPUShader *shader,
struct Object *ob, struct bGPdata *gpd, struct MaterialGPencilStyle *gp_style, int id, bool onion);
-void DRW_gpencil_populate_datablock(struct GPENCIL_e_data *e_data, void *vedata, struct Scene *scene, struct Object *ob, struct bGPdata *gpd);
+void DRW_gpencil_populate_datablock(struct GPENCIL_e_data *e_data, void *vedata,
+ struct Scene *scene,
+ struct Object *ob, struct tGPencilObjectCache *cache_ob);
void DRW_gpencil_populate_buffer_strokes(struct GPENCIL_e_data *e_data, void *vedata, struct ToolSettings *ts, struct Object *ob);
-void DRW_gpencil_populate_multiedit(struct GPENCIL_e_data *e_data, void *vedata, struct Scene *scene, struct Object *ob, struct bGPdata *gpd);
+void DRW_gpencil_populate_multiedit(struct GPENCIL_e_data *e_data, void *vedata,
+ struct Scene *scene, struct Object *ob, struct tGPencilObjectCache *cache_ob);
void DRW_gpencil_triangulate_stroke_fill(struct bGPDstroke *gps);
void DRW_gpencil_multisample_ensure(struct GPENCIL_Data *vedata, int rect_w, int rect_h);
/* create geometry functions */
struct GPUBatch *DRW_gpencil_get_point_geom(struct bGPDstroke *gps, short thickness, const float ink[4]);
-struct GPUBatch *DRW_gpencil_get_stroke_geom(struct bGPDframe *gpf, struct bGPDstroke *gps, short thickness, const float ink[4]);
+struct GPUBatch *DRW_gpencil_get_stroke_geom(struct bGPDstroke *gps, short thickness, const float ink[4]);
struct GPUBatch *DRW_gpencil_get_fill_geom(struct Object *ob, struct bGPDstroke *gps, const float color[4]);
struct GPUBatch *DRW_gpencil_get_edit_geom(struct bGPDstroke *gps, float alpha, short dflag);
struct GPUBatch *DRW_gpencil_get_edlin_geom(struct bGPDstroke *gps, float alpha, short dflag);
-struct GPUBatch *DRW_gpencil_get_buffer_stroke_geom(struct bGPdata *gpd, float matrix[4][4], short thickness);
+struct GPUBatch *DRW_gpencil_get_buffer_stroke_geom(struct bGPdata *gpd, short thickness);
struct GPUBatch *DRW_gpencil_get_buffer_fill_geom(struct bGPdata *gpd);
-struct GPUBatch *DRW_gpencil_get_buffer_point_geom(struct bGPdata *gpd, float matrix[4][4], short thickness);
+struct GPUBatch *DRW_gpencil_get_buffer_point_geom(struct bGPdata *gpd, short thickness);
struct GPUBatch *DRW_gpencil_get_grid(void);
/* object cache functions */
struct tGPencilObjectCache *gpencil_object_cache_add(
struct tGPencilObjectCache *cache_array, struct Object *ob,
- bool is_temp, int *gp_cache_size, int *gp_cache_used);
+ int *gp_cache_size, int *gp_cache_used);
/* geometry batch cache functions */
void gpencil_batch_cache_check_free_slots(struct Object *ob);
struct GpencilBatchCache *gpencil_batch_cache_get(struct Object *ob, int cfra);
-
-/* modifier functions */
-void gpencil_instance_modifiers(struct GPENCIL_StorageList *stl, struct Object *ob);
+struct GpencilBatchCache *gpencil_batch_get_element(struct Object *ob);
/* effects */
void GPENCIL_create_fx_shaders(struct GPENCIL_e_data *e_data);
diff --git a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
index 827f2e9344b..c3bf241baf5 100644
--- a/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
+++ b/source/blender/draw/engines/gpencil/gpencil_shader_fx.c
@@ -52,13 +52,12 @@ extern char datatoc_gpencil_fx_swirl_frag_glsl[];
extern char datatoc_gpencil_fx_wave_frag_glsl[];
/* verify if this fx is active */
-static bool effect_is_active(Object *ob, ShaderFxData *fx, bool is_render)
+static bool effect_is_active(bGPdata *gpd, ShaderFxData *fx, bool is_render)
{
if (fx == NULL) {
return false;
}
- bGPdata *gpd = ob->data;
if (gpd == NULL) {
return false;
}
@@ -161,9 +160,6 @@ static void DRW_gpencil_fx_blur(
RegionView3D *rv3d = draw_ctx->rv3d;
DRWShadingGroup *fx_shgrp;
- Object *ob = cache->ob;
- bGPdata *gpd = (bGPdata *)ob->data;
-
fxd->blur[0] = fxd->radius[0];
fxd->blur[1] = fxd->radius[1];
@@ -219,10 +215,10 @@ static void DRW_gpencil_fx_blur(
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_a);
DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &ob->loc[0], 1);
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &cache->loc[0], 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &cache->pixfactor, 1);
fxd->runtime.fx_sh = fx_shgrp;
}
@@ -291,7 +287,6 @@ static void DRW_gpencil_fx_light(
if (fx == NULL) {
return;
}
- Object *ob = cache->ob;
LightShaderFxData *fxd = (LightShaderFxData *)fx;
if (fxd->object == NULL) {
@@ -317,11 +312,11 @@ static void DRW_gpencil_fx_light(
*/
float r_point[3], r_normal[3];
float r_plane[4];
- bGPdata *gpd = (bGPdata *)ob->data;
+ bGPdata *gpd = cache->gpd;
if (!get_normal_vector(gpd, r_point, r_normal)) {
return;
}
- mul_mat3_m4_v3(ob->obmat, r_normal); /* only rotation component */
+ mul_mat3_m4_v3(cache->obmat, r_normal); /* only rotation component */
plane_from_point_normal_v3(r_plane, r_point, r_normal);
float dt = dist_to_plane_v3(fxd->object->loc, r_plane);
fxd->loc[3] = dt; /* use last element to save it */
@@ -333,7 +328,7 @@ static void DRW_gpencil_fx_light(
DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &cache->pixfactor, 1);
fxd->runtime.fx_sh = fx_shgrp;
}
@@ -346,13 +341,12 @@ static void DRW_gpencil_fx_pixel(
if (fx == NULL) {
return;
}
- Object *ob = cache->ob;
PixelShaderFxData *fxd = (PixelShaderFxData *)fx;
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
DRWShadingGroup *fx_shgrp;
- bGPdata *gpd = (bGPdata *)ob->data;
+ bGPdata *gpd = cache->gpd;
fxd->size[2] = (int)fxd->flag & FX_PIXEL_USE_LINES;
@@ -364,7 +358,7 @@ static void DRW_gpencil_fx_pixel(
DRW_shgroup_uniform_int(fx_shgrp, "size", &fxd->size[0], 3);
DRW_shgroup_uniform_vec4(fx_shgrp, "color", &fxd->rgba[0], 1);
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &ob->loc[0], 1);
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &cache->loc[0], 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
@@ -380,13 +374,11 @@ static void DRW_gpencil_fx_rim(
if (fx == NULL) {
return;
}
- Object *ob = cache->ob;
RimShaderFxData *fxd = (RimShaderFxData *)fx;
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
DRWShadingGroup *fx_shgrp;
- bGPdata *gpd = (bGPdata *)ob->data;
struct GPUBatch *fxquad = DRW_cache_fullscreen_quad_get();
/* prepare pass */
@@ -402,10 +394,10 @@ static void DRW_gpencil_fx_rim(
DRW_shgroup_uniform_vec3(fx_shgrp, "rim_color", &fxd->rim_rgb[0], 1);
DRW_shgroup_uniform_vec3(fx_shgrp, "mask_color", &fxd->mask_rgb[0], 1);
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &ob->loc[0], 1);
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &cache->loc[0], 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &cache->pixfactor, 1);
fxd->runtime.fx_sh = fx_shgrp;
@@ -418,10 +410,10 @@ static void DRW_gpencil_fx_rim(
DRW_shgroup_uniform_texture_ref(fx_shgrp, "strokeDepth", &e_data->temp_depth_tx_rim);
DRW_shgroup_uniform_int(fx_shgrp, "blur", &fxd->blur[0], 2);
- DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &ob->loc[0], 1);
+ DRW_shgroup_uniform_vec3(fx_shgrp, "loc", &cache->loc[0], 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &cache->pixfactor, 1);
fxd->runtime.fx_sh_b = fx_shgrp;
@@ -447,7 +439,6 @@ static void DRW_gpencil_fx_swirl(
if (fx == NULL) {
return;
}
- Object *ob = cache->ob;
SwirlShaderFxData *fxd = (SwirlShaderFxData *)fx;
if (fxd->object == NULL) {
return;
@@ -456,7 +447,6 @@ static void DRW_gpencil_fx_swirl(
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
DRWShadingGroup *fx_shgrp;
- bGPdata *gpd = (bGPdata *)ob->data;
fxd->transparent = (int)fxd->flag & FX_SWIRL_MAKE_TRANSPARENT;
@@ -476,7 +466,7 @@ static void DRW_gpencil_fx_swirl(
DRW_shgroup_uniform_float(fx_shgrp, "pixsize", stl->storage->pixsize, 1);
DRW_shgroup_uniform_float(fx_shgrp, "pixelsize", &U.pixelsize, 1);
- DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &gpd->pixfactor, 1);
+ DRW_shgroup_uniform_float(fx_shgrp, "pixfactor", &cache->pixfactor, 1);
fxd->runtime.fx_sh = fx_shgrp;
}
@@ -584,15 +574,14 @@ void DRW_gpencil_fx_prepare(
struct tGPencilObjectCache *cache)
{
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
- Object *ob = cache->ob;
int ob_idx = cache->idx;
- if (ob->shader_fx.first == NULL) {
+ if (cache->shader_fx.first == NULL) {
return;
}
/* loop FX */
- for (ShaderFxData *fx = ob->shader_fx.first; fx; fx = fx->next) {
- if (effect_is_active(ob, fx, stl->storage->is_render)) {
+ for (ShaderFxData *fx = cache->shader_fx.first; fx; fx = fx->next) {
+ if (effect_is_active(cache->gpd, fx, stl->storage->is_render)) {
switch (fx->type) {
case eShaderFxType_Blur:
DRW_gpencil_fx_blur(fx, ob_idx, e_data, vedata, cache);
@@ -790,12 +779,12 @@ void DRW_gpencil_fx_draw(
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl;
GPENCIL_FramebufferList *fbl = ((GPENCIL_Data *)vedata)->fbl;
- Object *ob = cache->ob;
/* loop FX modifiers */
- for (ShaderFxData *fx = ob->shader_fx.first; fx; fx = fx->next) {
- if (effect_is_active(ob, fx, stl->storage->is_render)) {
+ for (ShaderFxData *fx = cache->shader_fx.first; fx; fx = fx->next) {
+ if (effect_is_active(cache->gpd, fx, stl->storage->is_render)) {
switch (fx->type) {
+
case eShaderFxType_Blur:
{
BlurShaderFxData *fxd = (BlurShaderFxData *)fx;
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index f322e544307..7e9390e893a 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1365,6 +1365,12 @@ static int object_delete_exec(bContext *C, wmOperator *op)
continue;
}
+ /* if grease pencil object, set cache as dirty */
+ if (ob->type == OB_GPENCIL) {
+ bGPdata *gpd = (bGPdata *)ob->data;
+ DEG_id_tag_update(&gpd->id, OB_RECALC_OB | OB_RECALC_DATA);
+ }
+
/* This is sort of a quick hack to address T51243 - Proper thing to do here would be to nuke most of all this
* custom scene/object/base handling, and use generic lib remap/query for that.
* But this is for later (aka 2.8, once layers & co are settled and working).
diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c
index a35174d882f..10f96d3a22f 100644
--- a/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c
+++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c
@@ -77,7 +77,6 @@ static void initData(GpencilModifierData *md)
gpmd->rnd_rot = 0.5f;
gpmd->rnd_size = 0.5f;
gpmd->lock_axis |= GP_LOCKAXIS_X;
- gpmd->flag |= GP_INSTANCE_MAKE_OBJECTS;
/* fill random values */
BLI_array_frand(gpmd->rnd, 20, 1);
@@ -197,11 +196,10 @@ static void generate_geometry(
MEM_SAFE_FREE(valid_strokes);
}
-/* bakeModifier - "Bake to Data" Mode */
-static void bakeModifierGP_strokes(
- Depsgraph *depsgraph,
- GpencilModifierData *md, Object *ob)
+static void bakeModifier(Main *UNUSED(bmain), Depsgraph *depsgraph,
+ GpencilModifierData *md, Object *ob)
{
+
bGPdata *gpd = ob->data;
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
@@ -213,127 +211,12 @@ static void bakeModifierGP_strokes(
/* -------------------------------- */
-/* helper to create a new object */
-static Object *array_instance_add_ob_copy(Main *bmain, Scene *scene, Object *from_ob)
-{
- Object *ob;
-
- ob = BKE_object_copy(bmain, from_ob);
- BKE_collection_object_add_from(bmain, scene, from_ob, ob);
-
- zero_v3(ob->loc);
- zero_v3(ob->rot);
-
- DEG_id_type_tag(bmain, ID_OB);
- DEG_relations_tag_update(bmain);
- DEG_id_tag_update(&scene->id, 0);
-
- return ob;
-}
-
-/* bakeModifier - "Make Objects" Mode */
-static void bakeModifierGP_objects(Main *bmain, Depsgraph *depsgraph, GpencilModifierData *md, Object *ob)
-{
- InstanceGpencilModifierData *mmd = (InstanceGpencilModifierData *)md;
- Scene *scene = DEG_get_evaluated_scene(depsgraph);
- /* reset random */
- mmd->rnd[0] = 1;
-
- /* generate instances as objects */
- for (int x = 0; x < mmd->count[0]; x++) {
- for (int y = 0; y < mmd->count[1]; y++) {
- for (int z = 0; z < mmd->count[2]; z++) {
- Object *newob;
- GpencilModifierData *fmd;
-
- const int elem_idx[3] = {x, y, z};
- float mat[4][4], finalmat[4][4];
- int sh;
-
- /* original strokes are at index = 0,0,0 */
- if ((x == 0) && (y == 0) && (z == 0)) {
- continue;
- }
-
- /* compute transform for instance */
- BKE_gpencil_instance_modifier_instance_tfm(mmd, elem_idx, mat);
- mul_m4_m4m4(finalmat, ob->obmat, mat);
-
- /* moves to new origin */
- sh = x;
- if (mmd->lock_axis == GP_LOCKAXIS_Y) {
- sh = y;
- }
- if (mmd->lock_axis == GP_LOCKAXIS_Z) {
- sh = z;
- }
- madd_v3_v3fl(finalmat[3], mmd->shift, sh);
-
- /* Create a new object
- *
- * NOTE: Copies share the same original GP datablock
- * Artists can later user make_single_user on these
- * to make them unique (if necessary), without too
- * much extra memory usage.
- */
- newob = array_instance_add_ob_copy(bmain, scene, ob);
-
- /* remove array on destination object */
- fmd = (GpencilModifierData *)BLI_findstring(&newob->greasepencil_modifiers, md->name, offsetof(GpencilModifierData, name));
- if (fmd) {
- BLI_remlink(&newob->greasepencil_modifiers, fmd);
- BKE_gpencil_modifier_free(fmd);
- }
-
- /* copy transforms to destination object */
- copy_m4_m4(newob->obmat, finalmat);
-
- copy_v3_v3(newob->loc, finalmat[3]);
- mat4_to_eul(newob->rot, finalmat);
- mat4_to_size(newob->size, finalmat);
- }
- }
- }
-}
-
-/* -------------------------------- */
-
/* Generic "generateStrokes" callback */
static void generateStrokes(
GpencilModifierData *md, Depsgraph *depsgraph,
Object *ob, bGPDlayer *gpl, bGPDframe *gpf)
{
- InstanceGpencilModifierData *mmd = (InstanceGpencilModifierData *)md;
-
- /* When the "make_objects" flag is set, this modifier is handled as part of the
- * draw engine instead. The main benefit is that the instances won't suffer from
- * z-ordering problems.
- *
- * FIXME: Ultimately, the draw-engine hack here shouldn't be necessary, but until
- * we find a better fix to the z-ordering problems, it's better to have
- * working functionality
- */
- if ((mmd->flag & GP_INSTANCE_MAKE_OBJECTS) == 0) {
- generate_geometry(md, depsgraph, ob, gpl, gpf);
- }
-}
-
-/* Generic "bakeModifier" callback */
-static void bakeModifier(
- Main *bmain, Depsgraph *depsgraph,
- GpencilModifierData *md, Object *ob)
-{
- InstanceGpencilModifierData *mmd = (InstanceGpencilModifierData *)md;
-
- /* Create new objects or add all to current datablock.
- * Sometimes it's useful to have the option to do either of these...
- */
- if (mmd->flag & GP_INSTANCE_MAKE_OBJECTS) {
- bakeModifierGP_objects(bmain, depsgraph, md, ob);
- }
- else {
- bakeModifierGP_strokes(depsgraph, md, ob);
- }
+ generate_geometry(md, depsgraph, ob, gpl, gpf);
}
GpencilModifierTypeInfo modifierType_Gpencil_Instance = {
@@ -347,7 +230,7 @@ GpencilModifierTypeInfo modifierType_Gpencil_Instance = {
/* deformStroke */ NULL,
/* generateStrokes */ generateStrokes,
- /* bakeModifier */ bakeModifier,
+ /* bakeModifier */ bakeModifier,
/* initData */ initData,
/* freeData */ NULL,
diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h
index ae3621576f2..0cc7e9e40da 100644
--- a/source/blender/makesdna/DNA_gpencil_modifier_types.h
+++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h
@@ -217,7 +217,6 @@ typedef enum eInstanceGpencil_Flag {
GP_INSTANCE_RANDOM_ROT = (1 << 1),
GP_INSTANCE_INVERT_LAYER = (1 << 2),
GP_INSTANCE_INVERT_PASS = (1 << 3),
- GP_INSTANCE_MAKE_OBJECTS = (1 << 4),
} eInstanceGpencil_Flag;
typedef struct BuildGpencilModifierData {
diff --git a/source/blender/makesdna/DNA_gpencil_types.h b/source/blender/makesdna/DNA_gpencil_types.h
index 8febfbc8ffc..204b6e8741f 100644
--- a/source/blender/makesdna/DNA_gpencil_types.h
+++ b/source/blender/makesdna/DNA_gpencil_types.h
@@ -236,7 +236,7 @@ typedef enum eGPDframe_Flag {
typedef struct bGPDlayer_runtime {
struct GHash *derived_data; /* runtime data created by modifiers */
int icon_id; /* id for dynamic icon used to show annotation color preview for layer */
- char pad[4];
+ int batch_index; /* batch used for dupli instances */
} bGPDlayer_runtime;
/* Grease-Pencil Annotations - 'Layer' */
diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c
index d4252601c6a..c4d1e93a2ef 100644
--- a/source/blender/makesrna/intern/rna_gpencil_modifier.c
+++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c
@@ -928,11 +928,6 @@ static void rna_def_modifier_gpencilinstance(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Inverse Pass", "Inverse filter");
RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
- prop = RNA_def_property(srna, "use_make_objects", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_INSTANCE_MAKE_OBJECTS);
- RNA_def_property_ui_text(prop, "Make Objects",
- "When applying this modifier, instances get created as separate objects");
- RNA_def_property_update(prop, 0, "rna_GpencilModifier_update");
}
static void rna_def_modifier_gpencilbuild(BlenderRNA *brna)