Fix #2787. Fix creating invalid orphaned property and group relationships when removing systems / groups / elements.

This commit is contained in:
Dion Moult
2023-02-21 10:59:47 +11:00
parent 9d8551cb48
commit 03a66d2806
7 changed files with 118 additions and 5 deletions
@@ -16,6 +16,9 @@
# 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 ifcopenshell
import ifcopenshell.api
class Usecase:
def __init__(self, file, group=None):
@@ -40,6 +43,21 @@ class Usecase:
self.settings = {"group": group}
def execute(self):
for rel in self.settings["group"].IsGroupedBy or []:
self.file.remove(rel)
for inverse_id in [i.id() for i in self.file.get_inverse(self.settings["group"])]:
try:
inverse = self.file.by_id(inverse_id)
except:
continue
if inverse.is_a("IfcRelDefinesByProperties"):
ifcopenshell.api.run(
"pset.remove_pset",
self.file,
product=self.settings["group"],
pset=inverse.RelatingPropertyDefinition,
)
elif inverse.is_a("IfcRelAssignsToGroup"):
if inverse.RelatingGroup == self.settings["group"]:
self.file.remove(inverse)
elif len(inverse.RelatedObjects) == 1:
self.file.remove(inverse)
self.file.remove(self.settings["group"])
@@ -27,12 +27,20 @@ class Usecase:
product, but also all of its relationships. It is always recommended to
use this function to prevent orphaned data in your IFC model.
This is intended to be used for removing:
- IfcAnnotation
- IfcElement
- IfcElementType
- IfcSpatialElement
- IfcSpatialElementType
For example, geometric representations are removed. Placement
coordinates are also removed. Properties are removed. Material, type,
containment, aggregation, and nesting relationships are removed (but
naturally, the materials, types, containers, etc themselves remain).
:param product: The IfcProduct to remove.
:param product: The element to remove.
:type product: ifcopenshell.entity_instance.entity_instance
:return: None
:rtype: None
@@ -119,4 +127,7 @@ class Usecase:
self.file.remove(inverse)
elif inverse.is_a("IfcRelConnectsPathElements"):
self.file.remove(inverse)
elif inverse.is_a("IfcRelAssignsToGroup"):
if len(inverse.RelatedObjects) == 1:
self.file.remove(inverse)
self.file.remove(self.settings["product"])
@@ -16,6 +16,9 @@
# 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 ifcopenshell
import ifcopenshell.api
class Usecase:
def __init__(self, file, system=None):
@@ -42,6 +45,21 @@ class Usecase:
self.settings = {"system": system}
def execute(self):
for rel in self.settings["system"].IsGroupedBy or []:
self.file.remove(rel)
for inverse_id in [i.id() for i in self.file.get_inverse(self.settings["system"])]:
try:
inverse = self.file.by_id(inverse_id)
except:
continue
if inverse.is_a("IfcRelDefinesByProperties"):
ifcopenshell.api.run(
"pset.remove_pset",
self.file,
product=self.settings["system"],
pset=inverse.RelatingPropertyDefinition,
)
elif inverse.is_a("IfcRelAssignsToGroup"):
if inverse.RelatingGroup == self.settings["system"]:
self.file.remove(inverse)
elif len(inverse.RelatedObjects) == 1:
self.file.remove(inverse)
self.file.remove(self.settings["system"])