GPv3: Port frame_clean_duplicate operator #116655

Open
Abdelrahman Said wants to merge 28 commits from amsaid1989/blender:gpv3-delete-duplicate-frames into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
First-time contributor

Port the frame_clean_duplicate operator to GPv3:

  • Resolves: #114182
  • Adds GREASE_PENCIL_OT_frame_clean_duplicate operator
Port the `frame_clean_duplicate` operator to GPv3: - Resolves: [#114182](https://projects.blender.org/blender/blender/issues/114182) - Adds `GREASE_PENCIL_OT_frame_clean_duplicate` operator
Abdelrahman Said added 6 commits 2023-12-30 14:01:55 +01:00
Abdelrahman Said requested review from Falk David 2023-12-30 14:02:39 +01:00
Iliya Katushenock added this to the Grease Pencil project 2023-12-30 14:02:39 +01:00
Pratik Borhade requested changes 2024-01-24 13:15:39 +01:00
Dismissed
Pratik Borhade left a comment
Member

Hi, I checked the PR locally, found few points

Hi, I checked the PR locally, found few points
@ -266,2 +279,3 @@
if (keyframe_region_circle_test(static_cast<const KeyframeEdit_CircleData *>(ked->data),
pt)) {
pt))
{
Member

accidental formatting change. Can you revert this? :)

accidental formatting change. Can you revert this? :)
Author
First-time contributor

Reverted it

