nest.remove_task to clean up ownerhistory in more cases

1) It wasn't removing ownerhistory in the case if task was RelatingObject in IfcRelNests
2) Replaced handling of IfcRelNests as an inverse with direct api calls.
3) Added some basic tests.
This commit is contained in:
Andrej730
2024-06-10 12:00:47 +05:00
parent 277e53d5ac
commit 7c713eee65
2 changed files with 71 additions and 16 deletions
@@ -18,6 +18,7 @@
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.nest
import ifcopenshell.util.element
@@ -64,28 +65,23 @@ def remove_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance) ->
)
if settings["task"].TaskTime:
file.remove(settings["task"].TaskTime)
# Handle IfcRelNests.
if rels := settings["task"].IsNestedBy:
subtasks = rels[0].RelatedObjects
# Use batching for optimization.
ifcopenshell.api.nest.unassign_object(file, subtasks)
for task_ in subtasks:
ifcopenshell.api.run("sequence.remove_task", file, task=task_)
if settings["task"].Nests:
ifcopenshell.api.nest.unassign_object(file, [settings["task"]])
for inverse in file.get_inverse(settings["task"]):
if inverse.is_a("IfcRelSequence"):
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
elif inverse.is_a("IfcRelNests"):
if inverse.RelatingObject == settings["task"]:
for related_object in inverse.RelatedObjects:
ifcopenshell.api.run("sequence.remove_task", file, task=related_object)
elif not inverse.RelatedObjects:
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
elif settings["task"] in inverse.RelatedObjects:
related_objects = list(inverse.RelatedObjects)
related_objects.remove(settings["task"])
if not related_objects:
file.remove(inverse)
else:
inverse.RelatedObjects = related_objects
elif inverse.is_a("IfcRelAssignsToControl"):
if inverse.RelatingControl == settings["task"] or len(inverse.RelatedObjects) == 1:
history = inverse.OwnerHistory
@@ -0,0 +1,59 @@
# IfcOpenShell - IFC toolkit and geometry engine
# Copyright (C) 2021 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.api.nest
import ifcopenshell.api.sequence
# NOTE: sequence module features relies on entities introduced in IFC4
# therefore no IFC2X3 tests
class TestRemoveTask(test.bootstrap.IFC4):
def test_remove_task(self):
self.file.create_entity("IfcProject")
work_schedule = ifcopenshell.api.sequence.add_work_schedule(self.file)
task = ifcopenshell.api.sequence.add_task(self.file, work_schedule=work_schedule)
ifcopenshell.api.sequence.remove_task(self.file, task)
assert len(self.file.by_type("IfcTask")) == 0
def test_remove_task_with_subtasks(self):
self.file.create_entity("IfcProject")
work_schedule = ifcopenshell.api.sequence.add_work_schedule(self.file)
task = ifcopenshell.api.sequence.add_task(self.file, work_schedule=work_schedule)
subtask1 = ifcopenshell.api.sequence.add_task(self.file, work_schedule=work_schedule)
subtask2 = ifcopenshell.api.sequence.add_task(self.file, work_schedule=work_schedule)
ifcopenshell.api.nest.assign_object(self.file, related_objects=[subtask1, subtask2], relating_object=task)
ifcopenshell.api.sequence.remove_task(self.file, task)
assert len(self.file.by_type("IfcTask")) == 0
assert len(self.file.by_type("IfcRelNests")) == 0
def test_remove_subtask(self):
self.file.create_entity("IfcProject")
work_schedule = ifcopenshell.api.sequence.add_work_schedule(self.file)
task = ifcopenshell.api.sequence.add_task(self.file, work_schedule=work_schedule)
subtask1 = ifcopenshell.api.sequence.add_task(self.file, work_schedule=work_schedule)
ifcopenshell.api.nest.assign_object(self.file, related_objects=[subtask1], relating_object=task)
ifcopenshell.api.sequence.remove_task(self.file, subtask1)
assert len(self.file.by_type("IfcTask")) == 1
assert len(self.file.by_type("IfcRelNests")) == 0
class TestRemoveTaskIFC4X3(test.bootstrap.IFC4X3, TestRemoveTask):
pass