commit 1cfdc2309880e5d96eabd7fafb2a246e00019693
parent beac0350209306bb92dc601bf99633fe0eb662cc
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 9 Jul 2026 18:11:29 +0200
Fix the release of a Scene View
A view's geometry cache stores, for each shape, its geometry associated
with the identifier as defined in user space. When the user detaches
these shapes from a scene, the active views are notified of this
detachment and then store the identifiers of the detached shapes in
order to remove their geometry from the cache when the view is no longer
active.
The problem is that, in the meantime, the user may have detached,
reattached, and then detached the same shape again. The shape is then
referenced twice in the list of geometries to be removed from the view's
cache, whereas only its first occurrence should be taken into account.
This was not the case.
Another scenario leading to the same situation occurs when a shape is
deleted before another is created immediately afterward, so that the
newly created shape has the same identifier as the previous one, even
though it is an entirely new shape. Adding this new shape to the scene,
then removing it, records the removal in the views that are still
active-even though it involves a shape that does not exist in those
views. Although this scenario may seem more critical, the problem is
actually the same as in the situation mentioned earlier. In both cases,
a shape can only be removed from the cache if it is present there. This
applies only to the first occurrence of an identifier; the others should
simply be ignored.
Note that it would be possible to determine whether a shape's geometry
has already been marked for removal from the cache. This would prevent
the same shape identifier from being saved multiple times. However, this
would require a more complex associative structure, which does not seem
warranted in this context.
Diffstat:
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/src/s3d_scene_view.c b/src/s3d_scene_view.c
@@ -1073,8 +1073,21 @@ scene_view_release(ref_T* ref)
FOR_EACH(i, 0, n) {
const unsigned shape_id = darray_uint_cdata_get(&scnview->detached_shapes)[i];
struct geometry** pgeom = htable_geom_find(&scnview->cached_geoms, &shape_id);
- struct geometry* geom = *pgeom;
+ struct geometry* geom = NULL;
size_t tmp; (void)tmp;
+
+ /* It is possible that there is no geometry in the cache associated with the
+ * registered shape Id. This is the sign that this geometry has already
+ * been removed from the cache, and that its shape has been detached several
+ * times from the scene while the scene view was active.
+ *
+ * Indeed, each detachment is simply saved in the "detached shapes" list,
+ * without checking that the shape has already been saved as being to be
+ * detached. In other words, only the first occurrence of the shape in the
+ * said list is valid, the others must be ignored. */
+ if(pgeom == NULL) { ASSERT(n > 0); continue; }
+
+ geom = *pgeom;
scene_view_destroy_geometry(scnview, geom);
tmp = htable_geom_erase(&scnview->cached_geoms, &shape_id);
ASSERT(tmp == 1);