Reverted it
amsaid1989 marked this conversation as resolved
@ -359,0 +466,4 @@
bool attrs_equal = true;
attribute_math::convert_to_static_type(attrs_a.varray.type(), [&](auto dummy) {
Member

not sure if this is needed. You could just call std::equal() in current lamda too, no?
I might be misunderstanding something

not sure if this is needed. You could just call `std::equal()` in current lamda too, no? I might be misunderstanding something
Author
First-time contributor

This was implemented based on guidance I got in blender.chat from @mod_moder when I started working on this. This is what was recommended to me to compare all the attributes.

This was implemented based on guidance I got in [blender.chat](blender.chat) from @mod_moder when I started working on this. This is what was recommended to me to compare all the attributes.
amsaid1989 marked this conversation as resolved
@ -359,0 +507,4 @@
continue;
}
std::optional<bke::CurvesGeometry *> current_geo = get_gp_curves_geometry_from_frame_key(
Member

wouldn't get_editable_drawing_at work here?

wouldn't `get_editable_drawing_at` work here?
Author
First-time contributor

You're right.. get_editable_drawing_at works. Updated it

You're right.. `get_editable_drawing_at` works. Updated it
amsaid1989 marked this conversation as resolved
@ -359,0 +509,4 @@
std::optional<bke::CurvesGeometry *> current_geo = get_gp_curves_geometry_from_frame_key(
grease_pencil, layer, current);
std::optional<bke::CurvesGeometry *> next_geo = get_gp_curves_geometry_from_frame_key(
Member

same as above.

Also names can be improved. eg: curves and curves_next

same as above. Also names can be improved. eg: `curves` and `curves_next`
Author
First-time contributor

Switched to get_editable_drawing_at and renamed the variables

Switched to `get_editable_drawing_at` and renamed the variables
amsaid1989 marked this conversation as resolved
@ -359,0 +523,4 @@
frames_to_delete.append(next);
}
for (const FramesMapKey frame : frames_to_delete) {
Member

grease_pencil.remove_frames()

`grease_pencil.remove_frames()`
Author
First-time contributor

When I try to use this grease_pencil.remove_frames(*layer, frames_to_delete); I get a crash. I ran Blender in a debugger to see if I can find what is causing the crash, but I haven't figured out the reason. I am sure I am missing something with this being my first time working with Blender's code. This is the output I get in the terminal after running the test file I am using. I can't see what might be causing the problem so I thought I would share it here in case someone can figure it out.

Traceback (most recent call last):
  File "/home/abdelrahman/.config/blender/4.1/scripts/addons/bone_layer_manager/constraint_operators.py", line 472, in poll
    idx = cbone.constraint_active_index
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'constraint_active_index'
Traceback (most recent call last):
  File "/home/abdelrahman/.config/blender/4.1/scripts/addons/bone_layer_manager/constraint_operators.py", line 370, in poll
    return len(bone.constraints) > 0 and len(context.selected_pose_bones) > 1
               ^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'constraints'
Traceback (most recent call last):
  File "/home/abdelrahman/.config/blender/4.1/scripts/addons/bone_layer_manager/constraint_operators.py", line 404, in poll
    return len(bone.constraints) > 0 and len(context.selected_pose_bones) > 1
               ^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'constraints'
Traceback (most recent call last):
  File "/home/abdelrahman/.config/blender/4.1/scripts/addons/bone_layer_manager/constraint_operators.py", line 443, in poll
    return len(bone.constraints) > 0 and len(context.selected_pose_bones) > 1
               ^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'constraints'
Traceback (most recent call last):
  File "/home/abdelrahman/.config/blender/4.1/scripts/addons/bone_layer_manager/constraint_operators.py", line 260, in poll
    return len(bone.constraints) > 0 and len(context.selected_pose_bones) > 0
               ^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'constraints'
=================================================================
==1796374==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c000027c40 at pc 0x0000047e8a4d bp 0x7fa4ffff03d0 sp 0x7fa4ffff03c0
READ of size 8 at 0x60c000027c40 thread T18
    #0 0x47e8a4c in MEM_lockfree_freeN /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/intern/mallocn_lockfree_impl.c:98
    #1 0x374bfe9 in free_layer_data /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2150
    #2 0x377b79e in CustomDataLayerImplicitSharing::delete_self_with_data() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2312
    #3 0xa5ff14 in blender::ImplicitSharingInfo::remove_user_and_delete_if_last() const /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenlib/BLI_implicit_sharing.hh:145
    #4 0x3750959 in customData_free_layer__internal /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2478
    #5 0x3750cc3 in CustomData_free(CustomData*, int) /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2500
    #6 0x35f7df0 in blender::bke::CurvesGeometry::~CurvesGeometry() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/curves_geometry.cc:174
    #7 0xac1657 in blender::bke::greasepencil::Drawing::~Drawing() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:300
    #8 0xb02cb8 in void MEM_delete<blender::bke::greasepencil::Drawing>(blender::bke::greasepencil::Drawing const*) /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/MEM_guardedalloc.h:292
    #9 0xae30f9 in free_drawing_array /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:2359
    #10 0xabf9f7 in grease_pencil_free_data /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:132
    #11 0xdbf343 in BKE_libblock_free_datablock /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/lib_id_delete.cc:77
    #12 0x46a3088 in blender::deg::deg_free_copy_on_write_datablock(ID*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:1017
    #13 0x46a26fd in blender::deg::deg_update_copy_on_write_datablock(blender::deg::Depsgraph const*, blender::deg::IDNode const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:896
    #14 0x46a35e3 in blender::deg::deg_evaluate_copy_on_write(Depsgraph*, blender::deg::IDNode const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:1032
    #15 0x4729aa1 in operator() /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc:182
    #16 0x4781e16 in __invoke_impl<void, blender::deg::DepsgraphNodeBuilder::add_id_node(ID*)::<lambda(Depsgraph*)>&, Depsgraph*> /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/invoke.h:61
    #17 0x4777ccc in __invoke_r<void, blender::deg::DepsgraphNodeBuilder::add_id_node(ID*)::<lambda(Depsgraph*)>&, Depsgraph*> /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/invoke.h:111
    #18 0x477177f in _M_invoke /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/std_function.h:290
    #19 0x469a772 in std::function<void (Depsgraph*)>::operator()(Depsgraph*) const /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/std_function.h:591
    #20 0x4694a81 in evaluate_node /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval.cc:102
    #21 0x4694ec2 in deg_task_run_func /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval.cc:119
    #22 0x45170de in Task::operator()() const /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenlib/intern/task_pool.cc:166
    #23 0x451c02e in tbb::internal::function_task<Task>::execute() /home/abdelrahman/Sources/programming/blender/lib/linux_x86_64/tbb/include/tbb/task.h:1059
    #24 0x7fa55a59f5b4 in tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::process_bypass_loop(tbb::internal::context_guard_helper<false>&, tbb::task*, long) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x2a5b4) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb)
    #25 0x7fa55a59f8f2 in tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::local_wait_for_all(tbb::task&, tbb::task*) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x2a8f2) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb)
    #26 0x7fa55a587776 in tbb::internal::arena::process(tbb::internal::generic_scheduler&) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x12776) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb)
    #27 0x7fa55a595f9f in tbb::internal::market::process(rml::job&) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x20f9f) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb)
    #28 0x7fa55a599d0d in tbb::internal::rml::private_worker::run() (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x24d0d) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb)
    #29 0x7fa55a599f88 in tbb::internal::rml::private_worker::thread_routine(void*) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x24f88) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb)
    #30 0x7fa54f8aa9ea  (/usr/lib/libc.so.6+0x8c9ea) (BuildId: 8bfe03f6bf9b6a6e2591babd0bbc266837d8f658)
    #31 0x7fa54f92e7cb  (/usr/lib/libc.so.6+0x1107cb) (BuildId: 8bfe03f6bf9b6a6e2591babd0bbc266837d8f658)

0x60c000027c40 is located 0 bytes inside of 128-byte region [0x60c000027c40,0x60c000027cc0)
freed by thread T18 here:
    #0 0x7fa559edfdb2 in __interceptor_free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52
    #1 0x47e8ce9 in MEM_lockfree_freeN /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/intern/mallocn_lockfree_impl.c:110
    #2 0x374bfe9 in free_layer_data /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2150
    #3 0x377b79e in CustomDataLayerImplicitSharing::delete_self_with_data() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2312
    #4 0xa5ff14 in blender::ImplicitSharingInfo::remove_user_and_delete_if_last() const /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenlib/BLI_implicit_sharing.hh:145
    #5 0x3750959 in customData_free_layer__internal /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2478
    #6 0x3750cc3 in CustomData_free(CustomData*, int) /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2500
    #7 0x35f7df0 in blender::bke::CurvesGeometry::~CurvesGeometry() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/curves_geometry.cc:174
    #8 0xac1657 in blender::bke::greasepencil::Drawing::~Drawing() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:300
    #9 0xb02cb8 in void MEM_delete<blender::bke::greasepencil::Drawing>(blender::bke::greasepencil::Drawing const*) /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/MEM_guardedalloc.h:292
    #10 0xae30f9 in free_drawing_array /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:2359
    #11 0xabf9f7 in grease_pencil_free_data /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:132
    #12 0xdbf343 in BKE_libblock_free_datablock /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/lib_id_delete.cc:77
    #13 0x46a3088 in blender::deg::deg_free_copy_on_write_datablock(ID*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:1017
    #14 0x46a26fd in blender::deg::deg_update_copy_on_write_datablock(blender::deg::Depsgraph const*, blender::deg::IDNode const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:896
    #15 0x46a35e3 in blender::deg::deg_evaluate_copy_on_write(Depsgraph*, blender::deg::IDNode const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:1032
    #16 0x4729aa1 in operator() /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc:182
    #17 0x4781e16 in __invoke_impl<void, blender::deg::DepsgraphNodeBuilder::add_id_node(ID*)::<lambda(Depsgraph*)>&, Depsgraph*> /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/invoke.h:61
    #18 0x4777ccc in __invoke_r<void, blender::deg::DepsgraphNodeBuilder::add_id_node(ID*)::<lambda(Depsgraph*)>&, Depsgraph*> /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/invoke.h:111
    #19 0x477177f in _M_invoke /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/std_function.h:290
    #20 0x469a772 in std::function<void (Depsgraph*)>::operator()(Depsgraph*) const /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/std_function.h:591
    #21 0x4694a81 in evaluate_node /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval.cc:102
    #22 0x4694ec2 in deg_task_run_func /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval.cc:119
    #23 0x45170de in Task::operator()() const /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenlib/intern/task_pool.cc:166
    #24 0x451c02e in tbb::internal::function_task<Task>::execute() /home/abdelrahman/Sources/programming/blender/lib/linux_x86_64/tbb/include/tbb/task.h:1059
    #25 0x7fa55a59f5b4 in tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::process_bypass_loop(tbb::internal::context_guard_helper<false>&, tbb::task*, long) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x2a5b4) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb)

previously allocated by thread T0 here:
    #0 0x7fa559ee1359 in __interceptor_malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:69
    #1 0x47e96c4 in MEM_lockfree_mallocN /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/intern/mallocn_lockfree_impl.c:258
    #2 0x4a9dc3c in read_struct /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenloader/intern/readfile.cc:1811
    #3 0x4aa4936 in read_data_into_datamap /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenloader/intern/readfile.cc:2550
    #4 0x4aab6cc in read_libblock /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenloader/intern/readfile.cc:3025
    #5 0x4ab5192 in blo_read_file_internal(FileData*, char const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenloader/intern/readfile.cc:3668
    #6 0x4a88cdb in BLO_read_from_file /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenloader/intern/readblenentry.cc:417
    #7 0x8331f8 in BKE_blendfile_read(char const*, BlendFileReadParams const*, BlendFileReadReport*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/blendfile.cc:1030
    #8 0x48776bd in WM_file_read(bContext*, char const*, ReportList*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:1024
    #9 0x48846f9 in wm_file_read_opwrap /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2744
    #10 0x48857bb in wm_open_mainfile__open /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2870
    #11 0x4884a91 in operator_state_dispatch /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2780
    #12 0x4885995 in wm_open_mainfile_dispatch /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2891
    #13 0x4884d51 in wm_open_mainfile__discard_changes /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2819
    #14 0x4884a91 in operator_state_dispatch /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2780
    #15 0x4885995 in wm_open_mainfile_dispatch /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2891
    #16 0x48859be in wm_open_mainfile_invoke /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2896
    #17 0x482b5a6 in wm_operator_invoke /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:1550
    #18 0x482d47e in wm_operator_call_internal /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:1785
    #19 0x482d587 in WM_operator_name_call_ptr(bContext*, wmOperatorType*, wmOperatorCallContext, PointerRNA*, wmEvent const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:1799
    #20 0x482eb28 in WM_operator_name_call_ptr_with_depends_on_cursor(bContext*, wmOperatorType*, wmOperatorCallContext, PointerRNA*, wmEvent const*, char const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:1988
    #21 0x807c3d6 in ui_apply_but_funcs_after /home/abdelrahman/Sources/programming/blender/blender/source/blender/editors/interface/interface_handlers.cc:1039
    #22 0x81138b0 in ui_popup_handler /home/abdelrahman/Sources/programming/blender/blender/source/blender/editors/interface/interface_handlers.cc:11747
    #23 0x4824085 in wm_handler_ui_call /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:831
    #24 0x48447a9 in wm_handlers_do_intern /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:3333
    #25 0x4845bb1 in wm_handlers_do /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:3450
    #26 0x48501ce in wm_event_do_handlers(bContext*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:4077
    #27 0x47fbb3a in WM_main(bContext*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm.cc:613
    #28 0x80e26b in main /home/abdelrahman/Sources/programming/blender/blender/source/creator/creator.cc:575
    #29 0x7fa54f845ccf  (/usr/lib/libc.so.6+0x27ccf) (BuildId: 8bfe03f6bf9b6a6e2591babd0bbc266837d8f658)

Thread T18 created by T0 here:
    #0 0x7fa559e4a497 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:208
    #1 0x7fa55a599be5 in tbb::internal::rml::private_server::wake_some(int) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x24be5) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb)

SUMMARY: AddressSanitizer: heap-use-after-free /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/intern/mallocn_lockfree_impl.c:98 in MEM_lockfree_freeN
Shadow bytes around the buggy address:
  0x60c000027980: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
  0x60c000027a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x60c000027a80: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x60c000027b00: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
  0x60c000027b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x60c000027c00: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd
  0x60c000027c80: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x60c000027d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x60c000027d80: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x60c000027e00: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x60c000027e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==1796374==ABORTING
When I try to use this `grease_pencil.remove_frames(*layer, frames_to_delete);` I get a crash. I ran Blender in a debugger to see if I can find what is causing the crash, but I haven't figured out the reason. I am sure I am missing something with this being my first time working with Blender's code. This is the output I get in the terminal after running the test file I am using. I can't see what might be causing the problem so I thought I would share it here in case someone can figure it out. ``` Traceback (most recent call last): File "/home/abdelrahman/.config/blender/4.1/scripts/addons/bone_layer_manager/constraint_operators.py", line 472, in poll idx = cbone.constraint_active_index ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'constraint_active_index' Traceback (most recent call last): File "/home/abdelrahman/.config/blender/4.1/scripts/addons/bone_layer_manager/constraint_operators.py", line 370, in poll return len(bone.constraints) > 0 and len(context.selected_pose_bones) > 1 ^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'constraints' Traceback (most recent call last): File "/home/abdelrahman/.config/blender/4.1/scripts/addons/bone_layer_manager/constraint_operators.py", line 404, in poll return len(bone.constraints) > 0 and len(context.selected_pose_bones) > 1 ^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'constraints' Traceback (most recent call last): File "/home/abdelrahman/.config/blender/4.1/scripts/addons/bone_layer_manager/constraint_operators.py", line 443, in poll return len(bone.constraints) > 0 and len(context.selected_pose_bones) > 1 ^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'constraints' Traceback (most recent call last): File "/home/abdelrahman/.config/blender/4.1/scripts/addons/bone_layer_manager/constraint_operators.py", line 260, in poll return len(bone.constraints) > 0 and len(context.selected_pose_bones) > 0 ^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'constraints' ================================================================= ==1796374==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c000027c40 at pc 0x0000047e8a4d bp 0x7fa4ffff03d0 sp 0x7fa4ffff03c0 READ of size 8 at 0x60c000027c40 thread T18 #0 0x47e8a4c in MEM_lockfree_freeN /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/intern/mallocn_lockfree_impl.c:98 #1 0x374bfe9 in free_layer_data /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2150 #2 0x377b79e in CustomDataLayerImplicitSharing::delete_self_with_data() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2312 #3 0xa5ff14 in blender::ImplicitSharingInfo::remove_user_and_delete_if_last() const /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenlib/BLI_implicit_sharing.hh:145 #4 0x3750959 in customData_free_layer__internal /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2478 #5 0x3750cc3 in CustomData_free(CustomData*, int) /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2500 #6 0x35f7df0 in blender::bke::CurvesGeometry::~CurvesGeometry() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/curves_geometry.cc:174 #7 0xac1657 in blender::bke::greasepencil::Drawing::~Drawing() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:300 #8 0xb02cb8 in void MEM_delete<blender::bke::greasepencil::Drawing>(blender::bke::greasepencil::Drawing const*) /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/MEM_guardedalloc.h:292 #9 0xae30f9 in free_drawing_array /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:2359 #10 0xabf9f7 in grease_pencil_free_data /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:132 #11 0xdbf343 in BKE_libblock_free_datablock /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/lib_id_delete.cc:77 #12 0x46a3088 in blender::deg::deg_free_copy_on_write_datablock(ID*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:1017 #13 0x46a26fd in blender::deg::deg_update_copy_on_write_datablock(blender::deg::Depsgraph const*, blender::deg::IDNode const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:896 #14 0x46a35e3 in blender::deg::deg_evaluate_copy_on_write(Depsgraph*, blender::deg::IDNode const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:1032 #15 0x4729aa1 in operator() /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc:182 #16 0x4781e16 in __invoke_impl<void, blender::deg::DepsgraphNodeBuilder::add_id_node(ID*)::<lambda(Depsgraph*)>&, Depsgraph*> /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/invoke.h:61 #17 0x4777ccc in __invoke_r<void, blender::deg::DepsgraphNodeBuilder::add_id_node(ID*)::<lambda(Depsgraph*)>&, Depsgraph*> /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/invoke.h:111 #18 0x477177f in _M_invoke /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/std_function.h:290 #19 0x469a772 in std::function<void (Depsgraph*)>::operator()(Depsgraph*) const /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/std_function.h:591 #20 0x4694a81 in evaluate_node /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval.cc:102 #21 0x4694ec2 in deg_task_run_func /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval.cc:119 #22 0x45170de in Task::operator()() const /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenlib/intern/task_pool.cc:166 #23 0x451c02e in tbb::internal::function_task<Task>::execute() /home/abdelrahman/Sources/programming/blender/lib/linux_x86_64/tbb/include/tbb/task.h:1059 #24 0x7fa55a59f5b4 in tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::process_bypass_loop(tbb::internal::context_guard_helper<false>&, tbb::task*, long) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x2a5b4) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb) #25 0x7fa55a59f8f2 in tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::local_wait_for_all(tbb::task&, tbb::task*) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x2a8f2) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb) #26 0x7fa55a587776 in tbb::internal::arena::process(tbb::internal::generic_scheduler&) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x12776) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb) #27 0x7fa55a595f9f in tbb::internal::market::process(rml::job&) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x20f9f) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb) #28 0x7fa55a599d0d in tbb::internal::rml::private_worker::run() (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x24d0d) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb) #29 0x7fa55a599f88 in tbb::internal::rml::private_worker::thread_routine(void*) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x24f88) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb) #30 0x7fa54f8aa9ea (/usr/lib/libc.so.6+0x8c9ea) (BuildId: 8bfe03f6bf9b6a6e2591babd0bbc266837d8f658) #31 0x7fa54f92e7cb (/usr/lib/libc.so.6+0x1107cb) (BuildId: 8bfe03f6bf9b6a6e2591babd0bbc266837d8f658) 0x60c000027c40 is located 0 bytes inside of 128-byte region [0x60c000027c40,0x60c000027cc0) freed by thread T18 here: #0 0x7fa559edfdb2 in __interceptor_free /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:52 #1 0x47e8ce9 in MEM_lockfree_freeN /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/intern/mallocn_lockfree_impl.c:110 #2 0x374bfe9 in free_layer_data /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2150 #3 0x377b79e in CustomDataLayerImplicitSharing::delete_self_with_data() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2312 #4 0xa5ff14 in blender::ImplicitSharingInfo::remove_user_and_delete_if_last() const /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenlib/BLI_implicit_sharing.hh:145 #5 0x3750959 in customData_free_layer__internal /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2478 #6 0x3750cc3 in CustomData_free(CustomData*, int) /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/customdata.cc:2500 #7 0x35f7df0 in blender::bke::CurvesGeometry::~CurvesGeometry() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/curves_geometry.cc:174 #8 0xac1657 in blender::bke::greasepencil::Drawing::~Drawing() /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:300 #9 0xb02cb8 in void MEM_delete<blender::bke::greasepencil::Drawing>(blender::bke::greasepencil::Drawing const*) /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/MEM_guardedalloc.h:292 #10 0xae30f9 in free_drawing_array /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:2359 #11 0xabf9f7 in grease_pencil_free_data /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/grease_pencil.cc:132 #12 0xdbf343 in BKE_libblock_free_datablock /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/lib_id_delete.cc:77 #13 0x46a3088 in blender::deg::deg_free_copy_on_write_datablock(ID*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:1017 #14 0x46a26fd in blender::deg::deg_update_copy_on_write_datablock(blender::deg::Depsgraph const*, blender::deg::IDNode const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:896 #15 0x46a35e3 in blender::deg::deg_evaluate_copy_on_write(Depsgraph*, blender::deg::IDNode const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc:1032 #16 0x4729aa1 in operator() /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc:182 #17 0x4781e16 in __invoke_impl<void, blender::deg::DepsgraphNodeBuilder::add_id_node(ID*)::<lambda(Depsgraph*)>&, Depsgraph*> /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/invoke.h:61 #18 0x4777ccc in __invoke_r<void, blender::deg::DepsgraphNodeBuilder::add_id_node(ID*)::<lambda(Depsgraph*)>&, Depsgraph*> /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/invoke.h:111 #19 0x477177f in _M_invoke /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/std_function.h:290 #20 0x469a772 in std::function<void (Depsgraph*)>::operator()(Depsgraph*) const /usr/lib/gcc/x86_64-pc-linux-gnu/12.3.0/include/c++/bits/std_function.h:591 #21 0x4694a81 in evaluate_node /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval.cc:102 #22 0x4694ec2 in deg_task_run_func /home/abdelrahman/Sources/programming/blender/blender/source/blender/depsgraph/intern/eval/deg_eval.cc:119 #23 0x45170de in Task::operator()() const /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenlib/intern/task_pool.cc:166 #24 0x451c02e in tbb::internal::function_task<Task>::execute() /home/abdelrahman/Sources/programming/blender/lib/linux_x86_64/tbb/include/tbb/task.h:1059 #25 0x7fa55a59f5b4 in tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::process_bypass_loop(tbb::internal::context_guard_helper<false>&, tbb::task*, long) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x2a5b4) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb) previously allocated by thread T0 here: #0 0x7fa559ee1359 in __interceptor_malloc /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_malloc_linux.cpp:69 #1 0x47e96c4 in MEM_lockfree_mallocN /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/intern/mallocn_lockfree_impl.c:258 #2 0x4a9dc3c in read_struct /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenloader/intern/readfile.cc:1811 #3 0x4aa4936 in read_data_into_datamap /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenloader/intern/readfile.cc:2550 #4 0x4aab6cc in read_libblock /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenloader/intern/readfile.cc:3025 #5 0x4ab5192 in blo_read_file_internal(FileData*, char const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenloader/intern/readfile.cc:3668 #6 0x4a88cdb in BLO_read_from_file /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenloader/intern/readblenentry.cc:417 #7 0x8331f8 in BKE_blendfile_read(char const*, BlendFileReadParams const*, BlendFileReadReport*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/blenkernel/intern/blendfile.cc:1030 #8 0x48776bd in WM_file_read(bContext*, char const*, ReportList*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:1024 #9 0x48846f9 in wm_file_read_opwrap /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2744 #10 0x48857bb in wm_open_mainfile__open /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2870 #11 0x4884a91 in operator_state_dispatch /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2780 #12 0x4885995 in wm_open_mainfile_dispatch /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2891 #13 0x4884d51 in wm_open_mainfile__discard_changes /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2819 #14 0x4884a91 in operator_state_dispatch /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2780 #15 0x4885995 in wm_open_mainfile_dispatch /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2891 #16 0x48859be in wm_open_mainfile_invoke /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_files.cc:2896 #17 0x482b5a6 in wm_operator_invoke /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:1550 #18 0x482d47e in wm_operator_call_internal /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:1785 #19 0x482d587 in WM_operator_name_call_ptr(bContext*, wmOperatorType*, wmOperatorCallContext, PointerRNA*, wmEvent const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:1799 #20 0x482eb28 in WM_operator_name_call_ptr_with_depends_on_cursor(bContext*, wmOperatorType*, wmOperatorCallContext, PointerRNA*, wmEvent const*, char const*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:1988 #21 0x807c3d6 in ui_apply_but_funcs_after /home/abdelrahman/Sources/programming/blender/blender/source/blender/editors/interface/interface_handlers.cc:1039 #22 0x81138b0 in ui_popup_handler /home/abdelrahman/Sources/programming/blender/blender/source/blender/editors/interface/interface_handlers.cc:11747 #23 0x4824085 in wm_handler_ui_call /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:831 #24 0x48447a9 in wm_handlers_do_intern /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:3333 #25 0x4845bb1 in wm_handlers_do /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:3450 #26 0x48501ce in wm_event_do_handlers(bContext*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm_event_system.cc:4077 #27 0x47fbb3a in WM_main(bContext*) /home/abdelrahman/Sources/programming/blender/blender/source/blender/windowmanager/intern/wm.cc:613 #28 0x80e26b in main /home/abdelrahman/Sources/programming/blender/blender/source/creator/creator.cc:575 #29 0x7fa54f845ccf (/usr/lib/libc.so.6+0x27ccf) (BuildId: 8bfe03f6bf9b6a6e2591babd0bbc266837d8f658) Thread T18 created by T0 here: #0 0x7fa559e4a497 in __interceptor_pthread_create /usr/src/debug/gcc/gcc/libsanitizer/asan/asan_interceptors.cpp:208 #1 0x7fa55a599be5 in tbb::internal::rml::private_server::wake_some(int) (/home/abdelrahman/Sources/programming/blender/build_linux_debug/bin/lib/libtbb.so.2+0x24be5) (BuildId: efcc170f66e9a8108477d04e9164946672875ebb) SUMMARY: AddressSanitizer: heap-use-after-free /home/abdelrahman/Sources/programming/blender/blender/intern/guardedalloc/intern/mallocn_lockfree_impl.c:98 in MEM_lockfree_freeN Shadow bytes around the buggy address: 0x60c000027980: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa 0x60c000027a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x60c000027a80: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 0x60c000027b00: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa 0x60c000027b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x60c000027c00: fa fa fa fa fa fa fa fa[fd]fd fd fd fd fd fd fd 0x60c000027c80: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa 0x60c000027d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x60c000027d80: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x60c000027e00: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa 0x60c000027e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==1796374==ABORTING ```
PratikPB2123 marked this conversation as resolved
Member

BTW, PR looks ready enough. Can we remove WIP tag?

BTW, PR looks ready enough. Can we remove WIP tag?
Author
First-time contributor

BTW, PR looks ready enough. Can we remove WIP tag?

Thank you for the review @PratikPB2123.. Sorry, I've been busy at work and missed the notification with your comments. I will address the feedback and remove the WIP tag once done.

> BTW, PR looks ready enough. Can we remove WIP tag? Thank you for the review @PratikPB2123.. Sorry, I've been busy at work and missed the notification with your comments. I will address the feedback and remove the `WIP` tag once done.
Abdelrahman Said added 1 commit 2024-02-11 20:25:37 +01:00
Abdelrahman Said added 5 commits 2024-02-18 01:21:48 +01:00
Abdelrahman Said changed title from WIP: GPv3: Port `frame_clean_duplicate` operator to GPv3: Port `frame_clean_duplicate` operator 2024-02-18 02:01:44 +01:00
Author
First-time contributor

@PratikPB2123 I addressed most of your feedback, but not sure what you want me to do regarding the 2 comments I left above.

@PratikPB2123 I addressed most of your feedback, but not sure what you want me to do regarding the 2 comments I left above.
Member

Hi, sorry I missed the notification. Will check again :)
Since this is mostly about attributes, I think Falk and Hans are perfect for the further review.

Hi, sorry I missed the notification. Will check again :) Since this is mostly about attributes, I think Falk and Hans are perfect for the further review.
Pratik Borhade requested review from Hans Goudey 2024-03-22 12:36:20 +01:00
Pratik Borhade requested changes 2024-04-12 11:57:43 +02:00
Dismissed
Pratik Borhade left a comment
Member

Hi, can you merge latest main branch in your PR to update it? After 1b65faddd0 get_editable_drawing_at now requires layer reference instead of pointer.

To update PR branch (also see this docs):

  • run make update on main branch
  • git checkout gpv3-delete-duplicate-frames
  • git merge main
Hi, can you merge latest main branch in your PR to update it? After 1b65faddd07af00c401ee48a847fc24c51cec45b `get_editable_drawing_at` now requires layer reference instead of pointer. To update PR branch (also see [this docs](https://developer.blender.org/docs/handbook/contributing/pull_requests/#update-a-pull-request)): - run `make update` on main branch - git checkout gpv3-delete-duplicate-frames - git merge main
@ -359,0 +490,4 @@
continue;
}
Drawing *drawing = grease_pencil.get_editable_drawing_at(layer, current);
Member

get_editable_drawing_at accepts layer reference. So pass *layer

`get_editable_drawing_at` accepts layer reference. So pass `*layer`
amsaid1989 marked this conversation as resolved
@ -359,0 +491,4 @@
}
Drawing *drawing = grease_pencil.get_editable_drawing_at(layer, current);
Drawing *drawing_next = grease_pencil.get_editable_drawing_at(layer, next);
Member

same as above

same as above
Author
First-time contributor

Updated all uses of get_editable_drawing_at to pass a Layer & instead of Layer *

Updated all uses of `get_editable_drawing_at` to pass a `Layer &` instead of `Layer *`
amsaid1989 marked this conversation as resolved
Pratik Borhade reviewed 2024-04-12 13:25:31 +02:00
Pratik Borhade left a comment
Member

bit confused about these 2 checks. This will fail the operation in some cases.
For example: when keyframe is not duplicated but instead the strokes are copied between two adjacent drawings

bit confused about these 2 checks. This will fail the operation in some cases. For example: when keyframe is not duplicated but instead the strokes are copied between two adjacent drawings
@ -359,0 +388,4 @@
}
if (attrs_span_a.data() != attrs_span_b.data()) {
return false;
Member

I'm not sure why this check is needed.

I'm not sure why this check is needed.

This should be

if (attrs_span_a.data() == attrs_span_b.data()) {
  return true;
}
This should be ```Cpp if (attrs_span_a.data() == attrs_span_b.data()) { return true; } ```
Member

Make sense. Maybe same for other if() that I mentioned

Make sense. Maybe same for other `if()` that I mentioned
Author
First-time contributor

Updated the check to what @mod_moder suggested

Updated the check to what @mod_moder suggested
amsaid1989 marked this conversation as resolved
@ -359,0 +431,4 @@
const Set<AttributeIDRef> ids_a = attributes_a.all_ids();
const Set<AttributeIDRef> ids_b = attributes_b.all_ids();
if (ids_a != ids_b) {
Member

Not sure why this check is needed.

Not sure why this check is needed.

In case lists of attributes are different, i think this is reasonable to treat such curves as different..

In case lists of attributes are different, i think this is reasonable to treat such curves as different..
Author
First-time contributor

I will leave this check as is since @mod_moder agrees it's needed

I will leave this check as is since @mod_moder agrees it's needed
Member

I see, make sense.

I see, make sense.
PratikPB2123 marked this conversation as resolved
Abdelrahman Said added 1 commit 2024-04-13 23:02:02 +02:00
Abdelrahman Said added 1 commit 2024-04-13 23:57:35 +02:00
Author
First-time contributor

@PratikPB2123 I have merged the main branch and addressed the feedback.

@PratikPB2123 I have merged the `main` branch and addressed the feedback.
Pratik Borhade requested changes 2024-04-15 12:31:03 +02:00
Dismissed
Pratik Borhade left a comment
Member

Hi, thanks for updating the PR. Works correctly for me so far. AFAICS, only "BKE_curves.hh" header file is required. Code complies fine without rest of headers that you added :)

Hi, thanks for updating the PR. Works correctly for me so far. AFAICS, only `"BKE_curves.hh"` header file is required. Code complies fine without rest of headers that you added :)
@ -30,2 +42,4 @@
#include "WM_api.hh"
#include <algorithm>
#include <optional>
Member

