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:
Diffstat (limited to 'source/blender/draw/engines/gpencil/gpencil_draw_utils.c')
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c184
1 files changed, 60 insertions, 124 deletions
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);
- }
- }
- }
- }
-}