mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 17:57:02 +00:00
fix(ifcdiff): check attributes by default so PredefinedType changes are caught (#8214)
IfcDiff defaulted to relationships=["geometry"], so a plain diff only ever
compared geometry. Attribute-only edits on an element that kept its GlobalId
(a modified or removed PredefinedType, a renamed element, etc.) were silently
missed. The CLI made this worse: --relationships did not list "attributes" or
"geometry" as valid values, so there was no documented way to enable it.
The default is now ["attributes", "geometry"], so a plain `ifcdiff old new`
reports attribute changes alongside geometry changes. The CLI help and the
IfcDiff docstring now document all valid relationship values.
Added a regression test covering a PredefinedType change detected with the
default configuration.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
(cherry picked from commit 0a8ae14789)
This commit is contained in:
committed by
Dion Moult
parent
ff798bc989
commit
b3dc0b4478
+10
-4
@@ -51,8 +51,10 @@ class IfcDiff:
|
|||||||
|
|
||||||
:param old: IFC file object for the old model
|
:param old: IFC file object for the old model
|
||||||
:param new: IFC file object for the new model
|
:param new: IFC file object for the new model
|
||||||
:param relationships: List of relationships to check. None means that only
|
:param relationships: List of relationships to check. None means that
|
||||||
geometry is compared. See RELATIONSHIP_TYPE for available relationships.
|
attributes and geometry are compared, so changes such as a modified or
|
||||||
|
removed PredefinedType are reported. See RELATIONSHIP_TYPE for available
|
||||||
|
relationships.
|
||||||
:param is_shallow: True if you want only the first difference to be listed.
|
:param is_shallow: True if you want only the first difference to be listed.
|
||||||
False if you want all differences to be checked. Choosing False means
|
False if you want all differences to be checked. Choosing False means
|
||||||
that comparisons will take longer.
|
that comparisons will take longer.
|
||||||
@@ -86,7 +88,7 @@ class IfcDiff:
|
|||||||
self.new = new
|
self.new = new
|
||||||
self.change_register = {}
|
self.change_register = {}
|
||||||
self.representation_ids = {}
|
self.representation_ids = {}
|
||||||
self.relationships = relationships or ["geometry"]
|
self.relationships = relationships or ["attributes", "geometry"]
|
||||||
self.precision = 1e-4
|
self.precision = 1e-4
|
||||||
self.is_shallow = is_shallow
|
self.is_shallow = is_shallow
|
||||||
self.filter_elements = filter_elements
|
self.filter_elements = filter_elements
|
||||||
@@ -435,7 +437,11 @@ if __name__ == "__main__":
|
|||||||
"-r",
|
"-r",
|
||||||
"--relationships",
|
"--relationships",
|
||||||
type=str,
|
type=str,
|
||||||
help='A list of space-separated relationships, chosen from "type", "property", "container", "aggregate", "classification"',
|
help=(
|
||||||
|
'A list of space-separated relationships, chosen from "attributes", "geometry", '
|
||||||
|
'"type", "property", "container", "aggregate", "classification". '
|
||||||
|
'Defaults to "attributes geometry" when omitted.'
|
||||||
|
),
|
||||||
default="",
|
default="",
|
||||||
)
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|||||||
@@ -77,6 +77,23 @@ class TestIfcDiff:
|
|||||||
assert ifc_diff.deleted_elements == set()
|
assert ifc_diff.deleted_elements == set()
|
||||||
assert ifc_diff.change_register == {wall.GlobalId: {"attributes_changed": True}}
|
assert ifc_diff.change_register == {wall.GlobalId: {"attributes_changed": True}}
|
||||||
|
|
||||||
|
def test_changed_predefined_type_is_caught_by_default(self):
|
||||||
|
# Regression test for #8214: a plain diff (no relationships specified)
|
||||||
|
# must report a modified or removed PredefinedType. Previously the
|
||||||
|
# default only compared geometry, so attribute-only edits were missed.
|
||||||
|
ifc_file = setup_project()
|
||||||
|
wall = ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcWall", name="Foo")
|
||||||
|
wall.PredefinedType = "SOLIDWALL"
|
||||||
|
|
||||||
|
new_file = ifc_file.from_string(ifc_file.to_string())
|
||||||
|
new_file.by_id(wall.id()).PredefinedType = "NOTDEFINED"
|
||||||
|
|
||||||
|
ifc_diff = ifcdiff.IfcDiff(ifc_file, new_file)
|
||||||
|
ifc_diff.diff()
|
||||||
|
assert ifc_diff.added_elements == set()
|
||||||
|
assert ifc_diff.deleted_elements == set()
|
||||||
|
assert ifc_diff.change_register == {wall.GlobalId: {"attributes_changed": True}}
|
||||||
|
|
||||||
def test_changed_geometry(self):
|
def test_changed_geometry(self):
|
||||||
ifc_file = setup_project()
|
ifc_file = setup_project()
|
||||||
wall = ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcWall", name="Foo")
|
wall = ifcopenshell.api.root.create_entity(ifc_file, ifc_class="IfcWall", name="Foo")
|
||||||
|
|||||||
Reference in New Issue
Block a user