From 04e5f5036c3c852a47780a5e86d719203e20bacb Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Tue, 2 May 2023 22:14:38 +1000 Subject: [PATCH] See #1676. Deleting space boundaries now also removes connection geometry. --- src/blenderbim/blenderbim/tool/geometry.py | 3 ++ .../api/boundary/remove_boundary.py | 51 +++++++++++++++++++ .../ifcopenshell/api/grid/remove_grid_axis.py | 2 +- .../ifcopenshell/api/root/remove_product.py | 2 +- .../test/api/boundary/test_remove_boundary.py | 35 +++++++++++++ 5 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 src/ifcopenshell-python/ifcopenshell/api/boundary/remove_boundary.py create mode 100644 src/ifcopenshell-python/test/api/boundary/test_remove_boundary.py diff --git a/src/blenderbim/blenderbim/tool/geometry.py b/src/blenderbim/blenderbim/tool/geometry.py index 4523e53687..6912a6783b 100644 --- a/src/blenderbim/blenderbim/tool/geometry.py +++ b/src/blenderbim/blenderbim/tool/geometry.py @@ -71,6 +71,9 @@ class Geometry(blenderbim.core.tool.Geometry): return if element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING": return blenderbim.core.drawing.remove_drawing(tool.Ifc, tool.Drawing, drawing=element) + if element.is_a("IfcRelSpaceBoundary"): + ifcopenshell.api.run("boundary.remove_boundary", tool.Ifc.get(), boundary=element) + return bpy.data.objects.remove(obj) if obj.users_collection and obj.users_collection[0].name == obj.name: parent = ifcopenshell.util.element.get_aggregate(element) if not parent: diff --git a/src/ifcopenshell-python/ifcopenshell/api/boundary/remove_boundary.py b/src/ifcopenshell-python/ifcopenshell/api/boundary/remove_boundary.py new file mode 100644 index 0000000000..cdbbd37586 --- /dev/null +++ b/src/ifcopenshell-python/ifcopenshell/api/boundary/remove_boundary.py @@ -0,0 +1,51 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2023 Dion Moult +# +# 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 . + +import ifcopenshell.util.element + + +class Usecase: + def __init__(self, file, boundary=None): + """Removes a space boundary + + The relating space or related building element is untouched. Only the + boundary and its connection geometry is removed. + + :param boundary: The IfcRelSpaceBoundary you want to remove. + :type boundary: ifcopenshell.entity_instance.entity_instance + :return: None + :rtype: None + + Example: + + # A boring boundary with no geometry. Note that this boundary is + # invalid and does not relate to any space or building element. + boundary = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcRelSpaceBoundary") + + # Let's remove it! + ifcopenshell.api.run("grid.remove_grid_axis", model, axis=axis_2) + """ + self.file = file + self.settings = {"boundary": boundary} + + def execute(self): + geometry = self.settings["boundary"].ConnectionGeometry + if geometry: + self.settings["boundary"].ConnectionGeometry = None + ifcopenshell.util.element.remove_deep2(self.file, geometry) + self.file.remove(self.settings["boundary"]) diff --git a/src/ifcopenshell-python/ifcopenshell/api/grid/remove_grid_axis.py b/src/ifcopenshell-python/ifcopenshell/api/grid/remove_grid_axis.py index ab688a59d1..d14ee8cf0b 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/grid/remove_grid_axis.py +++ b/src/ifcopenshell-python/ifcopenshell/api/grid/remove_grid_axis.py @@ -37,7 +37,7 @@ class Usecase: axis_1 = ifcopenshell.api.run("grid.create_grid_axis", model, axis_tag="1", uvw_axes="VAxes", grid=grid) - # Let's create a third so we can remvoe it later + # Let's create a third so we can remove it later axis_2 = ifcopenshell.api.run("grid.create_grid_axis", model, axis_tag="2", uvw_axes="VAxes", grid=grid) diff --git a/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py b/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py index 0dd99a6844..37206881be 100644 --- a/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py +++ b/src/ifcopenshell-python/ifcopenshell/api/root/remove_product.py @@ -105,7 +105,7 @@ class Usecase: else: ifcopenshell.api.run("type.unassign_type", self.file, related_object=self.settings["product"]) elif inverse.is_a("IfcRelSpaceBoundary"): - self.file.remove(inverse) + ifcopenshell.api.run("boundary.remove_boundary", self.file, boundary=inverse) elif inverse.is_a("IfcRelFillsElement"): self.file.remove(inverse) elif inverse.is_a("IfcRelVoidsElement"): diff --git a/src/ifcopenshell-python/test/api/boundary/test_remove_boundary.py b/src/ifcopenshell-python/test/api/boundary/test_remove_boundary.py new file mode 100644 index 0000000000..7a6f3a0a16 --- /dev/null +++ b/src/ifcopenshell-python/test/api/boundary/test_remove_boundary.py @@ -0,0 +1,35 @@ +# IfcOpenShell - IFC toolkit and geometry engine +# Copyright (C) 2023 Dion Moult +# +# 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 . + +import test.bootstrap +import ifcopenshell.api + + +class TestRemoveBoundary(test.bootstrap.IFC4): + def test_run(self): + boundary = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcRelSpaceBoundary") + ifcopenshell.api.run("boundary.remove_boundary", self.file, boundary=boundary) + assert not self.file.by_type("IfcRelSpaceBoundary") + + def test_removing_connection_geometry(self): + geometry = self.file.createIfcConnectionSurfaceGeometry() + boundary = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcRelSpaceBoundary") + boundary.ConnectionGeometry = geometry + ifcopenshell.api.run("boundary.remove_boundary", self.file, boundary=boundary) + assert not self.file.by_type("IfcRelSpaceBoundary") + assert not self.file.by_type("IfcConnectionSurfaceGeometry")