From 9898a71d030c93fe602f9ce1cbdfdbbafca0d8a3 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Wed, 3 May 2023 13:20:28 +0200 Subject: [PATCH 01/16] overlay boilerplate --- scripts/startup/bl_ui/space_view3d.py | 2 +- source/blender/draw/CMakeLists.txt | 3 ++ .../draw/engines/overlay/overlay_engine.cc | 8 +++++ .../engines/overlay/overlay_onion_skin.cc | 31 +++++++++++++++++++ .../draw/engines/overlay/overlay_private.hh | 8 +++++ .../draw/engines/overlay/overlay_shader.cc | 11 +++++++ .../shaders/infos/overlay_extra_info.hh | 17 ++++++++++ .../shaders/overlay_onion_skin_mesh_frag.glsl | 4 +++ .../shaders/overlay_onion_skin_mesh_vert.glsl | 11 +++++++ 9 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 source/blender/draw/engines/overlay/overlay_onion_skin.cc create mode 100644 source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_frag.glsl create mode 100644 source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_vert.glsl diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index 81c1fe5f159..60c3ba23b86 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -6523,7 +6523,7 @@ class VIEW3D_PT_overlay_geometry(Panel): col.prop(overlay, "show_face_orientation") - # sub.prop(overlay, "show_onion_skins") + sub.prop(overlay, "show_onion_skins") class VIEW3D_PT_overlay_motion_tracking(Panel): diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt index 3309364c074..19e97db787e 100644 --- a/source/blender/draw/CMakeLists.txt +++ b/source/blender/draw/CMakeLists.txt @@ -219,6 +219,7 @@ set(SRC engines/overlay/overlay_viewer_attribute.cc engines/overlay/overlay_volume.cc engines/overlay/overlay_wireframe.cc + engines/overlay/overlay_onion_skin.cc DRW_engine.h DRW_pbvh.hh @@ -685,6 +686,8 @@ set(GLSL_SRC engines/overlay/shaders/overlay_motion_path_line_vert.glsl engines/overlay/shaders/overlay_motion_path_line_vert_no_geom.glsl engines/overlay/shaders/overlay_motion_path_point_vert.glsl + engines/overlay/shaders/overlay_onion_skin_mesh_frag.glsl + engines/overlay/shaders/overlay_onion_skin_mesh_vert.glsl engines/overlay/shaders/overlay_outline_detect_frag.glsl engines/overlay/shaders/overlay_outline_prepass_curves_vert.glsl engines/overlay/shaders/overlay_outline_prepass_frag.glsl diff --git a/source/blender/draw/engines/overlay/overlay_engine.cc b/source/blender/draw/engines/overlay/overlay_engine.cc index 0fcfc76e5ca..35aebd39b0e 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.cc +++ b/source/blender/draw/engines/overlay/overlay_engine.cc @@ -216,10 +216,12 @@ static void OVERLAY_cache_init(void *vedata) OVERLAY_image_cache_init(data); OVERLAY_metaball_cache_init(data); OVERLAY_motion_path_cache_init(data); + OVERLAY_onion_skin_init(data); OVERLAY_outline_cache_init(data); OVERLAY_particle_cache_init(data); OVERLAY_wireframe_cache_init(data); OVERLAY_volume_cache_init(data); + OVERLAY_onion_skin_init(data); } BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bool *do_init) @@ -357,6 +359,8 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) const bool draw_motion_paths = (pd->overlay.flag & V3D_OVERLAY_HIDE_MOTION_PATHS) == 0; + const bool draw_onion_skins = pd->overlay.flag & V3D_OVERLAY_ONION_SKINS; + bool do_init; OVERLAY_DupliData *dupli = OVERLAY_duplidata_get(ob, vedata, &do_init); @@ -378,6 +382,9 @@ static void OVERLAY_cache_populate(void *vedata, Object *ob) if (draw_bone_selection) { OVERLAY_pose_cache_populate(data, ob); } + if (draw_onion_skins) { + OVERLAY_onion_skin_populate(data, ob); + } if (pd->overlay.flag & V3D_OVERLAY_VIEWER_ATTRIBUTE) { if (is_preview) { @@ -678,6 +685,7 @@ static void OVERLAY_draw_scene(void *vedata) OVERLAY_image_in_front_draw(data); OVERLAY_motion_path_draw(data); + OVERLAY_onion_skin_draw(data); OVERLAY_extra_centers_draw(data); if (DRW_state_is_select() || DRW_state_is_depth()) { diff --git a/source/blender/draw/engines/overlay/overlay_onion_skin.cc b/source/blender/draw/engines/overlay/overlay_onion_skin.cc new file mode 100644 index 00000000000..7bc672b6d05 --- /dev/null +++ b/source/blender/draw/engines/overlay/overlay_onion_skin.cc @@ -0,0 +1,31 @@ +#include "DRW_render.h" +#include "overlay_private.hh" + +void OVERLAY_onion_skin_init(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + OVERLAY_PrivateData *pd = vedata->stl->pd; + + DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA; + DRW_PASS_CREATE(psl->onion_skin_ps, state | pd->clipping_state); + + GPUShader *shader = OVERLAY_shader_onion_skin_mesh(); + DRWShadingGroup *grp; + pd->onion_skin_grp = grp = DRW_shgroup_create(shader, psl->onion_skin_ps); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); +} + +void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) +{ + OVERLAY_PrivateData *pd = vedata->stl->pd; + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); + if (geom) { + DRW_shgroup_call(pd->onion_skin_grp, geom, ob); + } +} + +void OVERLAY_onion_skin_draw(OVERLAY_Data *vedata) +{ + OVERLAY_PassList *psl = vedata->psl; + DRW_draw_pass(psl->onion_skin_ps); +} \ No newline at end of file diff --git a/source/blender/draw/engines/overlay/overlay_private.hh b/source/blender/draw/engines/overlay/overlay_private.hh index 6c6e5cc7fbd..7825baa1dee 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -110,6 +110,7 @@ typedef struct OVERLAY_PassList { DRWPass *image_foreground_scene_ps; DRWPass *metaball_ps[2]; DRWPass *motion_paths_ps; + DRWPass *onion_skin_ps; DRWPass *outlines_prepass_ps; DRWPass *outlines_detect_ps; DRWPass *outlines_resolve_ps; @@ -276,6 +277,7 @@ typedef struct OVERLAY_PrivateData { DRWShadingGroup *flash_grp[2]; DRWShadingGroup *motion_path_lines_grp; DRWShadingGroup *motion_path_points_grp; + DRWShadingGroup *onion_skin_grp; DRWShadingGroup *outlines_grp; DRWShadingGroup *outlines_curves_grp; DRWShadingGroup *outlines_ptcloud_grp; @@ -649,6 +651,7 @@ void OVERLAY_image_empty_cache_populate(OVERLAY_Data *vedata, Object *ob); void OVERLAY_image_cache_finish(OVERLAY_Data *vedata); void OVERLAY_image_draw(OVERLAY_Data *vedata); void OVERLAY_image_background_draw(OVERLAY_Data *vedata); + /** * This function draws images that needs the view transform applied. * It draws these images directly into the scene color buffer. @@ -666,6 +669,10 @@ void OVERLAY_motion_path_cache_init(OVERLAY_Data *vedata); void OVERLAY_motion_path_cache_populate(OVERLAY_Data *vedata, Object *ob); void OVERLAY_motion_path_draw(OVERLAY_Data *vedata); +void OVERLAY_onion_skin_init(OVERLAY_Data *vedata); +void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob); +void OVERLAY_onion_skin_draw(OVERLAY_Data *vedata); + void OVERLAY_outline_init(OVERLAY_Data *vedata); void OVERLAY_outline_cache_init(OVERLAY_Data *vedata); void OVERLAY_outline_cache_populate(OVERLAY_Data *vedata, @@ -765,6 +772,7 @@ GPUShader *OVERLAY_shader_grid_image(void); GPUShader *OVERLAY_shader_image(void); GPUShader *OVERLAY_shader_motion_path_line(void); GPUShader *OVERLAY_shader_motion_path_vert(void); +GPUShader *OVERLAY_shader_onion_skin_mesh(void); GPUShader *OVERLAY_shader_uniform_color(void); GPUShader *OVERLAY_shader_uniform_color_pointcloud(void); GPUShader *OVERLAY_shader_outline_prepass(bool use_wire); diff --git a/source/blender/draw/engines/overlay/overlay_shader.cc b/source/blender/draw/engines/overlay/overlay_shader.cc index f549a66a537..4fab971516b 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.cc +++ b/source/blender/draw/engines/overlay/overlay_shader.cc @@ -76,6 +76,7 @@ struct OVERLAY_Shaders { GPUShader *image; GPUShader *motion_path_line; GPUShader *motion_path_vert; + GPUShader *onion_skin_mesh; GPUShader *outline_prepass; GPUShader *outline_prepass_curves; GPUShader *outline_prepass_gpencil; @@ -683,6 +684,16 @@ GPUShader *OVERLAY_shader_motion_path_vert(void) return sh_data->motion_path_vert; } +GPUShader *OVERLAY_shader_onion_skin_mesh(void) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; + if (!sh_data->onion_skin_mesh) { + sh_data->onion_skin_mesh = GPU_shader_create_from_info_name("overlay_onion_skin_mesh"); + } + return sh_data->onion_skin_mesh; +} + GPUShader *OVERLAY_shader_outline_prepass(bool use_wire) { const DRWContextState *draw_ctx = DRW_context_state_get(); diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh index 9e6b6e5f737..a422734f0b5 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh @@ -247,6 +247,23 @@ GPU_SHADER_CREATE_INFO(overlay_motion_path_point_clipped) /** \} */ +/* -------------------------------------------------------------------- */ +/** \name Onion Skin + * \{ */ + +GPU_SHADER_INTERFACE_INFO(onion_skin_iface, "interp").smooth(Type::VEC4, "color"); + +GPU_SHADER_CREATE_INFO(overlay_onion_skin_mesh) + .do_static_compilation(true) + .vertex_in(0, Type::VEC3, "pos") + .vertex_out(onion_skin_iface) + .fragment_out(0, Type::VEC4, "fragColor") + .fragment_source("overlay_onion_skin_mesh_frag.glsl") + .vertex_source("overlay_onion_skin_mesh_vert.glsl") + .additional_info("draw_mesh", "draw_globals"); + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Image Empty * \{ */ diff --git a/source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_frag.glsl b/source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_frag.glsl new file mode 100644 index 00000000000..dcf65b15cdf --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_frag.glsl @@ -0,0 +1,4 @@ +void main() +{ + fragColor = interp.color; +} \ No newline at end of file diff --git a/source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_vert.glsl new file mode 100644 index 00000000000..95bef155ba0 --- /dev/null +++ b/source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_vert.glsl @@ -0,0 +1,11 @@ +#pragma BLENDER_REQUIRE(common_view_clipping_lib.glsl) +#pragma BLENDER_REQUIRE(common_view_lib.glsl) + +void main() +{ + interp.color.rgb = vec3(1, 0, 1); + interp.color.a = 0.5f; + vec3 world_pos = point_object_to_world(pos); + gl_Position = point_world_to_ndc(world_pos); + /* view_clipping_distances(world_pos); */ +} \ No newline at end of file -- 2.30.2 From 23b6819fe4f802c5dd8fe2eab213bb1c011f2df8 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Wed, 3 May 2023 16:16:29 +0200 Subject: [PATCH 02/16] cpolor and alpha shader inputs --- source/blender/draw/engines/overlay/overlay_onion_skin.cc | 7 +++++++ .../engines/overlay/shaders/infos/overlay_extra_info.hh | 2 ++ .../overlay/shaders/overlay_onion_skin_mesh_vert.glsl | 4 ++-- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_onion_skin.cc b/source/blender/draw/engines/overlay/overlay_onion_skin.cc index 7bc672b6d05..c4c474bc573 100644 --- a/source/blender/draw/engines/overlay/overlay_onion_skin.cc +++ b/source/blender/draw/engines/overlay/overlay_onion_skin.cc @@ -12,12 +12,19 @@ void OVERLAY_onion_skin_init(OVERLAY_Data *vedata) GPUShader *shader = OVERLAY_shader_onion_skin_mesh(); DRWShadingGroup *grp; pd->onion_skin_grp = grp = DRW_shgroup_create(shader, psl->onion_skin_ps); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); } void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) { OVERLAY_PrivateData *pd = vedata->stl->pd; + DRWShadingGroup *grp = pd->onion_skin_grp; + + float color[3] = {1, 1, 0}; + DRW_shgroup_uniform_vec3_copy(grp, "color", color); + DRW_shgroup_uniform_float_copy(grp, "alpha", 0.2f); + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { DRW_shgroup_call(pd->onion_skin_grp, geom, ob); diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh index a422734f0b5..e6d1fb53422 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh @@ -257,6 +257,8 @@ GPU_SHADER_CREATE_INFO(overlay_onion_skin_mesh) .do_static_compilation(true) .vertex_in(0, Type::VEC3, "pos") .vertex_out(onion_skin_iface) + .push_constant(Type::VEC3, "color") + .push_constant(Type::FLOAT, "alpha") .fragment_out(0, Type::VEC4, "fragColor") .fragment_source("overlay_onion_skin_mesh_frag.glsl") .vertex_source("overlay_onion_skin_mesh_vert.glsl") diff --git a/source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_vert.glsl b/source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_vert.glsl index 95bef155ba0..beeead0b6b9 100644 --- a/source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_vert.glsl +++ b/source/blender/draw/engines/overlay/shaders/overlay_onion_skin_mesh_vert.glsl @@ -3,8 +3,8 @@ void main() { - interp.color.rgb = vec3(1, 0, 1); - interp.color.a = 0.5f; + interp.color.rgb = color; + interp.color.a = alpha; vec3 world_pos = point_object_to_world(pos); gl_Position = point_world_to_ndc(world_pos); /* view_clipping_distances(world_pos); */ -- 2.30.2 From 3a439111f9562c01bc2b14d82ee84b60a2d440d1 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 4 May 2023 09:40:48 +0200 Subject: [PATCH 03/16] operators wip --- .../editors/animation/anim_onion_skin.c | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 source/blender/editors/animation/anim_onion_skin.c diff --git a/source/blender/editors/animation/anim_onion_skin.c b/source/blender/editors/animation/anim_onion_skin.c new file mode 100644 index 00000000000..e015b08f6ab --- /dev/null +++ b/source/blender/editors/animation/anim_onion_skin.c @@ -0,0 +1,41 @@ +#include "BKE_context.h" +#include "DNA_scene_types.h" +#include "DNA_windowmanager_types.h" + +#include "ED_onion_skin.h" +#include "MEM_guardedalloc.h" +#include "WM_types.h" + +static void add_exec(bContext *C, wmOperator *op) +{ + Object *ob = CTX_data_active_object(C); + ListBase selected = {NULL, NULL}; + CTX_data_selected_objects(C, &selected); + Scene *scene = CTX_data_scene(C); + + BLI_freelistN(&selected); +} + +static void ANIM_OT_onion_skin_add(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Add Onion Skin"; + ot->description = "foobar"; + ot->idname = "ANIM_OT_onion_skin_add"; + + /* api callbacks */ + ot->exec = add_exec; + /* ot->cancel = WM_gesture_box_cancel; */ + + /* ot->poll = ed_markers_poll_markers_exist; */ + + /* flags */ + ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER; + + /* properties */ +} + +ED_operatortypes_onion_skin(void) +{ + WM_operatortype_append(ANIM_OT_onion_skin_add); +} -- 2.30.2 From 8fea5f23dc49906ee36c2104cd16e7c035576325 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 4 May 2023 09:41:10 +0200 Subject: [PATCH 04/16] operators wip --- source/blender/draw/engines/overlay/overlay_onion_skin.cc | 2 ++ source/blender/editors/animation/CMakeLists.txt | 1 + source/blender/editors/include/ED_onion_skin.h | 2 ++ source/blender/editors/space_api/spacetypes.c | 2 ++ source/blender/makesdna/DNA_scene_types.h | 6 ++++++ 5 files changed, 13 insertions(+) create mode 100644 source/blender/editors/include/ED_onion_skin.h diff --git a/source/blender/draw/engines/overlay/overlay_onion_skin.cc b/source/blender/draw/engines/overlay/overlay_onion_skin.cc index c4c474bc573..4fcc87fe9be 100644 --- a/source/blender/draw/engines/overlay/overlay_onion_skin.cc +++ b/source/blender/draw/engines/overlay/overlay_onion_skin.cc @@ -21,6 +21,8 @@ void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) OVERLAY_PrivateData *pd = vedata->stl->pd; DRWShadingGroup *grp = pd->onion_skin_grp; + const DRWContextState *draw_ctx = DRW_context_state_get(); + float color[3] = {1, 1, 0}; DRW_shgroup_uniform_vec3_copy(grp, "color", color); DRW_shgroup_uniform_float_copy(grp, "alpha", 0.2f); diff --git a/source/blender/editors/animation/CMakeLists.txt b/source/blender/editors/animation/CMakeLists.txt index 66db6eb7924..2d3e76fd863 100644 --- a/source/blender/editors/animation/CMakeLists.txt +++ b/source/blender/editors/animation/CMakeLists.txt @@ -29,6 +29,7 @@ set(SRC anim_ipo_utils.c anim_markers.c anim_motion_paths.c + anim_onion_skin.c anim_ops.c drivers.c fmodifier_ui.c diff --git a/source/blender/editors/include/ED_onion_skin.h b/source/blender/editors/include/ED_onion_skin.h new file mode 100644 index 00000000000..cabf3095c58 --- /dev/null +++ b/source/blender/editors/include/ED_onion_skin.h @@ -0,0 +1,2 @@ + +void ED_operatortypes_onion_skin(void); diff --git a/source/blender/editors/space_api/spacetypes.c b/source/blender/editors/space_api/spacetypes.c index 56aa0104329..76bfb15cebf 100644 --- a/source/blender/editors/space_api/spacetypes.c +++ b/source/blender/editors/space_api/spacetypes.c @@ -41,6 +41,7 @@ #include "ED_mesh.h" #include "ED_node.h" #include "ED_object.h" +#include "ED_onion_skin.h" #include "ED_paint.h" #include "ED_physics.h" #include "ED_render.h" @@ -105,6 +106,7 @@ void ED_spacetypes_init(void) ED_operatortypes_curves(); ED_operatortypes_armature(); ED_operatortypes_marker(); + ED_operatortypes_onion_skin(); ED_operatortypes_metaball(); ED_operatortypes_sound(); ED_operatortypes_render(); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 81ea41a52d2..875a865cdab 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1875,6 +1875,11 @@ enum { /** \name Scene ID-Block * \{ */ +typedef struct SceneOnionSkin { + SceneOnionSkin *prev, *next; + Mesh *mesh; +} SceneOnionSkin; + typedef struct Scene { ID id; /** Animation data (must be immediately after id for utilities to use it). */ @@ -1994,6 +1999,7 @@ typedef struct Scene { struct SceneDisplay display; struct SceneEEVEE eevee; struct SceneGpencil grease_pencil_settings; + struct ListBase onion_skin_cache /* SceneOnionSkin */; } Scene; /** \} */ -- 2.30.2 From f5fcc5dd0f23346bcdf2c047308d67c1cee03bf9 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Fri, 5 May 2023 10:14:59 +0200 Subject: [PATCH 05/16] wip --- .../draw/engines/overlay/overlay_engine.cc | 3 +-- .../editors/animation/anim_onion_skin.c | 18 +++++++++++++----- source/blender/makesdna/DNA_scene_types.h | 13 ++++++++++--- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_engine.cc b/source/blender/draw/engines/overlay/overlay_engine.cc index 35aebd39b0e..880354b88ec 100644 --- a/source/blender/draw/engines/overlay/overlay_engine.cc +++ b/source/blender/draw/engines/overlay/overlay_engine.cc @@ -129,6 +129,7 @@ static void OVERLAY_engine_init(void *vedata) OVERLAY_outline_init(data); OVERLAY_wireframe_init(data); OVERLAY_paint_init(data); + OVERLAY_onion_skin_init(data); } static void OVERLAY_cache_init(void *vedata) @@ -216,12 +217,10 @@ static void OVERLAY_cache_init(void *vedata) OVERLAY_image_cache_init(data); OVERLAY_metaball_cache_init(data); OVERLAY_motion_path_cache_init(data); - OVERLAY_onion_skin_init(data); OVERLAY_outline_cache_init(data); OVERLAY_particle_cache_init(data); OVERLAY_wireframe_cache_init(data); OVERLAY_volume_cache_init(data); - OVERLAY_onion_skin_init(data); } BLI_INLINE OVERLAY_DupliData *OVERLAY_duplidata_get(Object *ob, void *vedata, bool *do_init) diff --git a/source/blender/editors/animation/anim_onion_skin.c b/source/blender/editors/animation/anim_onion_skin.c index e015b08f6ab..0bd56374ab2 100644 --- a/source/blender/editors/animation/anim_onion_skin.c +++ b/source/blender/editors/animation/anim_onion_skin.c @@ -4,16 +4,24 @@ #include "ED_onion_skin.h" #include "MEM_guardedalloc.h" +#include "WM_api.h" #include "WM_types.h" -static void add_exec(bContext *C, wmOperator *op) +static int onion_skin_add_exec(bContext *C, wmOperator *op) { - Object *ob = CTX_data_active_object(C); ListBase selected = {NULL, NULL}; CTX_data_selected_objects(C, &selected); Scene *scene = CTX_data_scene(C); - + + LISTBASE_FOREACH (Object *, ob, &selected) { + /* Mesh *mesh; */ + OnionSkinMesh *link = MEM_callocN(sizeof(OnionSkinMesh), "onion skin mesh link"); + /* link->mesh = mesh; */ + BLI_addtail(&scene->onion_skin_cache.meshes, link); + } + BLI_freelistN(&selected); + return OPERATOR_FINISHED; } static void ANIM_OT_onion_skin_add(wmOperatorType *ot) @@ -24,7 +32,7 @@ static void ANIM_OT_onion_skin_add(wmOperatorType *ot) ot->idname = "ANIM_OT_onion_skin_add"; /* api callbacks */ - ot->exec = add_exec; + ot->exec = onion_skin_add_exec; /* ot->cancel = WM_gesture_box_cancel; */ /* ot->poll = ed_markers_poll_markers_exist; */ @@ -35,7 +43,7 @@ static void ANIM_OT_onion_skin_add(wmOperatorType *ot) /* properties */ } -ED_operatortypes_onion_skin(void) +void ED_operatortypes_onion_skin(void) { WM_operatortype_append(ANIM_OT_onion_skin_add); } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 4f385a3630e..d45ebfcdffa 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -23,6 +23,7 @@ #include "DNA_customdata_types.h" /* Scene's runtime custom-data masks. */ #include "DNA_layer_types.h" #include "DNA_listBase.h" +#include "DNA_mesh_types.h" #include "DNA_vec_types.h" #include "DNA_view3d_types.h" @@ -1875,9 +1876,15 @@ enum { /** \name Scene ID-Block * \{ */ -typedef struct SceneOnionSkin { - SceneOnionSkin *prev, *next; +typedef struct OnionSkinMesh { + struct OnionSkinMesh *prev, *next; Mesh *mesh; +} OnionSkinMesh; + +typedef struct SceneOnionSkin { + float color[3]; + float alpha; + ListBase meshes /* OnionSkinMesh */; } SceneOnionSkin; typedef struct Scene { @@ -1999,7 +2006,7 @@ typedef struct Scene { struct SceneDisplay display; struct SceneEEVEE eevee; struct SceneGpencil grease_pencil_settings; - struct ListBase onion_skin_cache /* SceneOnionSkin */; + struct SceneOnionSkin onion_skin_cache; } Scene; /** \} */ -- 2.30.2 From 9d0717ba70b463e872a365996884666ce8a2b69b Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Fri, 5 May 2023 10:49:32 +0200 Subject: [PATCH 06/16] fix --- source/blender/makesdna/DNA_scene_types.h | 24 +++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index d45ebfcdffa..bcea007f15c 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -23,7 +23,6 @@ #include "DNA_customdata_types.h" /* Scene's runtime custom-data masks. */ #include "DNA_layer_types.h" #include "DNA_listBase.h" -#include "DNA_mesh_types.h" #include "DNA_vec_types.h" #include "DNA_view3d_types.h" @@ -1849,6 +1848,18 @@ typedef struct SceneGpencil { char _pad[4]; } SceneGpencil; +typedef struct OnionSkinMesh { + struct OnionSkinMesh *prev, *next; + /* Having a Mesh pointer here breaks compilation. Complains about "extern C" issues. */ + void *mesh; +} OnionSkinMesh; + +typedef struct SceneOnionSkin { + float color[3]; + float alpha; + ListBase meshes /* OnionSkinMesh */; +} SceneOnionSkin; + /** \} */ /* -------------------------------------------------------------------- */ @@ -1876,17 +1887,6 @@ enum { /** \name Scene ID-Block * \{ */ -typedef struct OnionSkinMesh { - struct OnionSkinMesh *prev, *next; - Mesh *mesh; -} OnionSkinMesh; - -typedef struct SceneOnionSkin { - float color[3]; - float alpha; - ListBase meshes /* OnionSkinMesh */; -} SceneOnionSkin; - typedef struct Scene { ID id; /** Animation data (must be immediately after id for utilities to use it). */ -- 2.30.2 From 18d660da732d34cc3f4987cc54c7c096d66b5a13 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Fri, 5 May 2023 12:44:18 +0200 Subject: [PATCH 07/16] scene props --- scripts/startup/bl_ui/properties_render.py | 25 ++++++++++++ .../engines/overlay/overlay_onion_skin.cc | 12 ++++-- .../editors/animation/anim_onion_skin.c | 38 ++++++++++++++----- source/blender/makesdna/DNA_scene_types.h | 8 ++-- source/blender/makesrna/intern/rna_scene.c | 15 ++++++++ source/blender/makesrna/intern/rna_space.c | 6 ++- 6 files changed, 85 insertions(+), 19 deletions(-) diff --git a/scripts/startup/bl_ui/properties_render.py b/scripts/startup/bl_ui/properties_render.py index bf3c322f377..8f9bdac9a28 100644 --- a/scripts/startup/bl_ui/properties_render.py +++ b/scripts/startup/bl_ui/properties_render.py @@ -715,6 +715,29 @@ class RENDER_PT_gpencil(RenderButtonsPanel, Panel): col.prop(props, "antialias_threshold") +class RENDER_PT_onion_skins(RenderButtonsPanel, Panel): + bl_label = "Onion Skins" + bl_options = {'DEFAULT_CLOSED'} + bl_order = 10 + COMPAT_ENGINES = { + 'BLENDER_RENDER', + 'BLENDER_EEVEE', + 'BLENDER_EEVEE_NEXT', + 'BLENDER_WORKBENCH', + 'BLENDER_WORKBENCH_NEXT'} + + def draw(self, context): + layout = self.layout + # layout.use_property_split = True + # layout.use_property_decorate = False # No animation. + + scene = context.scene + + col = layout.column() + col.prop(scene, "onion_skin_color") + col.prop(scene, "onion_skin_alpha") + + class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel): bl_label = "Sampling" COMPAT_ENGINES = {'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'} @@ -921,6 +944,8 @@ classes = ( RENDER_PT_simplify_viewport, RENDER_PT_simplify_render, RENDER_PT_simplify_greasepencil, + + RENDER_PT_onion_skins, ) if __name__ == "__main__": # only for live edit. diff --git a/source/blender/draw/engines/overlay/overlay_onion_skin.cc b/source/blender/draw/engines/overlay/overlay_onion_skin.cc index 4fcc87fe9be..ac645926418 100644 --- a/source/blender/draw/engines/overlay/overlay_onion_skin.cc +++ b/source/blender/draw/engines/overlay/overlay_onion_skin.cc @@ -1,4 +1,5 @@ #include "DRW_render.h" +#include "draw_cache_impl.h" #include "overlay_private.hh" void OVERLAY_onion_skin_init(OVERLAY_Data *vedata) @@ -23,10 +24,15 @@ void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) const DRWContextState *draw_ctx = DRW_context_state_get(); - float color[3] = {1, 1, 0}; - DRW_shgroup_uniform_vec3_copy(grp, "color", color); - DRW_shgroup_uniform_float_copy(grp, "alpha", 0.2f); + DRW_shgroup_uniform_vec3_copy(grp, "color", draw_ctx->scene->onion_skin_cache.color); + DRW_shgroup_uniform_float_copy(grp, "alpha", draw_ctx->scene->onion_skin_cache.alpha); + /* LISTBASE_FOREACH (OnionSkinMeshLink *, mesh_link, &draw_ctx->scene->onion_skin_cache.meshes) { + struct GPUBatch *geom = DRW_mesh_batch_cache_get_surface((Mesh *)mesh_link->mesh); + if (geom) { + DRW_shgroup_call(pd->onion_skin_grp, geom, ob); + } + } */ struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { DRW_shgroup_call(pd->onion_skin_grp, geom, ob); diff --git a/source/blender/editors/animation/anim_onion_skin.c b/source/blender/editors/animation/anim_onion_skin.c index 0bd56374ab2..bfd992357ec 100644 --- a/source/blender/editors/animation/anim_onion_skin.c +++ b/source/blender/editors/animation/anim_onion_skin.c @@ -1,26 +1,44 @@ #include "BKE_context.h" +#include "BKE_lib_id.h" +#include "BKE_mesh.h" #include "DNA_scene_types.h" #include "DNA_windowmanager_types.h" - #include "ED_onion_skin.h" #include "MEM_guardedalloc.h" #include "WM_api.h" #include "WM_types.h" -static int onion_skin_add_exec(bContext *C, wmOperator *op) +static void graveyard() { ListBase selected = {NULL, NULL}; - CTX_data_selected_objects(C, &selected); + LISTBASE_FOREACH (CollectionPointerLink *, object_ptr_link, &selected) { + /* Mesh *mesh = BKE_mesh_from_object(ob); + if (!mesh) { + continue; + } */ + /* Mesh *copy = BKE_mesh_copy_for_eval(mesh); */ + /* Mesh *mesh_result = (Mesh *)BKE_id_copy_ex( + NULL, &mesh->id, NULL, LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT); */ + /* + OnionSkinMeshLink *link = MEM_callocN(sizeof(OnionSkinMeshLink), "onion skin mesh link"); + link->mesh = copy; + BLI_addtail(&scene->onion_skin_cache.meshes, link); */ + } + BLI_freelistN(&selected); +} + +static int onion_skin_add_exec(bContext *C, wmOperator *op) +{ Scene *scene = CTX_data_scene(C); - LISTBASE_FOREACH (Object *, ob, &selected) { - /* Mesh *mesh; */ - OnionSkinMesh *link = MEM_callocN(sizeof(OnionSkinMesh), "onion skin mesh link"); - /* link->mesh = mesh; */ - BLI_addtail(&scene->onion_skin_cache.meshes, link); - } + Object *ob = CTX_data_active_object(C); + Mesh *mesh = BKE_mesh_from_object(ob); + Mesh *copy = BKE_mesh_copy_for_eval(mesh); + + OnionSkinMeshLink *link = MEM_callocN(sizeof(OnionSkinMeshLink), "onion skin mesh link"); + link->mesh = copy; + BLI_addtail(&scene->onion_skin_cache.meshes, link); - BLI_freelistN(&selected); return OPERATOR_FINISHED; } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index bcea007f15c..588ec989086 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1848,16 +1848,16 @@ typedef struct SceneGpencil { char _pad[4]; } SceneGpencil; -typedef struct OnionSkinMesh { - struct OnionSkinMesh *prev, *next; +typedef struct OnionSkinMeshLink { + struct OnionSkinMeshLink *prev, *next; /* Having a Mesh pointer here breaks compilation. Complains about "extern C" issues. */ void *mesh; -} OnionSkinMesh; +} OnionSkinMeshLink; typedef struct SceneOnionSkin { float color[3]; float alpha; - ListBase meshes /* OnionSkinMesh */; + ListBase meshes /* OnionSkinMeshLink */; } SceneOnionSkin; /** \} */ diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 989399162e9..00dc405f360 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -8358,6 +8358,21 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "SceneGpencil"); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease Pencil settings for the scene"); + prop = RNA_def_property(srna, "onion_skin_color", PROP_FLOAT, PROP_COLOR); + RNA_def_property_float_sdna(prop, NULL, "onion_skin_cache.color"); + RNA_def_property_array(prop, 3); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Onion Skin Color", "Define the color of onion skins"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL); + + prop = RNA_def_property(srna, "onion_skin_alpha", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_sdna(prop, NULL, "onion_skin_cache.alpha"); + RNA_def_property_ui_text(prop, "Onion Skin Alpha", "Alpha of drawn onion skins"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 1, 2); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL); + /* Nestled Data. */ /* *** Non-Animated *** */ RNA_define_animate_sdna(false); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index b8cf054aeb4..9d4fc3f584c 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -1541,7 +1541,8 @@ static void rna_3DViewShading_render_pass_set(PointerRNA *ptr, int value) BLI_strncpy(shading->aov_name, aov->name, sizeof(aov->name)); } else if (value == EEVEE_RENDER_PASS_BLOOM && - ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) { + ((scene->eevee.flag & SCE_EEVEE_BLOOM_ENABLED) == 0)) + { shading->render_pass = EEVEE_RENDER_PASS_COMBINED; } else { @@ -3298,7 +3299,8 @@ const EnumPropertyItem *rna_SpaceSpreadsheet_attribute_domain_itemf(bContext *UN ATTR_DOMAIN_CORNER, ATTR_DOMAIN_EDGE, ATTR_DOMAIN_POINT, - ATTR_DOMAIN_FACE)) { + ATTR_DOMAIN_FACE)) + { continue; } } -- 2.30.2 From 47a7f7e342f109dfd70b9d0ffbaa099cf4de05dd Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Fri, 5 May 2023 14:16:56 +0200 Subject: [PATCH 08/16] wip --- .../blender/draw/engines/overlay/overlay_onion_skin.cc | 8 ++++---- source/blender/editors/animation/anim_onion_skin.c | 9 ++++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_onion_skin.cc b/source/blender/draw/engines/overlay/overlay_onion_skin.cc index ac645926418..21c49ee13b8 100644 --- a/source/blender/draw/engines/overlay/overlay_onion_skin.cc +++ b/source/blender/draw/engines/overlay/overlay_onion_skin.cc @@ -27,16 +27,16 @@ void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) DRW_shgroup_uniform_vec3_copy(grp, "color", draw_ctx->scene->onion_skin_cache.color); DRW_shgroup_uniform_float_copy(grp, "alpha", draw_ctx->scene->onion_skin_cache.alpha); - /* LISTBASE_FOREACH (OnionSkinMeshLink *, mesh_link, &draw_ctx->scene->onion_skin_cache.meshes) { + LISTBASE_FOREACH (OnionSkinMeshLink *, mesh_link, &draw_ctx->scene->onion_skin_cache.meshes) { struct GPUBatch *geom = DRW_mesh_batch_cache_get_surface((Mesh *)mesh_link->mesh); if (geom) { DRW_shgroup_call(pd->onion_skin_grp, geom, ob); } - } */ - struct GPUBatch *geom = DRW_cache_object_surface_get(ob); + } + /* struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { DRW_shgroup_call(pd->onion_skin_grp, geom, ob); - } + } */ } void OVERLAY_onion_skin_draw(OVERLAY_Data *vedata) diff --git a/source/blender/editors/animation/anim_onion_skin.c b/source/blender/editors/animation/anim_onion_skin.c index bfd992357ec..03304af78b6 100644 --- a/source/blender/editors/animation/anim_onion_skin.c +++ b/source/blender/editors/animation/anim_onion_skin.c @@ -32,8 +32,15 @@ static int onion_skin_add_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); Object *ob = CTX_data_active_object(C); + if (!ob) { + return OPERATOR_CANCELLED; + } Mesh *mesh = BKE_mesh_from_object(ob); - Mesh *copy = BKE_mesh_copy_for_eval(mesh); + if (!mesh) { + return OPERATOR_CANCELLED; + } + /* Mesh *copy = BKE_mesh_copy_for_eval(mesh); */ + Mesh *copy = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE); OnionSkinMeshLink *link = MEM_callocN(sizeof(OnionSkinMeshLink), "onion skin mesh link"); link->mesh = copy; -- 2.30.2 From 0a225f889578cceea62e3970cbea636ea7a0df80 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Fri, 19 May 2023 14:11:37 +0200 Subject: [PATCH 09/16] wip test --- .../engines/overlay/overlay_onion_skin.cc | 10 ++++-- .../editors/animation/anim_onion_skin.c | 32 ++++++++++++++++--- source/blender/makesdna/DNA_scene_types.h | 4 +-- 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_onion_skin.cc b/source/blender/draw/engines/overlay/overlay_onion_skin.cc index 21c49ee13b8..f31175ccc1c 100644 --- a/source/blender/draw/engines/overlay/overlay_onion_skin.cc +++ b/source/blender/draw/engines/overlay/overlay_onion_skin.cc @@ -1,3 +1,4 @@ +#include "BKE_mesh.h" #include "DRW_render.h" #include "draw_cache_impl.h" #include "overlay_private.hh" @@ -27,8 +28,13 @@ void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) DRW_shgroup_uniform_vec3_copy(grp, "color", draw_ctx->scene->onion_skin_cache.color); DRW_shgroup_uniform_float_copy(grp, "alpha", draw_ctx->scene->onion_skin_cache.alpha); - LISTBASE_FOREACH (OnionSkinMeshLink *, mesh_link, &draw_ctx->scene->onion_skin_cache.meshes) { - struct GPUBatch *geom = DRW_mesh_batch_cache_get_surface((Mesh *)mesh_link->mesh); + LISTBASE_FOREACH (OnionSkinMeshLink *, mesh_link, &draw_ctx->scene->onion_skin_cache.objects) { + if (ob != mesh_link->object) { + continue; + } + Mesh *mesh = BKE_mesh_from_object(ob); + + struct GPUBatch *geom = DRW_mesh_batch_cache_get_surface(mesh); if (geom) { DRW_shgroup_call(pd->onion_skin_grp, geom, ob); } diff --git a/source/blender/editors/animation/anim_onion_skin.c b/source/blender/editors/animation/anim_onion_skin.c index 03304af78b6..2c21e1f2be4 100644 --- a/source/blender/editors/animation/anim_onion_skin.c +++ b/source/blender/editors/animation/anim_onion_skin.c @@ -1,9 +1,15 @@ #include "BKE_context.h" +#include "BKE_layer.h" #include "BKE_lib_id.h" +#include "BKE_main.h" #include "BKE_mesh.h" +#include "BKE_object.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_build.h" #include "DNA_scene_types.h" #include "DNA_windowmanager_types.h" #include "ED_onion_skin.h" +#include "ED_outliner.h" #include "MEM_guardedalloc.h" #include "WM_api.h" #include "WM_types.h" @@ -30,6 +36,9 @@ static void graveyard() static int onion_skin_add_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); + Main *bmain = CTX_data_main(C); + BKE_main_id_newptr_and_tag_clear(bmain); + ViewLayer *view_layer = CTX_data_view_layer(C); Object *ob = CTX_data_active_object(C); if (!ob) { @@ -40,11 +49,26 @@ static int onion_skin_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } /* Mesh *copy = BKE_mesh_copy_for_eval(mesh); */ - Mesh *copy = (Mesh *)BKE_id_copy_ex(NULL, &mesh->id, NULL, LIB_ID_COPY_LOCALIZE); - + /* Mesh *copy = (Mesh *)BKE_id_copy_ex(bmain, &mesh->id, NULL, LIB_ID_COPY_DEFAULT); */ + Object *ob_new = BKE_object_duplicate(bmain, + ob, + (eDupli_ID_Flags)U.dupflag, + LIB_ID_DUPLICATE_IS_SUBPROCESS | + LIB_ID_DUPLICATE_IS_ROOT_ID); + LayerCollection *layer_collection = BKE_layer_collection_from_index(view_layer, 2); + BKE_collection_object_add(bmain, layer_collection->collection, ob_new); OnionSkinMeshLink *link = MEM_callocN(sizeof(OnionSkinMeshLink), "onion skin mesh link"); - link->mesh = copy; - BLI_addtail(&scene->onion_skin_cache.meshes, link); + link->object = ob_new; + ob_new->adt = NULL; + BLI_addtail(&scene->onion_skin_cache.objects, link); + + ED_outliner_select_sync_from_object_tag(C); + + DEG_relations_tag_update(bmain); + DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT); + + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); + WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); return OPERATOR_FINISHED; } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 4796b77823f..99b5e1225aa 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1852,13 +1852,13 @@ typedef struct SceneGpencil { typedef struct OnionSkinMeshLink { struct OnionSkinMeshLink *prev, *next; /* Having a Mesh pointer here breaks compilation. Complains about "extern C" issues. */ - void *mesh; + struct Object *object; } OnionSkinMeshLink; typedef struct SceneOnionSkin { float color[3]; float alpha; - ListBase meshes /* OnionSkinMeshLink */; + ListBase objects /* OnionSkinMeshLink */; } SceneOnionSkin; /** \} */ -- 2.30.2 From 1dc4512cdeff62d98794a64f6206c992fda0ce46 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Sun, 21 May 2023 13:22:33 +0200 Subject: [PATCH 10/16] hacky implementation --- .../engines/overlay/overlay_onion_skin.cc | 25 ++++++++++++++----- .../editors/animation/anim_onion_skin.c | 3 +-- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_onion_skin.cc b/source/blender/draw/engines/overlay/overlay_onion_skin.cc index f31175ccc1c..21630406b62 100644 --- a/source/blender/draw/engines/overlay/overlay_onion_skin.cc +++ b/source/blender/draw/engines/overlay/overlay_onion_skin.cc @@ -18,6 +18,17 @@ void OVERLAY_onion_skin_init(OVERLAY_Data *vedata) DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); } +static bool str_equals(const char *__restrict str, const char *__restrict start) +{ + for (; *str && *start; str++, start++) { + if (*str != *start) { + return false; + } + } + + return (*start == *str); +} + void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) { OVERLAY_PrivateData *pd = vedata->stl->pd; @@ -29,20 +40,22 @@ void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) DRW_shgroup_uniform_float_copy(grp, "alpha", draw_ctx->scene->onion_skin_cache.alpha); LISTBASE_FOREACH (OnionSkinMeshLink *, mesh_link, &draw_ctx->scene->onion_skin_cache.objects) { - if (ob != mesh_link->object) { + // if(BKE_id_comp) + + if (!str_equals(ob->id.name, mesh_link->object->id.name)) { continue; } - Mesh *mesh = BKE_mesh_from_object(ob); + /* Mesh *mesh = BKE_mesh_from_object(ob); struct GPUBatch *geom = DRW_mesh_batch_cache_get_surface(mesh); + if (geom) { + DRW_shgroup_call(pd->onion_skin_grp, geom, ob); + } */ + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { DRW_shgroup_call(pd->onion_skin_grp, geom, ob); } } - /* struct GPUBatch *geom = DRW_cache_object_surface_get(ob); - if (geom) { - DRW_shgroup_call(pd->onion_skin_grp, geom, ob); - } */ } void OVERLAY_onion_skin_draw(OVERLAY_Data *vedata) diff --git a/source/blender/editors/animation/anim_onion_skin.c b/source/blender/editors/animation/anim_onion_skin.c index 2c21e1f2be4..d8518743400 100644 --- a/source/blender/editors/animation/anim_onion_skin.c +++ b/source/blender/editors/animation/anim_onion_skin.c @@ -67,8 +67,7 @@ static int onion_skin_add_exec(bContext *C, wmOperator *op) DEG_relations_tag_update(bmain); DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE | ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); - WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); + WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT | ND_LAYER_CONTENT, scene); return OPERATOR_FINISHED; } -- 2.30.2 From ea6670404f5407e395c7eac9d5319050eee40f14 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 25 May 2023 15:10:12 +0200 Subject: [PATCH 11/16] onion skin range stuff --- .../keyconfig/keymap_data/blender_default.py | 1 + source/blender/editors/animation/anim_ops.c | 148 ++++++++++++++++++ .../blender/editors/animation/time_scrub_ui.c | 35 +++++ source/blender/makesdna/DNA_scene_types.h | 1 + 4 files changed, 185 insertions(+) diff --git a/scripts/presets/keyconfig/keymap_data/blender_default.py b/scripts/presets/keyconfig/keymap_data/blender_default.py index 9459c5eb122..65b53def66a 100644 --- a/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -1056,6 +1056,7 @@ def km_time_scrub(_params): items.extend([ ("anim.change_frame", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None), + ("anim.change_onion_skin_range", {"type": 'LEFTMOUSE', "value": 'PRESS', "alt": True}, None), ]) return keymap diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 22c9217dc35..3a6c8bae7e3 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -395,6 +395,153 @@ static void ANIM_OT_change_frame(wmOperatorType *ot) /** \} */ +/* Set the new frame number */ +static void change_onion_skin_range_apply(bContext *C, wmOperator *op, const bool always_update) +{ + Scene *scene = CTX_data_scene(C); + const int left = RNA_int_get(op->ptr, "left"); + const int right = RNA_int_get(op->ptr, "right"); + + scene->onion_skin_cache.relative_left = left; + scene->onion_skin_cache.relative_right = right; + + /* do updates */ + if (always_update) { + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + } +} + +static void change_onion_skin_range_cancel(bContext *C, wmOperator *UNUSED(op)) +{ + bScreen *screen = CTX_wm_screen(C); + screen->scrubbing = false; + + SpaceSeq *sseq = CTX_wm_space_seq(C); + if (sseq != NULL) { + change_frame_seq_preview_end(sseq); + } + + if (need_extra_redraw_after_scrubbing_ends(C)) { + Scene *scene = CTX_data_scene(C); + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + } +} + +/* Modal event handling of frame changing */ +static int change_onion_skin_range_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + int ret = OPERATOR_RUNNING_MODAL; + /* execute the events */ + switch (event->type) { + case EVT_ESCKEY: + ret = OPERATOR_FINISHED; + break; + + case MOUSEMOVE: + Scene *scene = CTX_data_scene(C); + const int clicked_frame = roundf(frame_from_event(C, event)); + const int current_scene_frame = BKE_scene_ctime_get(scene); + if (clicked_frame > current_scene_frame) { + RNA_int_set(op->ptr, "right", clicked_frame); + } + else if (clicked_frame < current_scene_frame) { + RNA_int_set(op->ptr, "left", clicked_frame); + } + else { + return OPERATOR_CANCELLED; + } + change_onion_skin_range_apply(C, op, false); + break; + + case LEFTMOUSE: + case RIGHTMOUSE: + case MIDDLEMOUSE: + /* We check for either mouse-button to end, to work with all user keymaps. */ + if (event->val == KM_RELEASE) { + ret = OPERATOR_FINISHED; + } + break; + } + + if (ret != OPERATOR_RUNNING_MODAL) { + bScreen *screen = CTX_wm_screen(C); + screen->scrubbing = false; + + SpaceSeq *sseq = CTX_wm_space_seq(C); + if (sseq != NULL) { + change_frame_seq_preview_end(sseq); + } + if (need_extra_redraw_after_scrubbing_ends(C)) { + Scene *scene = CTX_data_scene(C); + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + } + } + + return ret; +} + +/* Modal Operator init */ +static int change_onion_skin_range_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ARegion *region = CTX_wm_region(C); + bScreen *screen = CTX_wm_screen(C); + if (CTX_wm_space_seq(C) != NULL && region->regiontype == RGN_TYPE_PREVIEW) { + return OPERATOR_CANCELLED; + } + + Scene *scene = CTX_data_scene(C); + RNA_int_set(op->ptr, "right", scene->onion_skin_cache.relative_right); + RNA_int_set(op->ptr, "left", scene->onion_skin_cache.relative_left); + + const int clicked_frame = roundf(frame_from_event(C, event)); + const int current_scene_frame = BKE_scene_ctime_get(scene); + if (clicked_frame > current_scene_frame) { + RNA_int_set(op->ptr, "right", clicked_frame); + } + else if (clicked_frame < current_scene_frame) { + RNA_int_set(op->ptr, "left", clicked_frame); + } + else { + return OPERATOR_CANCELLED; + } + + screen->scrubbing = true; + + change_onion_skin_range_apply(C, op, true); + + /* add temp handler */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int change_onion_skin_range_exec(bContext *C, wmOperator *op) +{ + change_onion_skin_range_apply(C, op, true); + return OPERATOR_FINISHED; +} + +static void ANIM_OT_change_onion_skin_range(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Change Onion Skin Range"; + ot->idname = "ANIM_OT_change_onion_skin_range"; + ot->description = "Interactively change the amount of onion skins shown"; + + ot->exec = change_onion_skin_range_exec; + ot->poll = change_frame_poll; + ot->invoke = change_onion_skin_range_invoke; + ot->modal = change_onion_skin_range_modal; + ot->cancel = change_onion_skin_range_cancel; + + /* rna */ + ot->prop = RNA_def_int( + ot->srna, "left", 0, MINAFRAME, MAXFRAME, "Left", "", MINAFRAME, MAXFRAME); + ot->prop = RNA_def_int( + ot->srna, "right", 0, MINAFRAME, MAXFRAME, "Right", "", MINAFRAME, MAXFRAME); +} + /* -------------------------------------------------------------------- */ /** \name Start/End Frame Operators * \{ */ @@ -652,6 +799,7 @@ void ED_operatortypes_anim(void) { /* Animation Editors only -------------------------- */ WM_operatortype_append(ANIM_OT_change_frame); + WM_operatortype_append(ANIM_OT_change_onion_skin_range); WM_operatortype_append(ANIM_OT_start_frame_set); WM_operatortype_append(ANIM_OT_end_frame_set); diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c index 5b7eee00521..10bb3ff4a0f 100644 --- a/source/blender/editors/animation/time_scrub_ui.c +++ b/source/blender/editors/animation/time_scrub_ui.c @@ -136,6 +136,41 @@ static void draw_current_frame(const Scene *scene, U.pixelsize, 4 * UI_SCALE_FAC); + if (scene->onion_skin_cache.relative_left != 0) { + const int frame_relative_left = UI_view2d_view_to_region_x( + v2d, current_frame - scene->onion_skin_cache.relative_left); + UI_draw_roundbox_4fv_ex( + &(const rctf){ + .xmin = frame_relative_left - box_width / 4 + U.pixelsize / 2, + .xmax = frame_relative_left + box_width / 4 + U.pixelsize / 2, + .ymin = scrub_region_rect->ymin + box_padding, + .ymax = scrub_region_rect->ymax - box_padding, + }, + bg_color, + NULL, + 1.0f, + outline_color, + U.pixelsize, + 4 * UI_SCALE_FAC); + } + if (scene->onion_skin_cache.relative_right != 0) { + const int frame_relative_right = UI_view2d_view_to_region_x( + v2d, current_frame - scene->onion_skin_cache.relative_right); + UI_draw_roundbox_4fv_ex( + &(const rctf){ + .xmin = frame_relative_right - box_width / 4 + U.pixelsize / 2, + .xmax = frame_relative_right + box_width / 4 + U.pixelsize / 2, + .ymin = scrub_region_rect->ymin + box_padding, + .ymax = scrub_region_rect->ymax - box_padding, + }, + bg_color, + NULL, + 1.0f, + outline_color, + U.pixelsize, + 4 * UI_SCALE_FAC); + } + uchar text_color[4]; UI_GetThemeColor4ubv(TH_HEADER_TEXT_HI, text_color); UI_fontstyle_draw_simple(fstyle, diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index be1e978127e..8f9b9b515e2 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1866,6 +1866,7 @@ typedef struct OnionSkinMeshLink { typedef struct SceneOnionSkin { float color[3]; float alpha; + int relative_left, relative_right; ListBase objects /* OnionSkinMeshLink */; } SceneOnionSkin; -- 2.30.2 From 49a320d236fad3068c92f758bf88ea5b61241226 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 25 May 2023 15:48:13 +0200 Subject: [PATCH 12/16] fix update issue --- source/blender/editors/animation/anim_ops.c | 55 +++++++------------ .../blender/editors/animation/time_scrub_ui.c | 2 +- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 3a6c8bae7e3..4371d19315d 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -396,7 +396,7 @@ static void ANIM_OT_change_frame(wmOperatorType *ot) /** \} */ /* Set the new frame number */ -static void change_onion_skin_range_apply(bContext *C, wmOperator *op, const bool always_update) +static void change_onion_skin_range_apply(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); const int left = RNA_int_get(op->ptr, "left"); @@ -405,10 +405,20 @@ static void change_onion_skin_range_apply(bContext *C, wmOperator *op, const boo scene->onion_skin_cache.relative_left = left; scene->onion_skin_cache.relative_right = right; - /* do updates */ - if (always_update) { - DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); + DEG_id_tag_update(&scene->id, ID_RECALC_FRAME_CHANGE); + WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); +} + +static void onion_skin_range_foo(bContext *C, wmOperator *op, const wmEvent *event) +{ + Scene *scene = CTX_data_scene(C); + const int clicked_frame = roundf(frame_from_event(C, event)); + const int current_scene_frame = BKE_scene_ctime_get(scene); + if (clicked_frame > current_scene_frame) { + RNA_int_set(op->ptr, "right", clicked_frame - current_scene_frame); + } + else if (clicked_frame < current_scene_frame) { + RNA_int_set(op->ptr, "left", current_scene_frame - clicked_frame); } } @@ -439,19 +449,8 @@ static int change_onion_skin_range_modal(bContext *C, wmOperator *op, const wmEv break; case MOUSEMOVE: - Scene *scene = CTX_data_scene(C); - const int clicked_frame = roundf(frame_from_event(C, event)); - const int current_scene_frame = BKE_scene_ctime_get(scene); - if (clicked_frame > current_scene_frame) { - RNA_int_set(op->ptr, "right", clicked_frame); - } - else if (clicked_frame < current_scene_frame) { - RNA_int_set(op->ptr, "left", clicked_frame); - } - else { - return OPERATOR_CANCELLED; - } - change_onion_skin_range_apply(C, op, false); + onion_skin_range_foo(C, op, event); + change_onion_skin_range_apply(C, op); break; case LEFTMOUSE: @@ -468,10 +467,6 @@ static int change_onion_skin_range_modal(bContext *C, wmOperator *op, const wmEv bScreen *screen = CTX_wm_screen(C); screen->scrubbing = false; - SpaceSeq *sseq = CTX_wm_space_seq(C); - if (sseq != NULL) { - change_frame_seq_preview_end(sseq); - } if (need_extra_redraw_after_scrubbing_ends(C)) { Scene *scene = CTX_data_scene(C); WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); @@ -494,21 +489,11 @@ static int change_onion_skin_range_invoke(bContext *C, wmOperator *op, const wmE RNA_int_set(op->ptr, "right", scene->onion_skin_cache.relative_right); RNA_int_set(op->ptr, "left", scene->onion_skin_cache.relative_left); - const int clicked_frame = roundf(frame_from_event(C, event)); - const int current_scene_frame = BKE_scene_ctime_get(scene); - if (clicked_frame > current_scene_frame) { - RNA_int_set(op->ptr, "right", clicked_frame); - } - else if (clicked_frame < current_scene_frame) { - RNA_int_set(op->ptr, "left", clicked_frame); - } - else { - return OPERATOR_CANCELLED; - } + onion_skin_range_foo(C, op, event); screen->scrubbing = true; - change_onion_skin_range_apply(C, op, true); + change_onion_skin_range_apply(C, op); /* add temp handler */ WM_event_add_modal_handler(C, op); @@ -518,7 +503,7 @@ static int change_onion_skin_range_invoke(bContext *C, wmOperator *op, const wmE static int change_onion_skin_range_exec(bContext *C, wmOperator *op) { - change_onion_skin_range_apply(C, op, true); + change_onion_skin_range_apply(C, op); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c index 10bb3ff4a0f..0d2965ae946 100644 --- a/source/blender/editors/animation/time_scrub_ui.c +++ b/source/blender/editors/animation/time_scrub_ui.c @@ -155,7 +155,7 @@ static void draw_current_frame(const Scene *scene, } if (scene->onion_skin_cache.relative_right != 0) { const int frame_relative_right = UI_view2d_view_to_region_x( - v2d, current_frame - scene->onion_skin_cache.relative_right); + v2d, current_frame + scene->onion_skin_cache.relative_right); UI_draw_roundbox_4fv_ex( &(const rctf){ .xmin = frame_relative_right - box_width / 4 + U.pixelsize / 2, -- 2.30.2 From 80a4e7b010da9d8bd90ced0064b1c4b2a7efb5bc Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 25 May 2023 15:52:08 +0200 Subject: [PATCH 13/16] change draw call order --- .../blender/editors/animation/time_scrub_ui.c | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/source/blender/editors/animation/time_scrub_ui.c b/source/blender/editors/animation/time_scrub_ui.c index 0d2965ae946..4a299ba51e8 100644 --- a/source/blender/editors/animation/time_scrub_ui.c +++ b/source/blender/editors/animation/time_scrub_ui.c @@ -122,20 +122,6 @@ static void draw_current_frame(const Scene *scene, float outline_color[4]; UI_GetThemeColorShade4fv(TH_CFRAME, 5, outline_color); - UI_draw_roundbox_4fv_ex( - &(const rctf){ - .xmin = frame_x - box_width / 2 + U.pixelsize / 2, - .xmax = frame_x + box_width / 2 + U.pixelsize / 2, - .ymin = scrub_region_rect->ymin + box_padding, - .ymax = scrub_region_rect->ymax - box_padding, - }, - bg_color, - NULL, - 1.0f, - outline_color, - U.pixelsize, - 4 * UI_SCALE_FAC); - if (scene->onion_skin_cache.relative_left != 0) { const int frame_relative_left = UI_view2d_view_to_region_x( v2d, current_frame - scene->onion_skin_cache.relative_left); @@ -171,6 +157,20 @@ static void draw_current_frame(const Scene *scene, 4 * UI_SCALE_FAC); } + UI_draw_roundbox_4fv_ex( + &(const rctf){ + .xmin = frame_x - box_width / 2 + U.pixelsize / 2, + .xmax = frame_x + box_width / 2 + U.pixelsize / 2, + .ymin = scrub_region_rect->ymin + box_padding, + .ymax = scrub_region_rect->ymax - box_padding, + }, + bg_color, + NULL, + 1.0f, + outline_color, + U.pixelsize, + 4 * UI_SCALE_FAC); + uchar text_color[4]; UI_GetThemeColor4ubv(TH_HEADER_TEXT_HI, text_color); UI_fontstyle_draw_simple(fstyle, -- 2.30.2 From ba45e6bca3e44d1b0b6db303f5aaeb08c4fcc7d3 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Thu, 25 May 2023 16:57:17 +0200 Subject: [PATCH 14/16] onion skin drawing relative to current frame --- .../draw/engines/overlay/overlay_onion_skin.cc | 18 +++++++++++------- .../editors/animation/anim_onion_skin.c | 2 ++ source/blender/makesdna/DNA_scene_types.h | 2 ++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_onion_skin.cc b/source/blender/draw/engines/overlay/overlay_onion_skin.cc index 21630406b62..4da0575e1cd 100644 --- a/source/blender/draw/engines/overlay/overlay_onion_skin.cc +++ b/source/blender/draw/engines/overlay/overlay_onion_skin.cc @@ -39,18 +39,22 @@ void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) DRW_shgroup_uniform_vec3_copy(grp, "color", draw_ctx->scene->onion_skin_cache.color); DRW_shgroup_uniform_float_copy(grp, "alpha", draw_ctx->scene->onion_skin_cache.alpha); - LISTBASE_FOREACH (OnionSkinMeshLink *, mesh_link, &draw_ctx->scene->onion_skin_cache.objects) { - // if(BKE_id_comp) + Scene *scene = draw_ctx->scene; + const float current_frame = BKE_scene_ctime_get(scene); + LISTBASE_FOREACH (OnionSkinMeshLink *, mesh_link, &scene->onion_skin_cache.objects) { if (!str_equals(ob->id.name, mesh_link->object->id.name)) { continue; } - /* Mesh *mesh = BKE_mesh_from_object(ob); - struct GPUBatch *geom = DRW_mesh_batch_cache_get_surface(mesh); - if (geom) { - DRW_shgroup_call(pd->onion_skin_grp, geom, ob); - } */ + if (mesh_link->frame < current_frame - scene->onion_skin_cache.relative_left) { + continue; + } + + if (mesh_link->frame > current_frame + scene->onion_skin_cache.relative_right) { + continue; + } + struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { DRW_shgroup_call(pd->onion_skin_grp, geom, ob); diff --git a/source/blender/editors/animation/anim_onion_skin.c b/source/blender/editors/animation/anim_onion_skin.c index d8518743400..441a58c46fe 100644 --- a/source/blender/editors/animation/anim_onion_skin.c +++ b/source/blender/editors/animation/anim_onion_skin.c @@ -4,6 +4,7 @@ #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_object.h" +#include "BKE_scene.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_build.h" #include "DNA_scene_types.h" @@ -60,6 +61,7 @@ static int onion_skin_add_exec(bContext *C, wmOperator *op) OnionSkinMeshLink *link = MEM_callocN(sizeof(OnionSkinMeshLink), "onion skin mesh link"); link->object = ob_new; ob_new->adt = NULL; + link->frame = BKE_scene_ctime_get(scene); BLI_addtail(&scene->onion_skin_cache.objects, link); ED_outliner_select_sync_from_object_tag(C); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 8f9b9b515e2..62337e1293a 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1861,6 +1861,8 @@ typedef struct OnionSkinMeshLink { struct OnionSkinMeshLink *prev, *next; /* Having a Mesh pointer here breaks compilation. Complains about "extern C" issues. */ struct Object *object; + float frame; + char _pad[4]; } OnionSkinMeshLink; typedef struct SceneOnionSkin { -- 2.30.2 From bc0d9a18b72f09cfcf639e76f77d2f13813cad26 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Fri, 26 May 2023 16:57:49 +0200 Subject: [PATCH 15/16] left and right color. not working properly --- scripts/startup/bl_ui/properties_render.py | 5 +++- .../engines/overlay/overlay_onion_skin.cc | 17 +++++++++--- source/blender/makesdna/DNA_scene_types.h | 4 ++- source/blender/makesrna/intern/rna_scene.c | 27 ++++++++++++++++--- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/scripts/startup/bl_ui/properties_render.py b/scripts/startup/bl_ui/properties_render.py index 8f9bdac9a28..6d9def40e2a 100644 --- a/scripts/startup/bl_ui/properties_render.py +++ b/scripts/startup/bl_ui/properties_render.py @@ -734,7 +734,10 @@ class RENDER_PT_onion_skins(RenderButtonsPanel, Panel): scene = context.scene col = layout.column() - col.prop(scene, "onion_skin_color") + col.prop(scene, "onion_skin_color_left") + col.prop(scene, "onion_skin_color_right") + col.prop(scene, "os_relative_left") + col.prop(scene, "os_relative_right") col.prop(scene, "onion_skin_alpha") diff --git a/source/blender/draw/engines/overlay/overlay_onion_skin.cc b/source/blender/draw/engines/overlay/overlay_onion_skin.cc index 4da0575e1cd..dd39a726669 100644 --- a/source/blender/draw/engines/overlay/overlay_onion_skin.cc +++ b/source/blender/draw/engines/overlay/overlay_onion_skin.cc @@ -36,17 +36,20 @@ void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) const DRWContextState *draw_ctx = DRW_context_state_get(); - DRW_shgroup_uniform_vec3_copy(grp, "color", draw_ctx->scene->onion_skin_cache.color); - DRW_shgroup_uniform_float_copy(grp, "alpha", draw_ctx->scene->onion_skin_cache.alpha); - Scene *scene = draw_ctx->scene; const float current_frame = BKE_scene_ctime_get(scene); + DRW_shgroup_uniform_float_copy(grp, "alpha", draw_ctx->scene->onion_skin_cache.alpha); + LISTBASE_FOREACH (OnionSkinMeshLink *, mesh_link, &scene->onion_skin_cache.objects) { if (!str_equals(ob->id.name, mesh_link->object->id.name)) { continue; } + if (compare_ff(mesh_link->frame, current_frame, FLT_EPSILON)) { + continue; + } + if (mesh_link->frame < current_frame - scene->onion_skin_cache.relative_left) { continue; } @@ -54,10 +57,16 @@ void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) if (mesh_link->frame > current_frame + scene->onion_skin_cache.relative_right) { continue; } + if (mesh_link->frame < current_frame) { + DRW_shgroup_uniform_vec3_copy(grp, "color", draw_ctx->scene->onion_skin_cache.color_left); + } + else { + DRW_shgroup_uniform_vec3_copy(grp, "color", draw_ctx->scene->onion_skin_cache.color_right); + } struct GPUBatch *geom = DRW_cache_object_surface_get(ob); if (geom) { - DRW_shgroup_call(pd->onion_skin_grp, geom, ob); + DRW_shgroup_call(grp, geom, ob); } } } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 62337e1293a..28a835cd580 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1866,9 +1866,11 @@ typedef struct OnionSkinMeshLink { } OnionSkinMeshLink; typedef struct SceneOnionSkin { - float color[3]; + float color_left[3]; + float color_right[3]; float alpha; int relative_left, relative_right; + char _pad[4]; ListBase objects /* OnionSkinMeshLink */; } SceneOnionSkin; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 7a3923c6bba..b5253ad5395 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -8442,11 +8442,32 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_struct_type(prop, "SceneGpencil"); RNA_def_property_ui_text(prop, "Grease Pencil", "Grease Pencil settings for the scene"); - prop = RNA_def_property(srna, "onion_skin_color", PROP_FLOAT, PROP_COLOR); - RNA_def_property_float_sdna(prop, NULL, "onion_skin_cache.color"); + prop = RNA_def_property(srna, "onion_skin_color_left", PROP_FLOAT, PROP_COLOR); + RNA_def_property_float_sdna(prop, NULL, "onion_skin_cache.color_left"); RNA_def_property_array(prop, 3); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_ui_text(prop, "Onion Skin Color", "Define the color of onion skins"); + RNA_def_property_ui_text(prop, "Onion Skin Color Left", "Define the color of onion skins"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL); + + prop = RNA_def_property(srna, "onion_skin_color_right", PROP_FLOAT, PROP_COLOR); + RNA_def_property_float_sdna(prop, NULL, "onion_skin_cache.color_right"); + RNA_def_property_array(prop, 3); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Onion Skin Color Right", "Define the color of onion skins"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL); + + prop = RNA_def_property(srna, "os_relative_left", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "onion_skin_cache.relative_left"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text( + prop, "Onion Skin Range Left", "how far to the lef to draw onion skins"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL); + + prop = RNA_def_property(srna, "os_relative_right", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "onion_skin_cache.relative_right"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text( + prop, "Onion Skin Range Right", "how far to the lef to draw onion skins"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL); prop = RNA_def_property(srna, "onion_skin_alpha", PROP_FLOAT, PROP_FACTOR); -- 2.30.2 From efa97892e0696907a7064e0a5e562286e332c581 Mon Sep 17 00:00:00 2001 From: Christoph Lendenfeld Date: Fri, 26 May 2023 18:06:29 +0200 Subject: [PATCH 16/16] outline wip --- scripts/startup/bl_ui/properties_render.py | 1 + .../draw/engines/overlay/overlay_onion_skin.cc | 18 ++++++++++++++---- .../draw/engines/overlay/overlay_private.hh | 2 ++ .../draw/engines/overlay/overlay_shader.cc | 11 +++++++++++ .../shaders/infos/overlay_extra_info.hh | 1 + source/blender/makesdna/DNA_scene_types.h | 7 ++++++- source/blender/makesrna/intern/rna_scene.c | 12 ++++++++++++ 7 files changed, 47 insertions(+), 5 deletions(-) diff --git a/scripts/startup/bl_ui/properties_render.py b/scripts/startup/bl_ui/properties_render.py index 6d9def40e2a..f83ecc7e20f 100644 --- a/scripts/startup/bl_ui/properties_render.py +++ b/scripts/startup/bl_ui/properties_render.py @@ -739,6 +739,7 @@ class RENDER_PT_onion_skins(RenderButtonsPanel, Panel): col.prop(scene, "os_relative_left") col.prop(scene, "os_relative_right") col.prop(scene, "onion_skin_alpha") + col.prop(scene, "onion_skin_draw_modes") class RENDER_PT_opengl_sampling(RenderButtonsPanel, Panel): diff --git a/source/blender/draw/engines/overlay/overlay_onion_skin.cc b/source/blender/draw/engines/overlay/overlay_onion_skin.cc index dd39a726669..a0fbcb3aa26 100644 --- a/source/blender/draw/engines/overlay/overlay_onion_skin.cc +++ b/source/blender/draw/engines/overlay/overlay_onion_skin.cc @@ -11,10 +11,14 @@ void OVERLAY_onion_skin_init(OVERLAY_Data *vedata) DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND_ALPHA; DRW_PASS_CREATE(psl->onion_skin_ps, state | pd->clipping_state); - GPUShader *shader = OVERLAY_shader_onion_skin_mesh(); DRWShadingGroup *grp; - pd->onion_skin_grp = grp = DRW_shgroup_create(shader, psl->onion_skin_ps); + GPUShader *shader = OVERLAY_shader_onion_skin_mesh(); + pd->onion_skin_grp = grp = DRW_shgroup_create(shader, psl->onion_skin_ps); + DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); + + GPUShader *shader_outline = OVERLAY_shader_onion_skin_outline(); + pd->onion_skin_outline_grp = grp = DRW_shgroup_create(shader_outline, psl->onion_skin_ps); DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo); } @@ -32,14 +36,20 @@ static bool str_equals(const char *__restrict str, const char *__restrict start) void OVERLAY_onion_skin_populate(OVERLAY_Data *vedata, Object *ob) { OVERLAY_PrivateData *pd = vedata->stl->pd; - DRWShadingGroup *grp = pd->onion_skin_grp; const DRWContextState *draw_ctx = DRW_context_state_get(); Scene *scene = draw_ctx->scene; const float current_frame = BKE_scene_ctime_get(scene); - DRW_shgroup_uniform_float_copy(grp, "alpha", draw_ctx->scene->onion_skin_cache.alpha); + DRWShadingGroup *grp = nullptr; + if (scene->onion_skin_cache.draw_method == ONION_SKIN_DRAW_SOLID) { + grp = pd->onion_skin_grp; + } + else { + grp = pd->onion_skin_outline_grp; + } + DRW_shgroup_uniform_float_copy(grp, "alpha", scene->onion_skin_cache.alpha); LISTBASE_FOREACH (OnionSkinMeshLink *, mesh_link, &scene->onion_skin_cache.objects) { if (!str_equals(ob->id.name, mesh_link->object->id.name)) { diff --git a/source/blender/draw/engines/overlay/overlay_private.hh b/source/blender/draw/engines/overlay/overlay_private.hh index 87a7d72aa92..9893ddeac3a 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -281,6 +281,7 @@ typedef struct OVERLAY_PrivateData { DRWShadingGroup *motion_path_lines_grp; DRWShadingGroup *motion_path_points_grp; DRWShadingGroup *onion_skin_grp; + DRWShadingGroup *onion_skin_outline_grp; DRWShadingGroup *outlines_grp; DRWShadingGroup *outlines_curves_grp; DRWShadingGroup *outlines_ptcloud_grp; @@ -777,6 +778,7 @@ GPUShader *OVERLAY_shader_image(void); GPUShader *OVERLAY_shader_motion_path_line(void); GPUShader *OVERLAY_shader_motion_path_vert(void); GPUShader *OVERLAY_shader_onion_skin_mesh(void); +GPUShader *OVERLAY_shader_onion_skin_outline(void); GPUShader *OVERLAY_shader_uniform_color(void); GPUShader *OVERLAY_shader_uniform_color_pointcloud(void); GPUShader *OVERLAY_shader_outline_prepass(bool use_wire); diff --git a/source/blender/draw/engines/overlay/overlay_shader.cc b/source/blender/draw/engines/overlay/overlay_shader.cc index b40499a03b9..52af0f080f3 100644 --- a/source/blender/draw/engines/overlay/overlay_shader.cc +++ b/source/blender/draw/engines/overlay/overlay_shader.cc @@ -79,6 +79,7 @@ struct OVERLAY_Shaders { GPUShader *motion_path_line; GPUShader *motion_path_vert; GPUShader *onion_skin_mesh; + GPUShader *onion_skin_outline; GPUShader *outline_prepass; GPUShader *outline_prepass_curves; GPUShader *outline_prepass_gpencil; @@ -696,6 +697,16 @@ GPUShader *OVERLAY_shader_onion_skin_mesh(void) return sh_data->onion_skin_mesh; } +GPUShader *OVERLAY_shader_onion_skin_outline(void) +{ + const DRWContextState *draw_ctx = DRW_context_state_get(); + OVERLAY_Shaders *sh_data = &e_data.sh_data[draw_ctx->sh_cfg]; + if (!sh_data->onion_skin_outline) { + sh_data->onion_skin_outline = GPU_shader_create_from_info_name("overlay_outline_detect"); + } + return sh_data->onion_skin_outline; +} + GPUShader *OVERLAY_shader_outline_prepass(bool use_wire) { const DRWContextState *draw_ctx = DRW_context_state_get(); diff --git a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh index b67736c9bfd..0b817b0f565 100644 --- a/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh +++ b/source/blender/draw/engines/overlay/shaders/infos/overlay_extra_info.hh @@ -260,6 +260,7 @@ GPU_SHADER_CREATE_INFO(overlay_onion_skin_mesh) .vertex_out(onion_skin_iface) .push_constant(Type::VEC3, "color") .push_constant(Type::FLOAT, "alpha") + .push_constant(Type::INT, "draw_method") .fragment_out(0, Type::VEC4, "fragColor") .fragment_source("overlay_onion_skin_mesh_frag.glsl") .vertex_source("overlay_onion_skin_mesh_vert.glsl") diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 28a835cd580..56f71870ae2 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1865,12 +1865,17 @@ typedef struct OnionSkinMeshLink { char _pad[4]; } OnionSkinMeshLink; +enum { + ONION_SKIN_DRAW_SOLID = 0, + ONION_SKIN_DRAW_OUTLINE = 1, +}; + typedef struct SceneOnionSkin { float color_left[3]; float color_right[3]; float alpha; int relative_left, relative_right; - char _pad[4]; + int draw_method; ListBase objects /* OnionSkinMeshLink */; } SceneOnionSkin; diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index b5253ad5395..0091d271ca9 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -671,6 +671,12 @@ static const EnumPropertyItem plane_orientation_items[] = { {0, NULL, 0, NULL, NULL}, }; +static const EnumPropertyItem onion_skin_draw_modes[] = { + {ONION_SKIN_DRAW_SOLID, "SOLID", 0, "Solid", "Draw solid shape"}, + {ONION_SKIN_DRAW_OUTLINE, "OUTLINE", 0, "Outline", "Draw outline"}, + {0, NULL, 0, NULL, NULL}, +}; + static const EnumPropertyItem snap_to_items[] = { {SCE_SNAP_MODE_GEOM, "GEOMETRY", 0, "Geometry", "Snap to all geometry"}, {SCE_SNAP_MODE_NONE, "DEFAULT", 0, "Default", "Use the current snap settings"}, @@ -8478,6 +8484,12 @@ void RNA_def_scene(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL); + prop = RNA_def_property(srna, "onion_skin_draw_modes", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "onion_skin_cache.draw_method"); + RNA_def_property_enum_items(prop, onion_skin_draw_modes); + RNA_def_property_enum_default(prop, ONION_SKIN_DRAW_SOLID); + RNA_def_property_ui_text(prop, "Onion Skin Draw Modes", "How to draw os's"); + /* Nestled Data. */ /* *** Non-Animated *** */ RNA_define_animate_sdna(false); -- 2.30.2