mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-23 17:26:30 +00:00
ifcpatch: fix MergeProjects context deduplication and remove stale stub
Contexts were deleted with remove_deep2 into a single set, but file.add() inflates inverse counts causing phantom references. Split into coord_ops (0 real inverses, remove_deep2 recurses to clean IfcProjectedCRS) and contexts (sorted parent-first so phantoms don't become dangling references). Remove stale MakeVolume stub from ifcopenshell_wrapper.pyi. Generated with the assistance of an AI coding tool.
This commit is contained in:
committed by
Ryan Schultz
parent
6441c39c4e
commit
3c18964eb1
@@ -390,12 +390,6 @@ class JsonSerializer:
|
|||||||
def setFile(self, arg2): ...
|
def setFile(self, arg2): ...
|
||||||
def writeHeader(self): ...
|
def writeHeader(self): ...
|
||||||
|
|
||||||
# TODO: MakeVolume is ignored in SWIG, remove from stub once build is bumped.
|
|
||||||
class MakeVolume:
|
|
||||||
defaultvalue: Any
|
|
||||||
description: Any
|
|
||||||
name: Any
|
|
||||||
|
|
||||||
class OpaqueCoordinate_3:
|
class OpaqueCoordinate_3:
|
||||||
def __init__(self, *args): ...
|
def __init__(self, *args): ...
|
||||||
def get(self, i): ...
|
def get(self, i): ...
|
||||||
|
|||||||
@@ -158,7 +158,8 @@ class Patcher(ifcpatch.BasePatcher):
|
|||||||
return ifcopenshell.util.unit.get_full_unit_name(length_unit)
|
return ifcopenshell.util.unit.get_full_unit_name(length_unit)
|
||||||
|
|
||||||
def reuse_existing_contexts(self) -> None:
|
def reuse_existing_contexts(self) -> None:
|
||||||
to_delete = set()
|
contexts_to_delete: set[int] = set()
|
||||||
|
coord_ops_to_delete: set[int] = set()
|
||||||
|
|
||||||
for added_context in self.added_contexts:
|
for added_context in self.added_contexts:
|
||||||
equivalent_existing_context = self.get_equivalent_existing_context(added_context)
|
equivalent_existing_context = self.get_equivalent_existing_context(added_context)
|
||||||
@@ -166,15 +167,32 @@ class Patcher(ifcpatch.BasePatcher):
|
|||||||
for inverse in self.file.get_inverse(added_context):
|
for inverse in self.file.get_inverse(added_context):
|
||||||
if self.file.schema != "IFC2X3":
|
if self.file.schema != "IFC2X3":
|
||||||
if inverse.is_a("IfcCoordinateOperation"):
|
if inverse.is_a("IfcCoordinateOperation"):
|
||||||
to_delete.add(inverse.id())
|
coord_ops_to_delete.add(inverse.id())
|
||||||
continue
|
continue
|
||||||
ifcopenshell.util.element.replace_attribute(inverse, added_context, equivalent_existing_context)
|
ifcopenshell.util.element.replace_attribute(inverse, added_context, equivalent_existing_context)
|
||||||
to_delete.add(added_context.id())
|
contexts_to_delete.add(added_context.id())
|
||||||
|
|
||||||
for element_id in to_delete:
|
# IfcCoordinateOperation entities (e.g. IfcMapConversion) have 0 real inverses,
|
||||||
|
# so remove_deep2 works and also cleans up owned sub-entities (e.g. IfcProjectedCRS).
|
||||||
|
for element_id in coord_ops_to_delete:
|
||||||
try:
|
try:
|
||||||
ifcopenshell.util.element.remove_deep2(self.file, self.file.by_id(element_id))
|
ifcopenshell.util.element.remove_deep2(self.file, self.file.by_id(element_id))
|
||||||
except:
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Delete parent contexts before subcontexts: file.add() inflates inverse counts,
|
||||||
|
# leaving a phantom subcontext entry in the parent's index. Deleting the subcontext
|
||||||
|
# first turns it into a dangling reference; deleting the parent first is safe.
|
||||||
|
def deletion_priority(element_id: int) -> int:
|
||||||
|
try:
|
||||||
|
return 1 if self.file.by_id(element_id).is_a("IfcGeometricRepresentationSubContext") else 0
|
||||||
|
except Exception:
|
||||||
|
return 2
|
||||||
|
|
||||||
|
for element_id in sorted(contexts_to_delete, key=deletion_priority):
|
||||||
|
try:
|
||||||
|
self.file.remove(self.file.by_id(element_id))
|
||||||
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def get_equivalent_existing_context(
|
def get_equivalent_existing_context(
|
||||||
|
|||||||
Reference in New Issue
Block a user