This is a proof of concept patch that fixes T88026, using similar logic to other pointers that are shared between original & evaluated data.
This patch implements the following logic:
- The shared pointer for rigidbody and softbody is only ever copied when performing ID duplication into same Main (not when NO_MAIN tag).
- The depsgraph temporarily sets this shared pointer and clears it before freeing the ID data.
- This way when the shared pointer is set, it can always be freed without the possibility of causing a double-free or having to use ID tags to detect if it should be freed or not (as is currently done). This is error prone as any code that changes tags would need to run logic that update pointer ownership too (which seems unnecessarily complicated)
Open Topics
There are some things to consider with this patch.
- Should we consider this shared pointer to be part of the object that should not be lost (just as we would not want to loose custom-properties or material list).
Currently this pointer contains point-cache for softbody, which is written/read to a file.
- Accessing the shared pointer on the NO_MAIN copy requires looking up the original ID.
So BKE_libblock_management_main_add (currently unused) for example, won't get the shared pointer set unless there are explicit checks to do so. (currently the shared pointers aren't handled either).
- This leaves the shared pointer set to NULL, while I couldn't cause a case where this caused a NULL pointer de-reference, it's possible there are situations where the data can be NULL where as before it wouldn't have been.