From 4617d9f23490ce3a2dbc64e97c389fde23657a13 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 16 Nov 2021 18:30:23 +1100 Subject: [PATCH] A whole bunch of new usecases for managing IFC library information and references --- .../ifcopenshell/api/library/add_library.py | 14 ++++++++ .../ifcopenshell/api/library/add_reference.py | 14 ++++++++ .../api/library/assign_reference.py | 34 +++++++++++++++++++ .../ifcopenshell/api/library/edit_library.py | 10 ++++++ .../api/library/edit_reference.py | 10 ++++++ .../api/library/remove_library.py | 14 ++++++++ .../api/library/remove_reference.py | 11 ++++++ .../api/library/unassign_reference.py | 19 +++++++++++ .../test/api/library/test_add_library.py | 9 +++++ .../test/api/library/test_add_reference.py | 10 ++++++ .../test/api/library/test_assign_reference.py | 20 +++++++++++ .../test/api/library/test_edit_library.py | 19 +++++++++++ .../test/api/library/test_edit_reference.py | 19 +++++++++++ .../test/api/library/test_remove_library.py | 19 +++++++++++ .../test/api/library/test_remove_reference.py | 12 +++++++ .../api/library/test_unassign_reference.py | 12 +++++++ 16 files changed, 246 insertions(+) create mode 100644 src/ifcopenshell-python/ifcopenshell/api/library/add_library.py create mode 100644 src/ifcopenshell-python/ifcopenshell/api/library/add_reference.py create mode 100644 src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py create mode 100644 src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py create mode 100644 src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py create mode 100644 src/ifcopenshell-python/ifcopenshell/api/library/remove_library.py create mode 100644 src/ifcopenshell-python/ifcopenshell/api/library/remove_reference.py create mode 100644 src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py create mode 100644 src/ifcopenshell-python/test/api/library/test_add_library.py create mode 100644 src/ifcopenshell-python/test/api/library/test_add_reference.py create mode 100644 src/ifcopenshell-python/test/api/library/test_assign_reference.py create mode 100644 src/ifcopenshell-python/test/api/library/test_edit_library.py create mode 100644 src/ifcopenshell-python/test/api/library/test_edit_reference.py create mode 100644 src/ifcopenshell-python/test/api/library/test_remove_library.py create mode 100644 src/ifcopenshell-python/test/api/library/test_remove_reference.py create mode 100644 src/ifcopenshell-python/test/api/library/test_unassign_reference.py diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py b/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py new file mode 100644 index 0000000000..48f69adca1 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/library/add_library.py @@ -0,0 +1,14 @@ +import ifcopenshell +import ifcopenshell.util.schema +import ifcopenshell.util.date + + +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = {"name": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + return self.file.create_entity("IfcLibraryInformation", Name=self.settings["name"]) diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/add_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/add_reference.py new file mode 100644 index 0000000000..f7427155c6 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/library/add_reference.py @@ -0,0 +1,14 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = { + "library": None, + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + return self.file.createIfcLibraryReference(ReferencedLibrary=self.settings["library"]) diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py new file mode 100644 index 0000000000..d2d8816527 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/library/assign_reference.py @@ -0,0 +1,34 @@ +import ifcopenshell + + +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = { + "product": None, + "reference": None, + } + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + rels = self.settings["reference"].LibraryRefForObjects + if not rels: + return self.file.create_entity( + "IfcRelAssociatesLibrary", + GlobalId=ifcopenshell.guid.new(), + OwnerHistory=ifcopenshell.api.run("owner.create_owner_history", self.file), + RelatedObjects=[self.settings["product"]], + RelatingLibrary=self.settings["reference"], + ) + + for rel in rels: + if self.settings["product"] in rel.RelatedObjects: + return rel + + rel = rels[0] + related_objects = list(rel.RelatedObjects) + related_objects.append(self.settings["product"]) + rel.RelatedObjects = related_objects + ifcopenshell.api.run("owner.update_owner_history", self.file, element=rel) + return rel diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py b/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py new file mode 100644 index 0000000000..7aaa9f5ef7 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/library/edit_library.py @@ -0,0 +1,10 @@ +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = {"library": None, "attributes": {}} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for name, value in self.settings["attributes"].items(): + setattr(self.settings["library"], name, value) diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py new file mode 100644 index 0000000000..8c97468943 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/library/edit_reference.py @@ -0,0 +1,10 @@ +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = {"reference": None, "attributes": {}} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for name, value in self.settings["attributes"].items(): + setattr(self.settings["reference"], name, value) diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/remove_library.py b/src/ifcopenshell-python/ifcopenshell/api/library/remove_library.py new file mode 100644 index 0000000000..f6d218f28a --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/library/remove_library.py @@ -0,0 +1,14 @@ +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = {"library": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for reference in set(self.settings["library"].HasLibraryReferences or []): + self.file.remove(reference) + self.file.remove(self.settings["library"]) + for rel in self.file.by_type("IfcRelAssociatesLibrary"): + if not rel.RelatingLibrary: + self.file.remove(rel) diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/remove_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/remove_reference.py new file mode 100644 index 0000000000..d4ac557ac9 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/library/remove_reference.py @@ -0,0 +1,11 @@ +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = {"reference": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + for rel in self.settings["reference"].LibraryRefForObjects: + self.file.remove(rel) + self.file.remove(self.settings["reference"]) diff --git a/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py b/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py new file mode 100644 index 0000000000..7fb70b41f8 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/library/unassign_reference.py @@ -0,0 +1,19 @@ +class Usecase: + def __init__(self, file, **settings): + self.file = file + self.settings = {"reference": None, "product": None} + for key, value in settings.items(): + self.settings[key] = value + + def execute(self): + rels = self.settings["reference"].LibraryRefForObjects + if not rels: + return + for rel in rels: + if self.settings["product"] in rel.RelatedObjects: + if len(rel.RelatedObjects) == 1: + self.file.remove(rel) + continue + related_objects = list(rel.RelatedObjects) + related_objects.remove(self.settings["product"]) + rel.RelatedObjects = related_objects diff --git a/src/ifcopenshell-python/test/api/library/test_add_library.py b/src/ifcopenshell-python/test/api/library/test_add_library.py new file mode 100644 index 0000000000..1b20d76dcf --- /dev/null +++ b/src/ifcopenshell-python/test/api/library/test_add_library.py @@ -0,0 +1,9 @@ +import test.bootstrap +import ifcopenshell.api + + +class TestAddLibrary(test.bootstrap.IFC4): + def test_adding_a_library(self): + library = ifcopenshell.api.run("library.add_library", self.file, name="Name") + assert library.is_a("IfcLibraryInformation") + assert library.Name == "Name" diff --git a/src/ifcopenshell-python/test/api/library/test_add_reference.py b/src/ifcopenshell-python/test/api/library/test_add_reference.py new file mode 100644 index 0000000000..a33b6cfc23 --- /dev/null +++ b/src/ifcopenshell-python/test/api/library/test_add_reference.py @@ -0,0 +1,10 @@ +import test.bootstrap +import ifcopenshell.api + + +class TestAddReference(test.bootstrap.IFC4): + def test_adding_a_reference(self): + library = ifcopenshell.api.run("library.add_library", self.file, name="Name") + reference = ifcopenshell.api.run("library.add_reference", self.file, library=library) + assert reference.is_a("IfcLibraryReference") + assert reference.ReferencedLibrary == library diff --git a/src/ifcopenshell-python/test/api/library/test_assign_reference.py b/src/ifcopenshell-python/test/api/library/test_assign_reference.py new file mode 100644 index 0000000000..aeac898fd0 --- /dev/null +++ b/src/ifcopenshell-python/test/api/library/test_assign_reference.py @@ -0,0 +1,20 @@ +import test.bootstrap +import ifcopenshell.api + + +class TestAssignReference(test.bootstrap.IFC4): + def test_assigning_a_reference(self): + reference = self.file.createIfcLibraryReference() + product = self.file.createIfcWall() + product2 = self.file.createIfcWall() + ifcopenshell.api.run("library.assign_reference", self.file, product=product, reference=reference) + assert reference.LibraryRefForObjects[0].RelatedObjects == (product,) + ifcopenshell.api.run("library.assign_reference", self.file, product=product2, reference=reference) + assert reference.LibraryRefForObjects[0].RelatedObjects == (product, product2) + + def test_not_assigning_twice(self): + reference = self.file.createIfcLibraryReference() + product = self.file.createIfcWall() + ifcopenshell.api.run("library.assign_reference", self.file, product=product, reference=reference) + ifcopenshell.api.run("library.assign_reference", self.file, product=product, reference=reference) + assert reference.LibraryRefForObjects[0].RelatedObjects == (product,) diff --git a/src/ifcopenshell-python/test/api/library/test_edit_library.py b/src/ifcopenshell-python/test/api/library/test_edit_library.py new file mode 100644 index 0000000000..b49cab7cbf --- /dev/null +++ b/src/ifcopenshell-python/test/api/library/test_edit_library.py @@ -0,0 +1,19 @@ +import test.bootstrap +import ifcopenshell.api + + +class TestEditLibrary(test.bootstrap.IFC4): + def test_editing_a_library(self): + library = self.file.createIfcLibraryInformation() + ifcopenshell.api.run("library.edit_library", self.file, library=library, attributes={ + "Name": "Name", + "Version": "Version", + "VersionDate": "VersionDate", + "Location": "Location", + "Description": "Description", + }) + assert library.Name == "Name" + assert library.Version == "Version" + assert library.VersionDate == "VersionDate" + assert library.Location == "Location" + assert library.Description == "Description" diff --git a/src/ifcopenshell-python/test/api/library/test_edit_reference.py b/src/ifcopenshell-python/test/api/library/test_edit_reference.py new file mode 100644 index 0000000000..28d73dd022 --- /dev/null +++ b/src/ifcopenshell-python/test/api/library/test_edit_reference.py @@ -0,0 +1,19 @@ +import test.bootstrap +import ifcopenshell.api + + +class TestEditReference(test.bootstrap.IFC4): + def test_editing_a_reference(self): + reference = self.file.createIfcLibraryReference() + ifcopenshell.api.run("library.edit_reference", self.file, reference=reference, attributes={ + "Location": "Location", + "Identification": "Identification", + "Name": "Name", + "Description": "Description", + "Language": "Language", + }) + assert reference.Location == "Location" + assert reference.Identification == "Identification" + assert reference.Name == "Name" + assert reference.Description == "Description" + assert reference.Language == "Language" diff --git a/src/ifcopenshell-python/test/api/library/test_remove_library.py b/src/ifcopenshell-python/test/api/library/test_remove_library.py new file mode 100644 index 0000000000..2f77dc78ce --- /dev/null +++ b/src/ifcopenshell-python/test/api/library/test_remove_library.py @@ -0,0 +1,19 @@ +import test.bootstrap +import ifcopenshell.api + + +class TestRemoveLibrary(test.bootstrap.IFC4): + def test_removing_a_library(self): + library = self.file.createIfcLibraryInformation() + ifcopenshell.api.run("library.remove_library", self.file, library=library) + assert len(self.file.by_type("IfcLibraryInformation")) == 0 + + def test_removing_a_library_and_all_references(self): + library = self.file.createIfcLibraryInformation() + reference1 = self.file.createIfcLibraryReference(ReferencedLibrary=library) + reference2 = self.file.createIfcLibraryReference(ReferencedLibrary=library) + self.file.createIfcRelAssociatesLibrary(GlobalId='foo', RelatingLibrary=library) + self.file.createIfcRelAssociatesLibrary(GlobalId='bar', RelatingLibrary=reference1) + ifcopenshell.api.run("library.remove_library", self.file, library=library) + assert len(self.file.by_type("IfcLibraryReference")) == 0 + assert len(self.file.by_type("IfcRelAssociatesLibrary")) == 0 diff --git a/src/ifcopenshell-python/test/api/library/test_remove_reference.py b/src/ifcopenshell-python/test/api/library/test_remove_reference.py new file mode 100644 index 0000000000..e3008dfa67 --- /dev/null +++ b/src/ifcopenshell-python/test/api/library/test_remove_reference.py @@ -0,0 +1,12 @@ +import test.bootstrap +import ifcopenshell.api + + +class TestRemoveReference(test.bootstrap.IFC4): + def test_removing_a_reference(self): + reference = self.file.createIfcLibraryReference() + product = self.file.createIfcWall() + ifcopenshell.api.run("library.assign_reference", self.file, product=product, reference=reference) + ifcopenshell.api.run("library.remove_reference", self.file, reference=reference) + assert len(self.file.by_type("IfcLibraryReference")) == 0 + assert len(self.file.by_type("IfcRelAssociatesLibrary")) == 0 diff --git a/src/ifcopenshell-python/test/api/library/test_unassign_reference.py b/src/ifcopenshell-python/test/api/library/test_unassign_reference.py new file mode 100644 index 0000000000..4e2b651928 --- /dev/null +++ b/src/ifcopenshell-python/test/api/library/test_unassign_reference.py @@ -0,0 +1,12 @@ +import test.bootstrap +import ifcopenshell.api + + +class TestUnassignReference(test.bootstrap.IFC4): + def test_unassigning_a_reference(self): + reference = self.file.createIfcLibraryReference() + product = self.file.createIfcWall() + product2 = self.file.createIfcWall() + ifcopenshell.api.run("library.assign_reference", self.file, product=product, reference=reference) + ifcopenshell.api.run("library.unassign_reference", self.file, product=product, reference=reference) + assert len(self.file.by_type("IfcRelAssociatesLibrary")) == 0