Merge remote-tracking branch 'origin/v0.7.0' into v08attempt1

This commit is contained in:
Thomas Krijnen
2024-04-18 21:39:33 +02:00
86 changed files with 1817 additions and 631 deletions
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import pytest
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.classification
@@ -23,85 +24,127 @@ import ifcopenshell.util.classification
class TestAddReference(test.bootstrap.IFC4):
def test_adding_a_reference(self):
is_ifc2x3 = self.file.schema == "IFC2X3"
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element, element2],
identification="X",
name="Foobar",
classification=result,
)
references = list(ifcopenshell.util.classification.get_references(element))
assert len(references) == 1
assert references[0].Identification == "X"
assert getattr(references[0], "ItemReference" if is_ifc2x3 else "Identification") == "X"
assert references[0].Name == "Foobar"
assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element2,
identification="X",
name="Foobar",
classification=result,
references2 = list(ifcopenshell.util.classification.get_references(element))
assert len(references2) == 1
assert getattr(references2[0], "ItemReference" if is_ifc2x3 else "Identification") == "X"
assert references2[0].Name == "Foobar"
assert references2[0] == references[0]
rel = next(
rel
for rel in self.file.by_type("IfcRelAssociatesClassification")
if rel.RelatingClassification == references[0]
)
assert list(ifcopenshell.util.classification.get_references(element2))[0].Identification == "X"
assert list(ifcopenshell.util.classification.get_references(element2))[0].Name == "Foobar"
assert list(ifcopenshell.util.classification.get_references(element2))[0] == references[0]
assert len(rel.RelatedObjects) == 2
def test_adding_a_library_based_reference(self):
is_ifc2x3 = self.file.schema == "IFC2X3"
library = ifcopenshell.file()
classification = library.createIfcClassification(Name="Name")
reference = library.createIfcClassificationReference(Identification="1", ReferencedSource=classification)
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification=classification)
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element, element2],
reference=reference,
classification=result,
)
references = list(ifcopenshell.util.classification.get_references(element))
assert len(references) == 1
assert references[0].Identification == "1"
assert getattr(references[0], "ItemReference" if is_ifc2x3 else "Identification") == "1"
assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
def test_adding_a_reference_to_a_resource(self):
references2 = list(ifcopenshell.util.classification.get_references(element2))
assert len(references2) == 1
assert getattr(references2[0], "ItemReference" if is_ifc2x3 else "Identification") == "1"
assert references2[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
assert references[0] == references2[0]
rel = next(
rel
for rel in self.file.by_type("IfcRelAssociatesClassification")
if rel.RelatingClassification == references[0]
)
assert len(rel.RelatedObjects) == 2
def test_adding_a_reference_to_a_resource_and_to_a_root(self):
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = self.file.createIfcMaterial()
element2 = self.file.createIfcCostValue()
element3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
identification="X",
name="Foobar",
classification=result,
)
if self.file.schema == "IFC2X3":
with pytest.raises(TypeError):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
products=[element, element2, element3],
identification="X",
name="Foobar",
classification=result,
)
return
else:
ifcopenshell.api.run(
"classification.add_reference",
self.file,
products=[element, element2, element3],
identification="X",
name="Foobar",
classification=result,
)
references = list(ifcopenshell.util.classification.get_references(element))
assert len(references) == 1
assert references[0].Identification == "X"
assert references[0].Name == "Foobar"
assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
element2 = self.file.createIfcCostValue()
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element2,
identification="X",
name="Foobar",
classification=result,
)
assert list(ifcopenshell.util.classification.get_references(element2))[0].Identification == "X"
assert list(ifcopenshell.util.classification.get_references(element2))[0].Name == "Foobar"
assert list(ifcopenshell.util.classification.get_references(element2))[0] == references[0]
references2 = list(ifcopenshell.util.classification.get_references(element2))
assert references2[0].Identification == "X"
assert references2[0].Name == "Foobar"
assert references2[0] == references[0]
references3 = list(ifcopenshell.util.classification.get_references(element3))
assert references3[0].Identification == "X"
assert references3[0].Name == "Foobar"
assert references3[0] == references[0]
assert len(self.file.by_type("IfcExternalReferenceRelationship")[0].RelatedResourceObjects) == 2
rel = next(
rel
for rel in self.file.by_type("IfcRelAssociatesClassification")
if rel.RelatingClassification == references[0]
)
assert len(rel.RelatedObjects) == 1
class TestAddReferenceIFC2X3(test.bootstrap.IFC2X3, TestAddReference):
pass
@@ -34,7 +34,7 @@ class TestRemoveClassification(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element],
identification="X",
name="Foobar",
classification=result,
@@ -51,7 +51,7 @@ class TestRemoveClassification(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element],
identification="X",
name="Foobar",
classification=result,
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import pytest
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.classification
@@ -25,58 +26,80 @@ class TestRemoveReference(test.bootstrap.IFC4):
def test_removing_a_reference(self):
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
reference = ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element, element2],
identification="X",
name="Foobar",
classification=result,
)
ifcopenshell.api.run("classification.remove_reference", self.file, product=element, reference=reference)
ifcopenshell.api.run(
"classification.remove_reference", self.file, products=[element, element2], reference=reference
)
assert len(ifcopenshell.util.classification.get_references(element)) == 0
assert len(ifcopenshell.util.classification.get_references(element2)) == 0
assert len(self.file.by_type("IfcClassificationReference")) == 0
def test_removing_a_reference_from_a_resource(self):
def test_removing_a_reference_from_a_resource_and_from_a_root(self):
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = self.file.createIfcMaterial()
element2 = self.file.createIfcCostValue()
element3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
reference = ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
identification="X",
name="Foobar",
classification=result,
if self.file.schema == "IFC2X3":
with pytest.raises(TypeError):
reference = ifcopenshell.api.run(
"classification.add_reference",
self.file,
products=[element, element2, element3],
identification="X",
name="Foobar",
classification=result,
)
return
else:
reference = ifcopenshell.api.run(
"classification.add_reference",
self.file,
products=[element, element2, element3],
identification="X",
name="Foobar",
classification=result,
)
ifcopenshell.api.run(
"classification.remove_reference", self.file, products=[element, element2, element3], reference=reference
)
ifcopenshell.api.run("classification.remove_reference", self.file, product=element, reference=reference)
assert len(ifcopenshell.util.classification.get_references(element)) == 0
assert len(ifcopenshell.util.classification.get_references(element2)) == 0
assert len(ifcopenshell.util.classification.get_references(element3)) == 0
assert len(self.file.by_type("IfcClassificationReference")) == 0
def test_retaining_the_reference_if_still_in_use(self):
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = self.file.createIfcMaterial()
element2 = self.file.createIfcMaterial()
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
reference = ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
identification="X",
name="Foobar",
classification=result,
)
reference2 = ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element2,
products=[element, element2, element3],
identification="X",
name="Foobar",
classification=result,
)
assert len(self.file.by_type("IfcClassificationReference")) == 1
ifcopenshell.api.run("classification.remove_reference", self.file, product=element, reference=reference)
ifcopenshell.api.run(
"classification.remove_reference", self.file, products=[element, element2], reference=reference
)
assert len(self.file.by_type("IfcClassificationReference")) == 1
ifcopenshell.api.run("classification.remove_reference", self.file, product=element2, reference=reference2)
ifcopenshell.api.run("classification.remove_reference", self.file, products=[element3], reference=reference)
assert len(self.file.by_type("IfcClassificationReference")) == 0
class TestRemoveReferenceIFC2X3(test.bootstrap.IFC2X3, TestRemoveReference):
pass
@@ -0,0 +1,64 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import pytest
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.constraint
class TestAssignConstraint(test.bootstrap.IFC4):
def test_assign_a_constraint(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
constraint = ifcopenshell.api.run("constraint.add_objective", self.file)
ifcopenshell.api.run(
"constraint.assign_constraint", self.file, products=[element, element2], constraint=constraint
)
assert ifcopenshell.util.constraint.get_constrained_elements(constraint) == {element, element2}
assert len(self.file.by_type("IfcRelAssociatesConstraint")) == 1
def test_doing_nothing_if_the_constraint_is_already_assigned(self):
constraint = ifcopenshell.api.run("constraint.add_objective", self.file)
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"constraint.assign_constraint", self.file, products=[element, element2], constraint=constraint
)
total_elements = len([e for e in self.file])
ifcopenshell.api.run(
"constraint.assign_constraint", self.file, products=[element, element2], constraint=constraint
)
assert len([e for e in self.file]) == total_elements
def test_that_old_relationships_are_updated_if_they_still_contain_elements(self):
constraint = ifcopenshell.api.run("constraint.add_objective", self.file)
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("constraint.assign_constraint", self.file, products=[element1], constraint=constraint)
rel = self.file.by_type("IfcRelAssociatesConstraint")[0]
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"constraint.assign_constraint", self.file, products=[element2, element3], constraint=constraint
)
assert len(rel.RelatedObjects) == 3
class TestAssignConstraintIFC2X3(test.bootstrap.IFC2X3, TestAssignConstraint):
pass
@@ -0,0 +1,67 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
#
# This file is part of IfcOpenShell.
#
# IfcOpenShell is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# IfcOpenShell is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import pytest
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.constraint
class TestUnassignConstraint(test.bootstrap.IFC4):
def test_unassigning_a_constraint(self):
constraint = ifcopenshell.api.run("constraint.add_objective", self.file)
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"constraint.assign_constraint", self.file, products=[element, element2], constraint=constraint
)
ifcopenshell.api.run(
"constraint.unassign_constraint", self.file, products=[element, element2], constraint=constraint
)
assert ifcopenshell.util.constraint.get_constrained_elements(element) == set()
assert len(self.file.by_type("IfcRelAssociatesConstraint")) == 0
def test_doing_nothing_if_no_constraint(self):
constraint = ifcopenshell.api.run("constraint.add_objective", self.file)
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"constraint.unassign_constraint", self.file, products=[element, element2], constraint=constraint
)
assert ifcopenshell.util.constraint.get_constrained_elements(element) == set()
assert ifcopenshell.util.constraint.get_constrained_elements(element2) == set()
def test_updating_the_rel_when_a_reference_is_removed_with_multipled_elements(self):
constraint = ifcopenshell.api.run("constraint.add_objective", self.file)
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("constraint.assign_constraint", self.file, products=[element1], constraint=constraint)
rel = self.file.by_type("IfcRelAssociatesConstraint")[0]
ifcopenshell.api.run(
"constraint.assign_constraint", self.file, products=[element2, element3], constraint=constraint
)
ifcopenshell.api.run(
"constraint.unassign_constraint", self.file, products=[element1, element2], constraint=constraint
)
assert rel.RelatedObjects == (element3,)
class TestUnassignConstraintIFC2X3(test.bootstrap.IFC2X3, TestUnassignConstraint):
pass
@@ -18,22 +18,25 @@
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.element
class TestAssignDocument(test.bootstrap.IFC4):
def test_assigning_a_document(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
reference = ifcopenshell.api.run("document.add_reference", self.file, information=None)
ifcopenshell.api.run("document.assign_document", self.file, product=element, document=reference)
ifcopenshell.api.run("document.assign_document", self.file, products=[element], document=reference)
assert element.HasAssociations[0].RelatingDocument == reference
assert ifcopenshell.util.element.get_referenced_elements(reference) == {element}
def test_assigning_multiple_documents(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
reference = ifcopenshell.api.run("document.add_reference", self.file, information=None)
ifcopenshell.api.run("document.assign_document", self.file, product=element, document=reference)
ifcopenshell.api.run("document.assign_document", self.file, product=element2, document=reference)
ifcopenshell.api.run("document.assign_document", self.file, products=[element, element2], document=reference)
assert len(self.file.by_type("IfcRelAssociatesDocument")) == 1
assert element.HasAssociations[0].RelatingDocument == reference
assert element2.HasAssociations[0].RelatingDocument == reference
assert element.HasAssociations[0] == element.HasAssociations[0]
assert ifcopenshell.util.element.get_referenced_elements(reference) == {element, element2}
class TestAssignDocumentIFC2X3(test.bootstrap.IFC2X3, TestAssignDocument):
pass
@@ -35,7 +35,7 @@ class TestRemoveReference(test.bootstrap.IFC4):
wall = self.file.createIfcWall()
information = ifcopenshell.api.run("document.add_information", self.file, parent=None)
reference = ifcopenshell.api.run("document.add_reference", self.file, information=information)
ifcopenshell.api.run("document.assign_document", self.file, product=wall, document=reference)
ifcopenshell.api.run("document.assign_document", self.file, products=[wall], document=reference)
assert len(self.file.by_type("IfcRelAssociatesDocument")) == 2
ifcopenshell.api.run("document.remove_reference", self.file, reference=reference)
assert len(self.file.by_type("IfcDocumentReference")) == 0
@@ -18,23 +18,29 @@
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.element
class TestUnassignDocument(test.bootstrap.IFC4):
def test_unassigning_a_document(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
reference = ifcopenshell.api.run("document.add_reference", self.file, information=None)
ifcopenshell.api.run("document.assign_document", self.file, product=element, document=reference)
ifcopenshell.api.run("document.unassign_document", self.file, product=element, document=reference)
ifcopenshell.api.run("document.assign_document", self.file, products=[element], document=reference)
ifcopenshell.api.run("document.unassign_document", self.file, products=[element], document=reference)
assert not element.HasAssociations
assert not len(self.file.by_type("IfcRelAssociatesDocument"))
def test_unassigning_a_document_used_by_multiple_entities(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
element3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
reference = ifcopenshell.api.run("document.add_reference", self.file, information=None)
ifcopenshell.api.run("document.assign_document", self.file, product=element, document=reference)
ifcopenshell.api.run("document.assign_document", self.file, product=element2, document=reference)
ifcopenshell.api.run("document.unassign_document", self.file, product=element, document=reference)
assert not element.HasAssociations
assert element2.HasAssociations[0].RelatingDocument == reference
ifcopenshell.api.run(
"document.assign_document", self.file, products=[element, element2, element3], document=reference
)
ifcopenshell.api.run("document.unassign_document", self.file, products=[element, element2], document=reference)
assert ifcopenshell.util.element.get_referenced_elements(reference) == {element3}
class TestUnassignDocumentIFC2X3(test.bootstrap.IFC2X3, TestUnassignDocument):
pass
@@ -20,39 +20,48 @@ import test.bootstrap
import ifcopenshell.api
def validate_ifc_file(ifc_file: ifcopenshell.file, use_json=True):
import ifcopenshell
import ifcopenshell.validate
if use_json:
logger = ifcopenshell.validate.json_logger()
else:
import logging
logger = logging.getLogger("validate")
logger.setLevel(logging.DEBUG)
ifcopenshell.validate.validate(ifc_file, logger, express_rules=True)
if use_json:
if logger.statements:
from pprint import pprint
pprint(logger.statements)
else:
print("IFC is completely valid.")
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)
product3 = self.file.createIfcWall()
ifcopenshell.api.run("library.assign_reference", self.file, products=[product], reference=reference)
rel = self.file.by_type("IfcRelAssociatesLibrary")[0]
assert rel.RelatedObjects == (product,)
ifcopenshell.api.run("library.assign_reference", self.file, products=[product2, product3], reference=reference)
assert set(rel.RelatedObjects) == set((product, product2, product3))
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,)
class TestAssignReferenceIFC2X3(test.bootstrap.IFC2X3):
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)
ifcopenshell.api.run("library.assign_reference", self.file, products=[product], reference=reference)
ifcopenshell.api.run("library.assign_reference", self.file, products=[product], reference=reference)
rel = self.file.by_type("IfcRelAssociatesLibrary")[0]
assert rel.RelatedObjects == (product,)
ifcopenshell.api.run("library.assign_reference", self.file, product=product2, reference=reference)
assert rel.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)
rel = self.file.by_type("IfcRelAssociatesLibrary")[0]
assert rel.RelatedObjects == (product,)
class TestAssignReferenceIFC2X3(test.bootstrap.IFC2X3, TestAssignReference):
pass
@@ -24,7 +24,7 @@ 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.assign_reference", self.file, products=[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
@@ -18,12 +18,20 @@
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.element
class TestUnassignReference(test.bootstrap.IFC4):
def test_unassigning_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.unassign_reference", self.file, product=product, reference=reference)
products = [self.file.createIfcWall() for i in range(3)]
ifcopenshell.api.run("library.assign_reference", self.file, products=products, reference=reference)
ifcopenshell.api.run("library.unassign_reference", self.file, products=products[:1], reference=reference)
assert ifcopenshell.util.element.get_referenced_elements(reference) == set(products[1:])
ifcopenshell.api.run("library.unassign_reference", self.file, products=products[1:], reference=reference)
assert ifcopenshell.util.element.get_referenced_elements(reference) == set()
assert len(self.file.by_type("IfcRelAssociatesLibrary")) == 0
class TestUnassignReferenceIFC2X3(test.bootstrap.IFC2X3, TestUnassignReference):
pass
@@ -26,28 +26,42 @@ class TestDereferenceStructure(test.bootstrap.IFC4):
def test_removing_a_container(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("spatial.reference_structure", self.file, product=subelement, relating_structure=element)
ifcopenshell.api.run("spatial.dereference_structure", self.file, product=subelement, relating_structure=element)
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"spatial.reference_structure", self.file, products=[subelement, subelement2], relating_structure=element
)
ifcopenshell.api.run(
"spatial.dereference_structure", self.file, products=[subelement, subelement2], relating_structure=element
)
assert ifcopenshell.util.element.get_referenced_structures(subelement) == []
assert len(self.file.by_type("IfcRelReferencedInSpatialStructure")) == 0
def test_doing_nothing_if_no_container(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("spatial.dereference_structure", self.file, product=subelement, relating_structure=element)
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"spatial.dereference_structure", self.file, products=[subelement, subelement2], relating_structure=element
)
assert ifcopenshell.util.element.get_referenced_structures(subelement) == []
assert ifcopenshell.util.element.get_referenced_structures(subelement2) == []
def test_updating_the_rel_when_a_reference_is_removed_with_multipled_elements(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("spatial.reference_structure", self.file, product=subelement1, relating_structure=element)
ifcopenshell.api.run("spatial.reference_structure", self.file, product=subelement2, relating_structure=element)
ifcopenshell.api.run("spatial.dereference_structure", self.file, product=subelement1, relating_structure=element)
assert self.file.by_type("IfcRelReferencedInSpatialStructure")[0].RelatedElements == (subelement2,)
subelement3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"spatial.reference_structure", self.file, products=[subelement1], relating_structure=element
)
ifcopenshell.api.run(
"spatial.reference_structure", self.file, products=[subelement2, subelement3], relating_structure=element
)
ifcopenshell.api.run(
"spatial.dereference_structure", self.file, products=[subelement1, subelement2], relating_structure=element
)
assert element.ReferencesElements[0].RelatedElements == (subelement3,)
def test_deleting_the_rel_when_a_container_is_removed_with_no_elements(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("spatial.reference_structure", self.file, product=subelement, relating_structure=element)
ifcopenshell.api.run("spatial.dereference_structure", self.file, product=subelement, relating_structure=element)
assert len(self.file.by_type("IfcRelReferencedInSpatialStructure")) == 0
class TestDereferenceStructureIFC2X3(test.bootstrap.IFC2X3, TestDereferenceStructure):
pass
@@ -26,25 +26,39 @@ class TestReferenceStructure(test.bootstrap.IFC4):
def test_referencing_a_structure(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
rel = ifcopenshell.api.run(
"spatial.reference_structure", self.file, product=subelement, relating_structure=element
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"spatial.reference_structure", self.file, products=[subelement, subelement2], relating_structure=element
)
assert ifcopenshell.util.element.get_referenced_structures(subelement) == [element]
assert rel.is_a("IfcRelReferencedInSpatialStructure")
assert ifcopenshell.util.element.get_structure_referenced_elements(element) == {subelement, subelement2}
def test_doing_nothing_if_the_structure_is_already_referenced(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("spatial.reference_structure", self.file, product=subelement, relating_structure=element)
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"spatial.reference_structure", self.file, products=[subelement, subelement2], relating_structure=element
)
total_elements = len([e for e in self.file])
ifcopenshell.api.run("spatial.reference_structure", self.file, product=subelement, relating_structure=element)
ifcopenshell.api.run(
"spatial.reference_structure", self.file, products=[subelement, subelement2], relating_structure=element
)
assert len([e for e in self.file]) == total_elements
def test_that_old_relationships_are_updated_if_they_still_contain_elements(self):
element1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
subelement1 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"spatial.reference_structure", self.file, products=[subelement1], relating_structure=element
)
subelement2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("spatial.reference_structure", self.file, product=subelement1, relating_structure=element1)
ifcopenshell.api.run("spatial.reference_structure", self.file, product=subelement2, relating_structure=element1)
subelement3 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"spatial.reference_structure", self.file, products=[subelement2, subelement3], relating_structure=element
)
rel = subelement1.ReferencedInStructures[0]
assert len(rel.RelatedElements) == 2
assert len(rel.RelatedElements) == 3
class TestReferenceStructureIFC2X3(test.bootstrap.IFC2X3, TestReferenceStructure):
pass
@@ -18,6 +18,8 @@
import test.bootstrap
import ifcopenshell.api
import ifcopenshell.util.classification
import ifcopenshell.util.constraint
import ifcopenshell.util.element
import ifcopenshell.util.system
from datetime import datetime
@@ -186,3 +188,126 @@ class TestTemporarySupportForDeprecatedAPIArguments(test.bootstrap.IFC4):
assert len(self.file.by_type("IfcRelAssociatesMaterial")) == 0
assert len(self.file.by_type("IfcWall")) == 1
assert len(self.file.by_type("IfcMaterial")) == 1
@deprecation_check
def test_adding_a_reference(self):
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
identification="X",
name="Foobar",
classification=result,
)
references = list(ifcopenshell.util.classification.get_references(element))
assert len(references) == 1
assert references[0].Identification == "X"
assert references[0].Name == "Foobar"
assert references[0].ReferencedSource == self.file.by_type("IfcClassification")[0]
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element2,
identification="X",
name="Foobar",
classification=result,
)
assert list(ifcopenshell.util.classification.get_references(element2))[0].Identification == "X"
assert list(ifcopenshell.util.classification.get_references(element2))[0].Name == "Foobar"
assert list(ifcopenshell.util.classification.get_references(element2))[0] == references[0]
@deprecation_check
def test_removing_a_reference(self):
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
reference = ifcopenshell.api.run(
"classification.add_reference",
self.file,
products=[element],
identification="X",
name="Foobar",
classification=result,
)
ifcopenshell.api.run("classification.remove_reference", self.file, product=element, reference=reference)
assert len(ifcopenshell.util.classification.get_references(element)) == 0
assert len(self.file.by_type("IfcClassificationReference")) == 0
@deprecation_check
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 set(reference.LibraryRefForObjects[0].RelatedObjects) == set((product, product2))
@deprecation_check
def test_unassigning_a_reference(self):
reference = self.file.createIfcLibraryReference()
product = self.file.createIfcWall()
ifcopenshell.api.run("library.assign_reference", self.file, products=[product], reference=reference)
ifcopenshell.api.run("library.unassign_reference", self.file, product=product, reference=reference)
assert len(self.file.by_type("IfcRelAssociatesLibrary")) == 0
@deprecation_check
def test_assigning_a_document(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
reference = ifcopenshell.api.run("document.add_reference", self.file, information=None)
ifcopenshell.api.run("document.assign_document", self.file, product=element, document=reference)
assert element.HasAssociations[0].RelatingDocument == reference
@deprecation_check
def test_unassigning_a_document(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
reference = ifcopenshell.api.run("document.add_reference", self.file, information=None)
ifcopenshell.api.run("document.assign_document", self.file, products=[element], document=reference)
ifcopenshell.api.run("document.unassign_document", self.file, product=element, document=reference)
assert not element.HasAssociations
assert not len(self.file.by_type("IfcRelAssociatesDocument"))
@deprecation_check
def test_referencing_a_structure(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
rel = ifcopenshell.api.run(
"spatial.reference_structure", self.file, product=subelement, relating_structure=element
)
assert ifcopenshell.util.element.get_referenced_structures(subelement) == [element]
assert rel.is_a("IfcRelReferencedInSpatialStructure")
@deprecation_check
def test_removing_a_container(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
subelement = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"spatial.reference_structure", self.file, products=[subelement], relating_structure=element
)
ifcopenshell.api.run("spatial.dereference_structure", self.file, product=subelement, relating_structure=element)
assert ifcopenshell.util.element.get_referenced_structures(subelement) == []
@deprecation_check
def test_assign_a_constraint(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
constraint = ifcopenshell.api.run("constraint.add_objective", self.file)
ifcopenshell.api.run("constraint.assign_constraint", self.file, product=element, constraint=constraint)
assert ifcopenshell.util.constraint.get_constrained_elements(constraint) == {element}
@deprecation_check
def test_unassigning_a_constraint(self):
constraint = ifcopenshell.api.run("constraint.add_objective", self.file)
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run(
"constraint.assign_constraint", self.file, product=element, constraint=constraint
)
ifcopenshell.api.run(
"constraint.unassign_constraint", self.file, product=element, constraint=constraint
)
assert ifcopenshell.util.constraint.get_constrained_elements(element) == set()
assert len(self.file.by_type("IfcRelAssociatesConstraint")) == 0
@@ -34,14 +34,14 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element],
reference=reference1,
classification=classification,
)
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element],
reference=reference2,
classification=classification,
)
@@ -54,7 +54,7 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element],
identification="X",
name="Foobar",
classification=result,
@@ -74,14 +74,14 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element],
reference=reference1,
classification=classification,
)
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element_type,
products=[element_type],
reference=reference2,
classification=classification,
)
@@ -103,14 +103,14 @@ class TestGetReferences(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element],
reference=reference1,
classification=classification,
)
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element_type,
products=[element_type],
reference=reference2,
classification=classification,
)
@@ -291,6 +291,16 @@ class TestGetPredefinedTypeIFC4(test.bootstrap.IFC4):
element_type.ProcessType = "FOOBAR"
assert subject.get_predefined_type(element) == "FOOBAR"
def test_getting_an_element_type_predefined_type(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element_type.PredefinedType = "PARTITIONING"
assert subject.get_predefined_type(element_type) == "PARTITIONING"
def test_getting_an_element_type_null_predefined_type(self):
element_type = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWallType")
element_type.PredefinedType = "NOTDEFINED"
assert subject.get_predefined_type(element_type) == "NOTDEFINED"
class TestGetTypeIFC4(test.bootstrap.IFC4):
def test_getting_the_type_of_a_product(self):
@@ -352,12 +362,16 @@ class TestGetMaterial(test.bootstrap.IFC4):
def test_getting_a_material_layer_set_of_a_product(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
rel = ifcopenshell.api.run("material.assign_material", self.file, products=[element], type="IfcMaterialLayerSet")
rel = ifcopenshell.api.run(
"material.assign_material", self.file, products=[element], type="IfcMaterialLayerSet"
)
assert subject.get_material(element) == rel.RelatingMaterial
def test_getting_a_material_profile_set_of_a_product(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
rel = ifcopenshell.api.run("material.assign_material", self.file, products=[element], type="IfcMaterialProfileSet")
rel = ifcopenshell.api.run(
"material.assign_material", self.file, products=[element], type="IfcMaterialProfileSet"
)
assert subject.get_material(element) == rel.RelatingMaterial
def test_getting_a_material_layer_set_usage_of_a_product(self):
@@ -512,7 +526,9 @@ class TestGetElementsByMaterial(test.bootstrap.IFC4):
material_set = ifcopenshell.api.run("material.add_material_set", self.file, set_type="IfcMaterialProfileSet")
ifcopenshell.api.run("material.add_profile", self.file, profile_set=material_set, material=material)
ifcopenshell.api.run("material.assign_material", self.file, products=[element_type], material=material_set)
ifcopenshell.api.run("material.assign_material", self.file, products=[element], type="IfcMaterialProfileSetUsage")
ifcopenshell.api.run(
"material.assign_material", self.file, products=[element], type="IfcMaterialProfileSetUsage"
)
usage = self.file.by_type("IfcMaterialProfileSetUsage")[0]
assert subject.get_elements_by_material(self.file, material) == {element, element_type}
assert subject.get_elements_by_material(self.file, material_set) == {element, element_type}
@@ -703,13 +719,33 @@ class TestGetReferencedStructures(test.bootstrap.IFC4):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
assert subject.get_referenced_structures(element) == []
building = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
ifcopenshell.api.run("spatial.reference_structure", self.file, product=element, relating_structure=building)
ifcopenshell.api.run("spatial.reference_structure", self.file, products=[element], relating_structure=building)
assert subject.get_referenced_structures(element) == [building]
building2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
ifcopenshell.api.run("spatial.reference_structure", self.file, product=element, relating_structure=building2)
ifcopenshell.api.run("spatial.reference_structure", self.file, products=[element], relating_structure=building2)
assert subject.get_referenced_structures(element) == [building, building2]
class TestGetReferencedStructuresIFC2X3(test.bootstrap.IFC2X3, TestGetReferencedStructures):
pass
class TestGetStructureReferencedElements(test.bootstrap.IFC4):
def test_getting_references_of_an_element(self):
building = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcBuilding")
assert subject.get_structure_referenced_elements(building) == set()
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("spatial.reference_structure", self.file, products=[element], relating_structure=building)
assert subject.get_structure_referenced_elements(building) == {element}
element2 = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")
ifcopenshell.api.run("spatial.reference_structure", self.file, products=[element2], relating_structure=building)
assert subject.get_structure_referenced_elements(building) == {element, element2}
class TestGetStructureReferencedElementsIFC2X3(test.bootstrap.IFC2X3, TestGetStructureReferencedElements):
pass
class TestGetDecompositionIFC4(test.bootstrap.IFC4):
def test_getting_decomposed_subelements_of_an_element(self):
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcElementAssembly")
@@ -769,6 +805,50 @@ class TestGetNestIFC2X3(test.bootstrap.IFC2X3, TestGetNestIFC4):
pass
class TestGetReferencedElements(test.bootstrap.IFC4):
# TODO: test other references:
# IfcExternallyDefinedHatchStyle
# IfcExternallyDefinedSurfaceStyle
# IfcExternallyDefinedTextFont
def test_get_elements_referenced_by_classification_reference(self):
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcProject")
elements = [ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall")]
if self.file.schema != "IFC2X3":
elements.append(self.file.create_entity("IfcCostValue"))
result = ifcopenshell.api.run("classification.add_classification", self.file, classification="Name")
reference = ifcopenshell.api.run(
"classification.add_reference",
self.file,
products=elements,
identification="X",
name="Foobar",
classification=result,
)
assert subject.get_referenced_elements(reference) == set(elements)
def test_get_elements_referenced_by_library_reference(self):
reference = self.file.createIfcLibraryReference()
elements = [
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall"),
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall"),
]
ifcopenshell.api.run("library.assign_reference", self.file, reference=reference, products=elements)
assert subject.get_referenced_elements(reference) == set(elements)
def test_get_elements_referenced_by_document_reference(self):
reference = ifcopenshell.api.run("document.add_reference", self.file, information=None)
elements = [
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall"),
ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcWall"),
]
ifcopenshell.api.run("document.assign_document", self.file, document=reference, products=elements)
assert subject.get_referenced_elements(reference) == set(elements)
class TestGetReferencedElementsIFC2X3(test.bootstrap.IFC2X3, TestGetReferencedElements):
pass
class TestReplaceAttributeIFC4(test.bootstrap.IFC4):
def test_replacing_an_elements_attribute(self):
element = self.file.createIfcWall("foo")
@@ -225,7 +225,7 @@ class TestFilterElements(test.bootstrap.IFC4):
ifcopenshell.api.run(
"classification.add_reference",
self.file,
product=element,
products=[element],
identification="X",
name="Foobar",
classification=result,