These headers are not needed.

These headers are not needed.
amsaid1989 marked this conversation as resolved
Member

Also add operator in UI, this menu: VIEW3D_MT_edit_greasepencil_cleanup

Also add operator in UI, this menu: `VIEW3D_MT_edit_greasepencil_cleanup`
Abdelrahman Said added 2 commits 2024-04-16 21:38:04 +02:00
Author
First-time contributor

@PratikPB2123 Done. Removed the unnecessary header and added the operator to the menu.

@PratikPB2123 Done. Removed the unnecessary header and added the operator to the menu.
Member

Thanks. Among the all headers you added, only "BKE_curves.hh" is needed. You can remove rest all.

Thanks. Among the all headers you added, only `"BKE_curves.hh"` is needed. You can remove rest all.
Abdelrahman Said added 1 commit 2024-04-17 23:13:20 +02:00
Author
First-time contributor

Thanks. Among the all headers you added, only "BKE_curves.hh" is needed. You can remove rest all.

Sorry. I misunderstood and thought you only wanted me to remove the 2 headers you mentioned. All removed now.

> Thanks. Among the all headers you added, only `"BKE_curves.hh"` is needed. You can remove rest all. Sorry. I misunderstood and thought you only wanted me to remove the 2 headers you mentioned. All removed now.
Pratik Borhade requested changes 2024-04-18 13:07:10 +02:00
Dismissed
Pratik Borhade left a comment
Member

