Changeset View
Changeset View
Standalone View
Standalone View
source/blender/draw/engines/gpencil/gpencil_draw_utils.c
| Show First 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
| /* fill type to communicate to shader */ | /* fill type to communicate to shader */ | ||||
| #define SOLID 0 | #define SOLID 0 | ||||
| #define GRADIENT 1 | #define GRADIENT 1 | ||||
| #define RADIAL 2 | #define RADIAL 2 | ||||
| #define CHECKER 3 | #define CHECKER 3 | ||||
| #define TEXTURE 4 | #define TEXTURE 4 | ||||
| #define PATTERN 5 | #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 */ | /* Get number of vertex for using in GPU VBOs */ | ||||
| static void gpencil_calc_vertex(GPENCIL_StorageList *stl, | static void gpencil_calc_vertex(GPENCIL_StorageList *stl, | ||||
| tGPencilObjectCache *cache_ob, | tGPencilObjectCache *cache_ob, | ||||
| GpencilBatchCache *cache, | GpencilBatchCache *cache, | ||||
| bGPdata *gpd, | bGPdata *gpd, | ||||
| int cfra_eval) | int cfra_eval) | ||||
| { | { | ||||
| if (!cache->is_dirty) { | if (!cache->is_dirty) { | ||||
| return; | return; | ||||
| } | } | ||||
| Object *ob = cache_ob->ob; | Object *ob = cache_ob->ob; | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| const bool main_onion = draw_ctx->v3d != NULL ? | const bool main_onion = draw_ctx->v3d != NULL ? | ||||
| (draw_ctx->v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : | (draw_ctx->v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : | ||||
| true; | true; | ||||
| const bool playing = stl->storage->is_playing; | const bool playing = stl->storage->is_playing; | ||||
| const bool overlay = draw_ctx->v3d != NULL ? | const bool overlay = draw_ctx->v3d != NULL ? | ||||
| (bool)((draw_ctx->v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : | (bool)((draw_ctx->v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : | ||||
| true; | true; | ||||
| const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && overlay && | const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && overlay && | ||||
| main_onion && gpencil_onion_active(gpd) && !playing; | 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); | const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); | ||||
| cache_ob->tot_vertex = 0; | cache_ob->tot_vertex = 0; | ||||
| cache_ob->tot_triangles = 0; | cache_ob->tot_triangles = 0; | ||||
| int derived_idx = 0; | |||||
| for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { | for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { | ||||
| bGPDframe *init_gpf = NULL; | bGPDframe *init_gpf = NULL; | ||||
| const bool is_onion = ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN)); | const bool is_onion = ((do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN)); | ||||
| if (gpl->flag & GP_LAYER_HIDE) { | if (gpl->flag & GP_LAYER_HIDE) { | ||||
| derived_idx++; | |||||
| continue; | continue; | ||||
| } | } | ||||
| /* if multiedit or onion skin need to count all frames of the layer */ | /* if multiedit or onion skin need to count all frames of the layer */ | ||||
| if ((is_multiedit) || (is_onion)) { | if ((is_multiedit) || (is_onion)) { | ||||
| init_gpf = gpl->frames.first; | init_gpf = gpl->frames.first; | ||||
| } | } | ||||
| else { | else { | ||||
| /* verify time modifiers */ | init_gpf = &ob->runtime.derived_frames[derived_idx]; | ||||
| 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; | |||||
| } | |||||
| } | } | ||||
| if (init_gpf == NULL) { | if (init_gpf == NULL) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { | for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { | ||||
| for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { | for (bGPDstroke *gps = gpf->strokes.first; gps; gps = gps->next) { | ||||
| cache_ob->tot_vertex += gps->totpoints + 3; | cache_ob->tot_vertex += gps->totpoints + 3; | ||||
| cache_ob->tot_triangles += gps->totpoints - 1; | cache_ob->tot_triangles += gps->totpoints - 1; | ||||
| } | } | ||||
| if ((!is_multiedit) && (!is_onion)) { | if ((!is_multiedit) && (!is_onion)) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| derived_idx++; | |||||
| } | } | ||||
| cache->b_fill.tot_vertex = cache_ob->tot_triangles * 3; | cache->b_fill.tot_vertex = cache_ob->tot_triangles * 3; | ||||
| cache->b_stroke.tot_vertex = cache_ob->tot_vertex; | cache->b_stroke.tot_vertex = cache_ob->tot_vertex; | ||||
| cache->b_point.tot_vertex = cache_ob->tot_vertex; | cache->b_point.tot_vertex = cache_ob->tot_vertex; | ||||
| cache->b_edit.tot_vertex = cache_ob->tot_vertex; | cache->b_edit.tot_vertex = cache_ob->tot_vertex; | ||||
| cache->b_edlin.tot_vertex = cache_ob->tot_vertex; | cache->b_edlin.tot_vertex = cache_ob->tot_vertex; | ||||
| ▲ Show 20 Lines • Show All 863 Lines • ▼ Show 20 Lines | |||||
| /* main function to draw strokes */ | /* main function to draw strokes */ | ||||
| static void gpencil_draw_strokes(GpencilBatchCache *cache, | static void gpencil_draw_strokes(GpencilBatchCache *cache, | ||||
| GPENCIL_e_data *e_data, | GPENCIL_e_data *e_data, | ||||
| void *vedata, | void *vedata, | ||||
| Object *ob, | Object *ob, | ||||
| bGPdata *gpd, | bGPdata *gpd, | ||||
| bGPDlayer *gpl, | bGPDlayer *gpl, | ||||
| bGPDframe *src_gpf, | bGPDframe *gpf, | ||||
| bGPDframe *derived_gpf, | |||||
| const float opacity, | const float opacity, | ||||
| const float tintcolor[4], | const float tintcolor[4], | ||||
| const bool custonion, | const bool custonion, | ||||
| tGPencilObjectCache *cache_ob) | tGPencilObjectCache *cache_ob) | ||||
| { | { | ||||
| GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; | GPENCIL_PassList *psl = ((GPENCIL_Data *)vedata)->psl; | ||||
| GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; | GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| Scene *scene = draw_ctx->scene; | Scene *scene = draw_ctx->scene; | ||||
| View3D *v3d = draw_ctx->v3d; | View3D *v3d = draw_ctx->v3d; | ||||
| bGPDstroke *gps, *src_gps; | bGPDstroke *gps; | ||||
| const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); | const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); | ||||
| const bool playing = stl->storage->is_playing; | const bool playing = stl->storage->is_playing; | ||||
| const bool is_render = (bool)stl->storage->is_render; | const bool is_render = (bool)stl->storage->is_render; | ||||
| const bool is_mat_preview = (bool)stl->storage->is_mat_preview; | const bool is_mat_preview = (bool)stl->storage->is_mat_preview; | ||||
| const bool overlay_multiedit = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_MULTIEDIT_LINES) : true; | const bool overlay_multiedit = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_MULTIEDIT_LINES) : true; | ||||
| /* Get evaluation context */ | /* Get evaluation context */ | ||||
| /* NOTE: We must check if C is valid, otherwise we get crashes when trying to save files | /* NOTE: We must check if C is valid, otherwise we get crashes when trying to save files | ||||
| * (i.e. the thumbnail offscreen rendering fails) | * (i.e. the thumbnail offscreen rendering fails) | ||||
| */ | */ | ||||
| Depsgraph *depsgraph = DRW_context_state_get()->depsgraph; | Depsgraph *depsgraph = DRW_context_state_get()->depsgraph; | ||||
| /* get parent matrix and save as static data */ | /* get parent matrix and save as static data */ | ||||
| if ((cache_ob != NULL) && (cache_ob->is_dup_ob)) { | if ((cache_ob != NULL) && (cache_ob->is_dup_ob)) { | ||||
| copy_m4_m4(derived_gpf->runtime.parent_obmat, cache_ob->obmat); | copy_m4_m4(gpf->runtime.parent_obmat, cache_ob->obmat); | ||||
| } | } | ||||
| else { | else { | ||||
| ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, derived_gpf->runtime.parent_obmat); | ED_gpencil_parent_location(depsgraph, ob, gpd, gpl, 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; | |||||
| } | |||||
| else { | |||||
| src_gps = NULL; | |||||
| } | } | ||||
| 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); | MaterialGPencilStyle *gp_style = BKE_material_gpencil_settings_get(ob, gps->mat_nr + 1); | ||||
| /* check if stroke can be drawn */ | /* check if stroke can be drawn */ | ||||
| if (gpencil_can_draw_stroke(gp_style, gps, false, is_mat_preview) == false) { | if (gpencil_can_draw_stroke(gp_style, gps, false, is_mat_preview) == false) { | ||||
| GP_SET_SRC_GPS(src_gps); | |||||
| continue; | continue; | ||||
| } | } | ||||
| /* be sure recalc all cache 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 */ | * and improve fps */ | ||||
| if (src_gps) { | gpencil_recalc_geometry_caches( | ||||
| gpencil_recalc_geometry_caches(ob, gpl, gp_style, src_gps); | 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 | /* if the fill has any value, it's considered a fill and is not drawn if simplify fill is | ||||
| * enabled */ | * enabled */ | ||||
| if ((stl->storage->simplify_fill) && | if ((stl->storage->simplify_fill) && | ||||
| (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_REMOVE_FILL_LINE)) { | (scene->r.simplify_gpencil & SIMPLIFY_GPENCIL_REMOVE_FILL_LINE)) { | ||||
| if ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || | if ((gp_style->fill_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || | ||||
| (gp_style->fill_style > GP_STYLE_FILL_STYLE_SOLID) || | (gp_style->fill_style > GP_STYLE_FILL_STYLE_SOLID) || | ||||
| (gpl->blend_mode != eGplBlendMode_Regular)) { | (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 ) */ | continue; | ||||
| 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 */ | /* hide any blend layer */ | ||||
| if ((!stl->storage->simplify_blend) || (gpl->blend_mode == eGplBlendMode_Regular)) { | if ((!stl->storage->simplify_blend) || (gpl->blend_mode == eGplBlendMode_Regular)) { | ||||
| /* fill */ | /* fill */ | ||||
| if ((gp_style->flag & GP_STYLE_FILL_SHOW) && (!stl->storage->simplify_fill) && | if ((gp_style->flag & GP_STYLE_FILL_SHOW) && (!stl->storage->simplify_fill) && | ||||
| ((gps->flag & GP_STROKE_NOFILL) == 0)) { | ((gps->flag & GP_STROKE_NOFILL) == 0)) { | ||||
| gpencil_add_fill_vertexdata( | gpencil_add_fill_vertexdata( | ||||
| cache, ob, gpl, derived_gpf, gps, opacity, tintcolor, false, custonion); | cache, ob, gpl, gpf, gps, opacity, tintcolor, false, custonion); | ||||
| } | } | ||||
| /* stroke */ | /* stroke */ | ||||
| /* No fill strokes, must show stroke always */ | /* No fill strokes, must show stroke always */ | ||||
| if (((gp_style->flag & GP_STYLE_STROKE_SHOW) || (gps->flag & GP_STROKE_NOFILL)) && | if (((gp_style->flag & GP_STYLE_STROKE_SHOW) || (gps->flag & GP_STROKE_NOFILL)) && | ||||
| ((gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || | ((gp_style->stroke_rgba[3] > GPENCIL_ALPHA_OPACITY_THRESH) || | ||||
| (gpl->blend_mode == eGplBlendMode_Regular))) { | (gpl->blend_mode == eGplBlendMode_Regular))) { | ||||
| /* recalc strokes uv (geometry can be changed by modifiers) */ | /* recalc strokes uv (geometry can be changed by modifiers) */ | ||||
| if (gps->flag & GP_STROKE_RECALC_GEOMETRY) { | if (gps->flag & GP_STROKE_RECALC_GEOMETRY) { | ||||
| ED_gpencil_calc_stroke_uv(ob, gps); | ED_gpencil_calc_stroke_uv(ob, gps); | ||||
| } | } | ||||
| gpencil_add_stroke_vertexdata( | 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) */ | /* edit points (only in edit mode and not play animation not render) */ | ||||
| if ((draw_ctx->obact == ob) && (src_gps) && (!playing) && (!is_render) && | if ((draw_ctx->obact == ob) && (!playing) && (!is_render) && (!cache_ob->is_dup_ob)) { | ||||
| (!cache_ob->is_dup_ob)) { | |||||
| if ((gpl->flag & GP_LAYER_LOCKED) == 0) { | if ((gpl->flag & GP_LAYER_LOCKED) == 0) { | ||||
| if (!stl->g_data->shgrps_edit_line) { | if (!stl->g_data->shgrps_edit_line) { | ||||
| stl->g_data->shgrps_edit_line = DRW_shgroup_create(e_data->gpencil_line_sh, | stl->g_data->shgrps_edit_line = DRW_shgroup_create(e_data->gpencil_line_sh, | ||||
| psl->edit_pass); | psl->edit_pass); | ||||
| } | } | ||||
| if (!stl->g_data->shgrps_edit_point) { | if (!stl->g_data->shgrps_edit_point) { | ||||
| stl->g_data->shgrps_edit_point = DRW_shgroup_create(e_data->gpencil_edit_point_sh, | stl->g_data->shgrps_edit_point = DRW_shgroup_create(e_data->gpencil_edit_point_sh, | ||||
| psl->edit_pass); | psl->edit_pass); | ||||
| const float *viewport_size = DRW_viewport_size_get(); | const float *viewport_size = DRW_viewport_size_get(); | ||||
| DRW_shgroup_uniform_vec2(stl->g_data->shgrps_edit_point, "Viewport", viewport_size, 1); | 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); | |||||
| } | } | ||||
| } | } | ||||
| /* get alpha factor for onion strokes */ | /* get alpha factor for onion strokes */ | ||||
| static void gpencil_get_onion_alpha(float color[4], bGPdata *gpd) | static void gpencil_get_onion_alpha(float color[4], bGPdata *gpd) | ||||
| { | { | ||||
| #define MIN_ALPHA_VALUE 0.01f | #define MIN_ALPHA_VALUE 0.01f | ||||
| ▲ Show 20 Lines • Show All 197 Lines • ▼ Show 20 Lines | static void gpencil_draw_onionskins(GpencilBatchCache *cache, | ||||
| if ((gpd->onion_flag & GP_ONION_LOOP) && (gpf_loop != NULL)) { | if ((gpd->onion_flag & GP_ONION_LOOP) && (gpf_loop != NULL)) { | ||||
| if ((last == gpf->framenum) || (gpf->next == NULL)) { | if ((last == gpf->framenum) || (gpf->next == NULL)) { | ||||
| gpencil_get_onion_alpha(color, gpd); | gpencil_get_onion_alpha(color, gpd); | ||||
| gpencil_draw_onion_strokes(cache, vedata, ob, gpd, gpl, gpf_loop, color[3], color, colflag); | gpencil_draw_onion_strokes(cache, vedata, ob, gpd, gpl, gpf_loop, color[3], color, colflag); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| 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 | /* Triangulate stroke for high quality fill (this is done only if cache is null or stroke was | ||||
| * modified) */ | * modified) */ | ||||
| void gpencil_triangulate_stroke_fill(Object *ob, bGPDstroke *gps) | void gpencil_triangulate_stroke_fill(Object *ob, bGPDstroke *gps) | ||||
| { | { | ||||
| BLI_assert(gps->totpoints >= 3); | BLI_assert(gps->totpoints >= 3); | ||||
| bGPdata *gpd = (bGPdata *)ob->data; | bGPdata *gpd = (bGPdata *)ob->data; | ||||
| ▲ Show 20 Lines • Show All 490 Lines • ▼ Show 20 Lines | if (!playing) { | ||||
| if ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)) { | if ((gpf == gpl->actframe) || (gpf->flag & GP_FRAME_SELECT)) { | ||||
| gpencil_draw_strokes(cache, | gpencil_draw_strokes(cache, | ||||
| e_data, | e_data, | ||||
| vedata, | vedata, | ||||
| ob, | ob, | ||||
| gpd, | gpd, | ||||
| gpl, | gpl, | ||||
| gpf, | gpf, | ||||
| gpf, | |||||
| gpl->opacity, | gpl->opacity, | ||||
| gpl->tintcolor, | gpl->tintcolor, | ||||
| false, | false, | ||||
| cache_ob); | cache_ob); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV); | gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV); | ||||
| if (gpf) { | if (gpf) { | ||||
| gpencil_draw_strokes(cache, | gpencil_draw_strokes(cache, | ||||
| e_data, | e_data, | ||||
| vedata, | vedata, | ||||
| ob, | ob, | ||||
| gpd, | gpd, | ||||
| gpl, | gpl, | ||||
| gpf, | gpf, | ||||
| gpf, | |||||
| gpl->opacity, | gpl->opacity, | ||||
| gpl->tintcolor, | gpl->tintcolor, | ||||
| false, | false, | ||||
| cache_ob); | cache_ob); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* create batchs and shading groups */ | /* create batchs and shading groups */ | ||||
| gpencil_create_batches(cache); | gpencil_create_batches(cache); | ||||
| gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob); | gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob); | ||||
| cache->is_dirty = false; | 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 */ | /* helper for populate a complete grease pencil datablock */ | ||||
| void gpencil_populate_datablock(GPENCIL_e_data *e_data, | void gpencil_populate_datablock(GPENCIL_e_data *e_data, | ||||
| void *vedata, | void *vedata, | ||||
| Object *ob, | Object *ob, | ||||
| tGPencilObjectCache *cache_ob) | tGPencilObjectCache *cache_ob) | ||||
| { | { | ||||
| GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; | GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl; | ||||
| const DRWContextState *draw_ctx = DRW_context_state_get(); | const DRWContextState *draw_ctx = DRW_context_state_get(); | ||||
| const ViewLayer *view_layer = DEG_get_evaluated_view_layer(draw_ctx->depsgraph); | const ViewLayer *view_layer = DEG_get_evaluated_view_layer(draw_ctx->depsgraph); | ||||
| Scene *scene = draw_ctx->scene; | 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; | View3D *v3d = draw_ctx->v3d; | ||||
| int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph); | int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph); | ||||
| bGPDframe *derived_gpf = NULL; | bGPDframe *derived_gpf = NULL; | ||||
| const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true; | const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_HIDE_OVERLAYS) == 0) : true; | ||||
| const bool time_remap = BKE_gpencil_has_time_modifiers(ob); | const bool time_remap = BKE_gpencil_has_time_modifiers(ob); | ||||
| Show All 10 Lines | void gpencil_populate_datablock(GPENCIL_e_data *e_data, | ||||
| if (cache_ob->is_dup_ob) { | if (cache_ob->is_dup_ob) { | ||||
| gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob); | gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob); | ||||
| return; | return; | ||||
| } | } | ||||
| /* calc max size of VBOs */ | /* calc max size of VBOs */ | ||||
| gpencil_calc_vertex(stl, cache_ob, cache, gpd, cfra_eval); | 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 */ | /* draw normal strokes */ | ||||
| for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { | for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { | ||||
| /* don't draw layer if hidden */ | /* don't draw layer if hidden */ | ||||
| if (gpl->flag & GP_LAYER_HIDE) { | if (gpl->flag & GP_LAYER_HIDE) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| const bool is_solomode = GPENCIL_PAINT_MODE(gpd) && (!playing) && (!stl->storage->is_render) && | const bool is_solomode = GPENCIL_PAINT_MODE(gpd) && (!playing) && (!stl->storage->is_render) && | ||||
| Show All 31 Lines | for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { | ||||
| } | } | ||||
| /* fade no active layers */ | /* fade no active layers */ | ||||
| if ((overlay) && (draw_ctx->object_mode == OB_MODE_PAINT_GPENCIL) && | if ((overlay) && (draw_ctx->object_mode == OB_MODE_PAINT_GPENCIL) && | ||||
| (v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS) && (draw_ctx->obact) && | (v3d->gp_flag & V3D_GP_FADE_NOACTIVE_LAYERS) && (draw_ctx->obact) && | ||||
| (draw_ctx->obact == ob) && (gpl != gpl_active)) { | (draw_ctx->obact == ob) && (gpl != gpl_active)) { | ||||
| opacity = opacity * v3d->overlay.gpencil_fade_layer; | opacity = opacity * v3d->overlay.gpencil_fade_layer; | ||||
| } | } | ||||
| /* create derived frames array data or expand */ | /* Get derived frames array data */ | ||||
| gpencil_ensure_derived_frame(gpd, gpl, gpf, cache, &derived_gpf); | int derived_idx = BLI_findindex(&gpd->layers, gpl); | ||||
| derived_gpf = &ob->runtime.derived_frames[derived_idx]; | |||||
| /* draw onion skins */ | /* draw onion skins */ | ||||
| if (!ID_IS_LINKED(&gpd->id)) { | if (!ID_IS_LINKED(&gpd->id)) { | ||||
| if ((gpl->onion_flag & GP_LAYER_ONIONSKIN) && | if ((gpl->onion_flag & GP_LAYER_ONIONSKIN) && | ||||
| ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)) && (!cache_ob->is_dup_ob) && | ((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)) && (!cache_ob->is_dup_ob) && | ||||
| (gpd->id.us <= 1)) { | (gpd->id.us <= 1)) { | ||||
| if ((!stl->storage->is_render) || | if ((!stl->storage->is_render) || | ||||
| ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) { | ((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS))) { | ||||
| gpencil_draw_onionskins(cache, vedata, ob, gpd, gpl, gpf); | gpencil_draw_onionskins(cache, vedata, ob, gpd, gpl, gpf); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* draw normal strokes */ | /* draw normal strokes */ | ||||
| gpencil_draw_strokes(cache, | gpencil_draw_strokes(cache, | ||||
| e_data, | e_data, | ||||
| vedata, | vedata, | ||||
| ob, | ob, | ||||
| gpd, | gpd, | ||||
| gpl, | gpl, | ||||
| gpf, | |||||
| derived_gpf, | derived_gpf, | ||||
| opacity, | opacity, | ||||
| gpl->tintcolor, | gpl->tintcolor, | ||||
| false, | false, | ||||
| cache_ob); | cache_ob); | ||||
| } | } | ||||
| /* clear any lattice data */ | |||||
| if ((cache->is_dirty) && (ob->greasepencil_modifiers.first)) { | |||||
| BKE_gpencil_lattice_clear(ob); | |||||
| } | |||||
| /* create batchs and shading groups */ | /* create batchs and shading groups */ | ||||
| gpencil_create_batches(cache); | gpencil_create_batches(cache); | ||||
| gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob); | gpencil_shgroups_create(e_data, vedata, ob, cache, cache_ob); | ||||
| cache->is_dirty = false; | cache->is_dirty = false; | ||||
| } | } | ||||
| void gpencil_populate_particles(GPENCIL_e_data *e_data, GHash *gh_objects, void *vedata) | void gpencil_populate_particles(GPENCIL_e_data *e_data, GHash *gh_objects, void *vedata) | ||||
| Show All 21 Lines | |||||