В линейке Blender 2.8x система отмены операций undo/redo (ctrl+z / ctrl+shift+z) была полностью переделана по сравнению с линейкой 2.7x. Одним из результатов такого изменения API является то, что при выполнении операции отмены все объекты в сцене перестраиваются заново – текущий объект уничтожается, а вместо него создается совершенно новый объект. Ссылки, которые указывали на старый объект, до выполнения операции отмены, после нее указывают на невалидный объект с которым больше нельзя работать.
Такое поведение описано в официальной документации Blender Python API.
Проверить на практике это можно выполнив простой код в Python Console:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
obj = bpy.context.active_object print(obj) # <bpy_struct, Object("Suzanne")> # выполнить любые действия, например, сдвинуть объект # g - z - 1 - ввод # выполнить отмену # ctrl+z print(obj) # <bpy_struct, Object invalid> |
Также теряют целостность любые списки объектов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
lst = bpy.context.selected_objects[:] print(last) # [bpy.data.objects['Suzanne'], bpy.data.objects['Cube']] print(bpy.context.active_object) # bpy.data.objects['Suzanne'] bpy.context.active_object in lst # True # выполнить действия с отменой print(lst) # [<bpy_struct, Object invalid>, <bpy_struct, Object invalid>] print(bpy.context.active_object) # bpy.data.objects['Suzanne'] bpy.context.active_object in lst # False |
Чем все это оборачивается на практике?
Остерегайтесь использовать в коде долговременные ссылки на объекты и списки объектов. Если пользователь имеет возможность нажать ctrl+z в течение времени жизни такой ссылки или списка – они придут в негодность!