I am writing addon, that adds keyframes to a group of objects at a time.
In example .blend file I created two objects: Group_obj1 and Group_obj2.
If you select both of them and go to View3D > Sidebar > View Tab > Group Poses you can add keyframes to both of them when you hit Add Keypose button, both object will get keyframes by location at frame 1.
What I do next to break addon:
Go to frame 100. Hit button Add Keypose
Go to frame 150 and change Y location of one of the objects. Hit Add Keypose
Press Ctrl+Z so keyframes in frame 150 are not set.
Hit Add Keypose again and I get an error:
Traceback (most recent call last):
File "C:\Program Files\Blender Foundation\Blender 2.83\2.83\scripts\addons\out_exmpl\__init__.py", line 98, in execute
GroupObjectsData.add_keypose(current_frame)
File "C:\Program Files\Blender Foundation\Blender 2.83\2.83\scripts\addons\out_exmpl\__init__.py", line 27, in add_keypose
x, y, z = obj.location
ReferenceError: StructRNA of type Object has been removed
How can I handle this Undo, so nothing breaks?
I want to keep all backend associated with inserting keyframes and other animation stuff in my own class GroupObjects, which is not inherrited from bpy.
In general you simply can’t keep references to Blender objects in a global variable like this. Even without undo, those objects may be deleted and the references may become invalid.
If you want to keep references, you have to either use a PointerProperty and store them on a Blender data structure somewhere, or only store them for the lifetime of an operator.
I thought I could use references, since I don’t do shallow or deep copy of the objects. However, it seems not the case (
I need to store objects in some class permanently and do not like the idea to store them for the operator lifetime.
Do you have and idea where is it better to store Pointer? In scene? What is the best practice for that?
If you came across any good examples of using PointerProperty, I would be really greatful
The scene may be a good place, or maybe there is no need to keep a list, and rather some data should be attached to objects. It all depends on the use case.
It’s often tempting to store all your data together in a way that’s most convenient for UI drawing or operators. But that also tends to not work well with object delete, duplicate, append, undo, etc.
I usually store the data as some kind of key, usually the name, and look it up when I need it. But it’s also kind of bad practice to write an addon where this becomes an issue. If you re-write your addon as a modal operator, maybe you can avoid the problem to begin with.