From 4a71ebdece3ce5f341dd22a332bd1f2124f00235 Mon Sep 17 00:00:00 2001 From: Petru Conduraru Date: Sat, 11 Jul 2026 20:05:54 +0300 Subject: [PATCH] ifcopenshell: fix geom.iterator memory growth on the OCC path #6904 On the pythonOCC path (use_python_opencascade=True) the iterator emits SERIALIZED elements, deserialized per element by create_shape_from_serialization. For OCC >= 7.8 this used the single-argument breptools.ReadFromString(brep_data) overload, which pythonOCC documents as allocating and returning a new TopoDS_Shape on every call ("increases memory"); the by-reference overload ReadFromString(brep_data, shape) exists specifically to prevent that growth. Use the by-reference overload, with a TypeError fallback for older bindings that only expose the single-argument form. Generated with the assistance of an AI coding tool. Co-Authored-By: Claude Opus 4.8 --- src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py index 15a4dfc838..9d0dae148f 100644 --- a/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py +++ b/src/ifcopenshell-python/ifcopenshell/geom/occ_utils.py @@ -295,8 +295,16 @@ def create_shape_from_serialization( ss.ReadFromString(brep_data) occ_shape = ss.Shape(ss.NbShapes()) else: + # The single-argument breptools.ReadFromString allocates and returns + # a new TopoDS_Shape on every call, which pythonOCC documents as + # increasing memory; pass the shape by reference to reuse it instead + # and fall back for older bindings lacking that overload. See #6904. ss = BRepTools.breptools() - occ_shape = ss.ReadFromString(brep_data) + occ_shape = TopoDS.TopoDS_Shape() + try: + ss.ReadFromString(brep_data, occ_shape) + except TypeError: + occ_shape = ss.ReadFromString(brep_data) except BaseException as e: print("Error occurred parsing a shape from a string:", e)