diff --git a/src/ifcopenshell-python/ifcopenshell/entity_instance.py b/src/ifcopenshell-python/ifcopenshell/entity_instance.py index 3941e2263f..0d59732dac 100644 --- a/src/ifcopenshell-python/ifcopenshell/entity_instance.py +++ b/src/ifcopenshell-python/ifcopenshell/entity_instance.py @@ -131,6 +131,13 @@ class entity_instance(object): """ self.wrapped_data.file = None + @property + def file(self): + # ugh circular imports, name collisions + from . import file + + return file.file.from_pointer(self.wrapped_data.file_pointer()) + def __getattr__(self, name): INVALID, FORWARD, INVERSE = range(3) attr_cat = self.wrapped_data.get_attribute_category(name) diff --git a/src/ifcopenshell-python/ifcopenshell/file.py b/src/ifcopenshell-python/ifcopenshell/file.py index ad0e2d1344..7c0df7665f 100644 --- a/src/ifcopenshell-python/ifcopenshell/file.py +++ b/src/ifcopenshell-python/ifcopenshell/file.py @@ -176,6 +176,9 @@ class Transaction: pass +file_dict = {} + + class file(object): """Base class for containing IFC files. @@ -249,6 +252,8 @@ class file(object): self.future = [] self.transaction = None + file_dict[self.file_pointer()] = self + def set_history_size(self, size): self.history_size = size while len(self.history) > self.history_size: @@ -543,10 +548,18 @@ class file(object): unzipped_path = path.with_suffix(format) path.rename(unzipped_path) with zipfile.ZipFile(path, "w") as zip_file: - zip_file.write(unzipped_path, unzipped_path.name, compress_type=zipfile.ZIP_DEFLATED) + zip_file.write( + unzipped_path, + unzipped_path.name, + compress_type=zipfile.ZIP_DEFLATED, + ) unzipped_path.unlink() return @staticmethod def from_string(s): return file(ifcopenshell_wrapper.read(s)) + + @staticmethod + def from_pointer(v): + return file_dict.get(v) diff --git a/src/ifcwrap/IfcParseWrapper.i b/src/ifcwrap/IfcParseWrapper.i index 04e79d91e9..b9fcd5aadd 100644 --- a/src/ifcwrap/IfcParseWrapper.i +++ b/src/ifcwrap/IfcParseWrapper.i @@ -116,6 +116,12 @@ static IfcUtil::ArgumentType helper_fn_attribute_type(const IfcUtil::IfcBaseClas %} %extend IfcParse::IfcFile { + // Use to correlate to entity_instance.file_pointer, so that we + // can trace file ownership of instances on the python side. + size_t file_pointer() const { + return reinterpret_cast($self); + } + IfcUtil::IfcBaseClass* by_guid(const std::string& guid) { return $self->instance_by_guid(guid); }