mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 21:42:19 +00:00
Some optimisations to IfcDiff for a 50% speed up (461s down to 300s on sample data)
This commit is contained in:
+27
-19
@@ -29,14 +29,15 @@ import decimal
|
|||||||
|
|
||||||
|
|
||||||
class IfcDiff:
|
class IfcDiff:
|
||||||
def __init__(self, old_file, new_file, output_file, inverse_classes=None):
|
def __init__(self, old_file, new_file, output_file, inverse_classes=None, is_shallow=False):
|
||||||
self.old_file = old_file
|
self.old_file = old_file
|
||||||
self.new_file = new_file
|
self.new_file = new_file
|
||||||
self.output_file = output_file
|
self.output_file = output_file
|
||||||
self.change_register = {}
|
self.change_register = {}
|
||||||
self.representation_ids = []
|
self.representation_ids = set()
|
||||||
self.inverse_classes = inverse_classes
|
self.inverse_classes = inverse_classes
|
||||||
self.precision = 2
|
self.precision = 2
|
||||||
|
self.is_shallow = is_shallow
|
||||||
|
|
||||||
def diff(self):
|
def diff(self):
|
||||||
print("# IFC Diff")
|
print("# IFC Diff")
|
||||||
@@ -61,16 +62,18 @@ class IfcDiff:
|
|||||||
|
|
||||||
for global_id in same_elements:
|
for global_id in same_elements:
|
||||||
total_diffed += 1
|
total_diffed += 1
|
||||||
print("{}/{} diffed ...".format(total_diffed, total_same_elements), end="\r", flush=True)
|
if total_diffed % 250 == 0:
|
||||||
|
print("{}/{} diffed ...".format(total_diffed, total_same_elements), end="\r", flush=True)
|
||||||
old_element = self.old.by_id(global_id)
|
old_element = self.old.by_id(global_id)
|
||||||
new_element = self.new.by_id(global_id)
|
new_element = self.new.by_id(global_id)
|
||||||
self.diff_element(old_element, new_element)
|
if self.diff_element(old_element, new_element) and self.is_shallow:
|
||||||
self.diff_element_inverse_relationships(old_element, new_element)
|
continue
|
||||||
|
if self.diff_element_inverse_relationships(old_element, new_element) and self.is_shallow:
|
||||||
|
continue
|
||||||
representation_id = self.get_representation_id(new_element)
|
representation_id = self.get_representation_id(new_element)
|
||||||
if representation_id in self.representation_ids:
|
if representation_id in self.representation_ids:
|
||||||
continue
|
continue
|
||||||
self.representation_ids.append(representation_id)
|
self.representation_ids.add(representation_id)
|
||||||
self.diff_element_geometry(old_element, new_element)
|
self.diff_element_geometry(old_element, new_element)
|
||||||
|
|
||||||
print(" - {} item(s) were changed either geometrically or with data".format(len(self.change_register.keys())))
|
print(" - {} item(s) were changed either geometrically or with data".format(len(self.change_register.keys())))
|
||||||
@@ -114,15 +117,16 @@ class IfcDiff:
|
|||||||
significant_digits=self.precision,
|
significant_digits=self.precision,
|
||||||
ignore_string_type_changes=True,
|
ignore_string_type_changes=True,
|
||||||
ignore_numeric_type_changes=True,
|
ignore_numeric_type_changes=True,
|
||||||
exclude_regex_paths=[
|
exclude_regex_paths={
|
||||||
r"root.*id$",
|
r"root.*id$",
|
||||||
r".*Representation.*",
|
r".*Representation.*",
|
||||||
r".*OwnerHistory.*",
|
r".*OwnerHistory.*",
|
||||||
r".*ObjectPlacement.*",
|
r".*ObjectPlacement.*",
|
||||||
],
|
},
|
||||||
)
|
)
|
||||||
if diff and new_element.GlobalId:
|
if diff and new_element.GlobalId:
|
||||||
self.change_register.setdefault(new_element.GlobalId, {}).update(diff)
|
self.change_register.setdefault(new_element.GlobalId, {}).update(diff)
|
||||||
|
return True
|
||||||
|
|
||||||
def diff_element_inverse_relationships(self, old_element, new_element):
|
def diff_element_inverse_relationships(self, old_element, new_element):
|
||||||
if not self.inverse_classes:
|
if not self.inverse_classes:
|
||||||
@@ -154,6 +158,7 @@ class IfcDiff:
|
|||||||
)
|
)
|
||||||
if diff and new_element.GlobalId:
|
if diff and new_element.GlobalId:
|
||||||
self.change_register.setdefault(new_element.GlobalId, {}).update(diff)
|
self.change_register.setdefault(new_element.GlobalId, {}).update(diff)
|
||||||
|
return True
|
||||||
|
|
||||||
def diff_element_geometry(self, old_element, new_element):
|
def diff_element_geometry(self, old_element, new_element):
|
||||||
try:
|
try:
|
||||||
@@ -166,16 +171,6 @@ class IfcDiff:
|
|||||||
ignore_numeric_type_changes=True,
|
ignore_numeric_type_changes=True,
|
||||||
exclude_regex_paths=r"root.*id$",
|
exclude_regex_paths=r"root.*id$",
|
||||||
)
|
)
|
||||||
DeepDiff(
|
|
||||||
old_element.Representation,
|
|
||||||
new_element.Representation,
|
|
||||||
terminate_on_first=True,
|
|
||||||
skip_after_n=1000, # Arbitrary value to "skim" check
|
|
||||||
significant_digits=self.precision,
|
|
||||||
ignore_string_type_changes=True,
|
|
||||||
ignore_numeric_type_changes=True,
|
|
||||||
exclude_regex_paths=r"root.*id$",
|
|
||||||
)
|
|
||||||
DeepDiff(
|
DeepDiff(
|
||||||
old_element.HasOpenings,
|
old_element.HasOpenings,
|
||||||
new_element.HasOpenings,
|
new_element.HasOpenings,
|
||||||
@@ -194,6 +189,19 @@ class IfcDiff:
|
|||||||
ignore_numeric_type_changes=True,
|
ignore_numeric_type_changes=True,
|
||||||
exclude_regex_paths=r"root.*id$",
|
exclude_regex_paths=r"root.*id$",
|
||||||
)
|
)
|
||||||
|
DeepDiff(
|
||||||
|
old_element.Representation.get_info_2(recursive=True),
|
||||||
|
new_element.Representation.get_info_2(recursive=True),
|
||||||
|
terminate_on_first=True,
|
||||||
|
skip_after_n=500, # Arbitrary value to "skim" check
|
||||||
|
significant_digits=self.precision,
|
||||||
|
ignore_string_type_changes=True,
|
||||||
|
ignore_numeric_type_changes=True,
|
||||||
|
exclude_regex_paths=[
|
||||||
|
r"root.*id']$",
|
||||||
|
r".*ContextOfItems.*",
|
||||||
|
],
|
||||||
|
)
|
||||||
except:
|
except:
|
||||||
if new_element.GlobalId:
|
if new_element.GlobalId:
|
||||||
return self.change_register.setdefault(new_element.GlobalId, {}).update({"has_geometry_change": True})
|
return self.change_register.setdefault(new_element.GlobalId, {}).update({"has_geometry_change": True})
|
||||||
|
|||||||
Reference in New Issue
Block a user