Hi, found a crash with empty drawings. Attaching .blend file in case needed

Hi, found a crash with empty drawings. Attaching .blend file in case needed
@ -412,0 +462,4 @@
if (curves_a.curves_num() != curves_b.curves_num() ||
curves_a.points_num() != curves_b.points_num() || curves_a.offsets() != curves_b.offsets())
{
Member

here offset() memory is garbage if curves has empty drawing. This would lead to crash. Just add one if condition before this to return true when both the curves has 0 points:

  if ((curves_a.points_num() == 0) && (curves_b.points_num() == 0)) {
    return true;
  }
here offset() memory is garbage if curves has empty drawing. This would lead to crash. Just add one if condition before this to return true when both the curves has 0 points: ``` if ((curves_a.points_num() == 0) && (curves_b.points_num() == 0)) { return true; } ```
Author
First-time contributor

Fixed it. Thank you very much for catching it

Fixed it. Thank you very much for catching it
amsaid1989 marked this conversation as resolved
Abdelrahman Said added 1 commit 2024-04-19 01:18:33 +02:00
Pratik Borhade approved these changes 2024-04-19 12:42:15 +02:00
Pratik Borhade left a comment
Member

Thanks. Looks correct to me 🙂

Let's wait for Falk/Hans/Iliya for further review of attribute comparison code.

Thanks. Looks correct to me 🙂 Let's wait for Falk/Hans/Iliya for further review of attribute comparison code.
Iliya Katushenock reviewed 2024-04-19 15:43:09 +02:00
@ -412,0 +423,4 @@
const GSpan attrs_span_a = attrs_a.varray.get_internal_span();
const GSpan attrs_span_b = attrs_b.varray.get_internal_span();
if (attrs_span_a.size() != attrs_span_b.size()) {

You have check size few lines above, right?

You have check size few lines above, right?
Author
First-time contributor

Removed this extra size check

Removed this extra size check
amsaid1989 marked this conversation as resolved
@ -412,0 +487,4 @@
return false;
}
bool attrs_equal = true;

attrs_equal -> attributes_are_equal

`attrs_equal` -> `attributes_are_equal`
Author
First-time contributor

Renamed the variable

Renamed the variable
amsaid1989 marked this conversation as resolved
@ -412,0 +520,4 @@
const Span<FramesMapKey> &keys = layer->sorted_keys();
Vector<FramesMapKey> frames_to_delete = {};
for (size_t i = 0; i < keys.size(); ++i) {

for (size_t i = 0; i < keys.size(); ++i) { and if (i + 1 >= keys.size()) {
->
const int i : keys.index_range().drop_front(1)

.... ?

`for (size_t i = 0; i < keys.size(); ++i) {` and `if (i + 1 >= keys.size()) {` -> `const int i : keys.index_range().drop_front(1)` .... ?
Author
First-time contributor

I needed const int i : keys.index_range().drop_back(1) instead of const int i : keys.index_range().drop_front(1)

I needed `const int i : keys.index_range().drop_back(1)` instead of `const int i : keys.index_range().drop_front(1)`
mod_moder marked this conversation as resolved
@ -412,0 +525,4 @@
break;
}
FramesMapKey current = keys[i];

Can be const?

Can be const?
Author
First-time contributor

Changed to const

Changed to `const`
amsaid1989 marked this conversation as resolved
Abdelrahman Said added 1 commit 2024-04-20 15:34:24 +02:00
Author
First-time contributor

Thanks. Looks correct to me 🙂

Let's wait for Falk/Hans/Iliya for further review of attribute comparison code.

Thank you for your help, @PratikPB2123 😊

> Thanks. Looks correct to me 🙂 > > Let's wait for Falk/Hans/Iliya for further review of attribute comparison code. Thank you for your help, @PratikPB2123 😊
Abdelrahman Said added 4 commits 2024-04-20 16:36:32 +02:00
Abdelrahman Said added 1 commit 2024-04-24 23:45:13 +02:00
Author
First-time contributor

@mod_moder Let me know if there are any changes you would like me to make

@mod_moder Let me know if there are any changes you would like me to make
Iliya Katushenock reviewed 2024-04-28 22:48:00 +02:00
@ -413,0 +429,4 @@
}
}
return true;

Should be false.

Should be false.
Author
First-time contributor

Done

Done
amsaid1989 marked this conversation as resolved
@ -413,0 +481,4 @@
GAttributeReader attrs_b = attributes_b.lookup(id);
if (!attributes_varrays_are_equal(attrs_a, attrs_b)) {
return false;
if (attributes_varrays_are_equal(attrs_a, attrs_b)) {
  return true;
}
```Cpp if (attributes_varrays_are_equal(attrs_a, attrs_b)) { return true; } ```
Author
First-time contributor

Done

Done
amsaid1989 marked this conversation as resolved
@ -413,0 +515,4 @@
}
const Span<FramesMapKey> &keys = layer->sorted_keys();
Vector<FramesMapKey> frames_to_delete = {};

Vector<FramesMapKey> frames_to_delete;

`Vector<FramesMapKey> frames_to_delete;`
Author
First-time contributor

Done

Done
amsaid1989 marked this conversation as resolved
Abdelrahman Said added 1 commit 2024-04-29 22:15:11 +02:00
Author
First-time contributor

@mod_moder Addressed your latest feedback

@mod_moder Addressed your latest feedback
Iliya Katushenock reviewed 2024-04-30 00:20:00 +02:00
@ -413,0 +489,4 @@
attribute_math::convert_to_static_type(attrs_a.varray.type(), [&](auto dummy) {
using T = decltype(dummy);
attributes_are_equal = attributes_elements_are_equal<T>(attrs_a, attrs_b);

Right now this is incorrect.
if (attributes_varrays_are_equal(attrs_a, attrs_b)) { is used for early skip if this is possible (arrays is actually is the same data segment in memory).
But right now you also have to check if this is obviously impossible (different types or sizes).
If you'll do this cast for attributes with different sizes/types, this will be UB and assertion in debug.
You need to explicitly check if attributes_varrays_not_equal before of this.
And additional cleanup comment: upcast to static type for attributes should be on the caller, not in the template method.

Right now this is incorrect. `if (attributes_varrays_are_equal(attrs_a, attrs_b)) {` is used for early skip if this is possible (arrays is actually is the same data segment in memory). But right now you also have to check if this is obviously impossible (different types or sizes). If you'll do this cast for attributes with different sizes/types, this will be UB and assertion in debug. You need to explicitly check if `attributes_varrays_not_equal` before of this. And additional cleanup comment: upcast to static type for attributes should be on the caller, not in the template method.
Author
First-time contributor

@mod_moder I have addressed your comments about the varrays check.

Renamed attributes_varrays_are_equal to attributes_varrays_span_data_equal and updated it to this:

static bool attributes_varrays_span_data_equal(const bke::GAttributeReader &attrs_a,
                                         const bke::GAttributeReader &attrs_b)
{
  if (attrs_a.varray.is_span() && attrs_b.varray.is_span()) {
    const GSpan attrs_span_a = attrs_a.varray.get_internal_span();
    const GSpan attrs_span_b = attrs_b.varray.get_internal_span();

    if (attrs_span_a.data() == attrs_span_b.data()) {
      return true;
    }
  }

  return false;
}

Then, I added attributes_varrays_not_equal which is implemented as follows:

static bool attributes_varrays_not_equal(const bke::GAttributeReader &attrs_a,
                                         const bke::GAttributeReader &attrs_b)
{
  return (attrs_a.varray.size() != attrs_b.varray.size() ||
          attrs_a.varray.type() != attrs_b.varray.type());
}

These 2 functions are then used like this:

if (attributes_varrays_span_data_equal(attrs_a, attrs_b)) {
	return true;
}

if (attributes_varrays_not_equal(attrs_a, attrs_b)) {
	return false;
}

Does this make more sense?

@mod_moder I have addressed your comments about the varrays check. Renamed `attributes_varrays_are_equal` to `attributes_varrays_span_data_equal` and updated it to this: ```cpp static bool attributes_varrays_span_data_equal(const bke::GAttributeReader &attrs_a, const bke::GAttributeReader &attrs_b) { if (attrs_a.varray.is_span() && attrs_b.varray.is_span()) { const GSpan attrs_span_a = attrs_a.varray.get_internal_span(); const GSpan attrs_span_b = attrs_b.varray.get_internal_span(); if (attrs_span_a.data() == attrs_span_b.data()) { return true; } } return false; } ``` Then, I added `attributes_varrays_not_equal` which is implemented as follows: ```cpp static bool attributes_varrays_not_equal(const bke::GAttributeReader &attrs_a, const bke::GAttributeReader &attrs_b) { return (attrs_a.varray.size() != attrs_b.varray.size() || attrs_a.varray.type() != attrs_b.varray.type()); } ``` These 2 functions are then used like this: ```cpp if (attributes_varrays_span_data_equal(attrs_a, attrs_b)) { return true; } if (attributes_varrays_not_equal(attrs_a, attrs_b)) { return false; } ``` Does this make more sense?
Author
First-time contributor

And additional cleanup comment: upcast to static type for attributes should be on the caller, not in the template method.

Regarding this, I would like to confirm that I understand you correctly.

You want to change the lambda in convert_to_static_type to this:

attribute_math::convert_to_static_type(attrs_a.varray.type(), [&](auto dummy) {
  using T = decltype(dummy);

  const VArray attributes_a = attrs_a.varray.typed<T>();
  const VArray attributes_b = attrs_b.varray.typed<T>();

  attributes_are_equal = attributes_elements_are_equal(attributes_a, attributes_b);
});

And change the attributes_elements_are_equal to the following:

template<typename T>
static bool attributes_elements_are_equal(const VArray<T> &attributes_a,
                                          const VArray<T> &attributes_b)
{
  const std::optional<T> value_a = attributes_a.get_if_single();
  const std::optional<T> value_b = attributes_b.get_if_single();
  if (value_a.has_value() && value_b.has_value()) {
    return value_a.value() == value_b.value();
  }

  const VArraySpan attrs_span_a = attributes_a;
  const VArraySpan attrs_span_b = attributes_b;

  return std::equal(
      attrs_span_a.begin(), attrs_span_a.end(), attrs_span_b.begin(), attrs_span_b.end());
}
> And additional cleanup comment: upcast to static type for attributes should be on the caller, not in the template method. Regarding this, I would like to confirm that I understand you correctly. You want to change the lambda in `convert_to_static_type` to this: ```cpp attribute_math::convert_to_static_type(attrs_a.varray.type(), [&](auto dummy) { using T = decltype(dummy); const VArray attributes_a = attrs_a.varray.typed<T>(); const VArray attributes_b = attrs_b.varray.typed<T>(); attributes_are_equal = attributes_elements_are_equal(attributes_a, attributes_b); }); ``` And change the `attributes_elements_are_equal` to the following: ```cpp template<typename T> static bool attributes_elements_are_equal(const VArray<T> &attributes_a, const VArray<T> &attributes_b) { const std::optional<T> value_a = attributes_a.get_if_single(); const std::optional<T> value_b = attributes_b.get_if_single(); if (value_a.has_value() && value_b.has_value()) { return value_a.value() == value_b.value(); } const VArraySpan attrs_span_a = attributes_a; const VArraySpan attrs_span_b = attributes_b; return std::equal( attrs_span_a.begin(), attrs_span_a.end(), attrs_span_b.begin(), attrs_span_b.end()); } ```

Order of attributes_varrays_span_data_equal and attributes_varrays_not_equal can be changed (first - early skip of wrong types and sizes, and next early confirm that data is the same). This looks good now.

Regarding this, I would like to confirm that I understand you correctly.

Yes, this is correct.

Order of `attributes_varrays_span_data_equal` and `attributes_varrays_not_equal` can be changed (first - early skip of wrong types and sizes, and next early confirm that data is the same). This looks good now. > Regarding this, I would like to confirm that I understand you correctly. Yes, this is correct.
Author
First-time contributor

Great.. Thank you very much. Updated the PR.

Great.. Thank you very much. Updated the PR.
amsaid1989 marked this conversation as resolved
Abdelrahman Said added 1 commit 2024-05-04 17:38:05 +02:00
Abdelrahman Said added 2 commits 2024-05-04 19:43:01 +02:00
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u gpv3-delete-duplicate-frames:amsaid1989-gpv3-delete-duplicate-frames
git checkout amsaid1989-gpv3-delete-duplicate-frames
Sign in to join this conversation.
No Label
Interest
Alembic
Interest
Animation & Rigging
Interest
Asset Browser
Interest
Asset Browser Project Overview
Interest
Audio
Interest
Automated Testing
Interest
Blender Asset Bundle
Interest
BlendFile
Interest
Collada
Interest
Compatibility
Interest
Compositing
Interest
Core
Interest
Cycles
Interest
Dependency Graph
Interest
Development Management
Interest
EEVEE
Interest
EEVEE & Viewport
Interest
Freestyle
Interest
Geometry Nodes
Interest
Grease Pencil
Interest
ID Management
Interest
Images & Movies
Interest
Import Export
Interest
Line Art
Interest
Masking
Interest
Metal
Interest
Modeling
Interest
Modifiers
Interest
Motion Tracking
Interest
Nodes & Physics
Interest
OpenGL
Interest
Overlay
Interest
Overrides
Interest
Performance
Interest
Physics
Interest
Pipeline, Assets & IO
Interest
Platforms, Builds & Tests
Interest
Python API
Interest
Render & Cycles
Interest
Render Pipeline
Interest
Sculpt, Paint & Texture
Interest
Text Editor
Interest
Translations
Interest
Triaging
Interest
Undo
Interest
USD
Interest
User Interface
Interest
UV Editing
Interest
VFX & Video
Interest
Video Sequencer
Interest
Virtual Reality
Interest
Vulkan
Interest
Wayland
Interest
Workbench
Interest: X11
Legacy
Blender 2.8 Project
Legacy
Milestone 1: Basic, Local Asset Browser
Legacy
OpenGL Error
Meta
Good First Issue
Meta
Papercut
Meta
Retrospective
Meta
Security
Module
Animation & Rigging
Module
Core
Module
Development Management
Module
EEVEE & Viewport
Module
Grease Pencil
Module
Modeling
Module
Nodes & Physics
Module
Pipeline, Assets & IO
Module
Platforms, Builds & Tests
Module
Python API
Module
Render & Cycles
Module
Sculpt, Paint & Texture
Module
Triaging
Module
User Interface
Module
VFX & Video
Platform
FreeBSD
Platform
Linux
Platform
macOS
Platform
Windows
Priority
High
Priority
Low
Priority
Normal
Priority
Unbreak Now!
Status
Archived
Status
Confirmed
Status
Duplicate
Status
Needs Info from Developers
Status
Needs Information from User
Status
Needs Triage
Status
Resolved
Type
Bug
Type
Design
Type
Known Issue
Type
Patch
Type
Report
Type
To Do
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: blender/blender#116655
No description provided.