This commit is contained in:
Andrej730
2025-02-24 11:37:19 +05:00
parent 0783f8082e
commit 6eda4e389c
34 changed files with 336 additions and 245 deletions
@@ -28,11 +28,8 @@ def remove_cost_item_quantity(
removed.
:param cost_item: The IfcCostItem that the quantity is assigned to
:type cost_item: ifcopenshell.entity_instance
:param physical_quantity: The IfcPhysicalQuantity to remove
:type physical_quantity: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -46,11 +43,9 @@ def remove_cost_item_quantity(
ifcopenshell.api.cost.remove_cost_item(model,
cost_item=item, physical_quantity=quantity)
"""
settings = {"cost_item": cost_item, "physical_quantity": physical_quantity}
if len(file.get_inverse(settings["physical_quantity"])) == 1:
file.remove(settings["physical_quantity"])
if len(file.get_inverse(physical_quantity)) == 1:
file.remove(physical_quantity)
return
quantities = list(settings["cost_item"].CostQuantities or [])
quantities.remove(settings["physical_quantity"])
settings["cost_item"].CostQuantities = quantities
quantities = list(cost_item.CostQuantities or [])
quantities.remove(physical_quantity)
cost_item.CostQuantities = quantities
@@ -28,11 +28,8 @@ def remove_cost_value(
:param parent: The IfcCostItem, IfcConstructionResource, or IfcCostValue
that the IfcCostValue is assigned to.
:type parent: ifcopenshell.entity_instance
:param cost_value: The IfcCostValue that you want to remove
:type parent: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -48,20 +45,18 @@ def remove_cost_value(
ifcopenshell.api.cost.remove_cost_value(model, parent=item, cost_value=value)
"""
settings = {"parent": parent, "cost_value": cost_value}
if len(file.get_inverse(settings["cost_value"])) == 1:
file.remove(settings["cost_value"])
if len(file.get_inverse(cost_value)) == 1:
file.remove(cost_value)
# TODO deep purge
elif settings["parent"].is_a("IfcCostItem"):
values = list(settings["parent"].CostValues)
values.remove(settings["cost_value"])
settings["parent"].CostValues = values if values else None
elif settings["parent"].is_a("IfcConstructionResource"):
values = list(settings["parent"].BaseCosts)
values.remove(settings["cost_value"])
settings["parent"].BaseCosts = values if values else None
elif settings["parent"].is_a("IfcCostValue"):
components = list(settings["parent"].Components)
components.remove(settings["cost_value"])
settings["parent"].Components = components if components else None
elif parent.is_a("IfcCostItem"):
values = list(parent.CostValues)
values.remove(cost_value)
parent.CostValues = values if values else None
elif parent.is_a("IfcConstructionResource"):
values = list(parent.BaseCosts)
values.remove(cost_value)
parent.BaseCosts = values if values else None
elif parent.is_a("IfcCostValue"):
components = list(parent.Components)
components.remove(cost_value)
parent.Components = components if components else None
@@ -23,9 +23,7 @@ def remove_grid_axis(file: ifcopenshell.file, axis: ifcopenshell.entity_instance
"""Removes a grid axis from a grid
:param axis: The IfcGridAxis you want to remove.
:type axis: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -92,19 +92,17 @@ def assign_profile(
"""
usecase = Usecase()
usecase.file = file
usecase.settings = {"material_profile": material_profile, "profile": profile}
return usecase.execute()
return usecase.execute(material_profile, profile)
class Usecase:
file: ifcopenshell.file
settings: dict[str, Any]
def execute(self) -> None:
def execute(self, material_profile: ifcopenshell.entity_instance, profile: ifcopenshell.entity_instance) -> None:
# TODO: handle composite profiles
old_profile = self.settings["material_profile"].Profile
self.settings["material_profile"].Profile = self.settings["profile"]
for profile_set in self.settings["material_profile"].ToMaterialProfileSet:
old_profile = material_profile.Profile
material_profile.Profile = profile
for profile_set in material_profile.ToMaterialProfileSet:
for inverse in self.file.get_inverse(profile_set):
if not inverse.is_a("IfcMaterialProfileSetUsage"):
continue
@@ -113,20 +111,20 @@ class Usecase:
if not rel.is_a("IfcRelAssociatesMaterial"):
continue
for element in rel.RelatedObjects:
self.change_profile(element)
self.change_profile(element, profile)
else:
for rel in inverse.AssociatedTo:
for element in rel.RelatedObjects:
self.change_profile(element)
self.change_profile(element, profile)
if old_profile and len(self.file.get_inverse(old_profile)) == 0:
# TODO: check remove deep
self.file.remove(old_profile)
def change_profile(self, element: ifcopenshell.entity_instance) -> None:
def change_profile(self, element: ifcopenshell.entity_instance, profile: ifcopenshell.entity_instance) -> None:
representation = ifcopenshell.util.representation.get_representation(element, "Model", "Body", "MODEL_VIEW")
if not representation:
return
for subelement in self.file.traverse(representation):
if subelement.is_a("IfcSweptAreaSolid"):
subelement.SweptArea = self.settings["profile"]
subelement.SweptArea = profile
@@ -27,9 +27,7 @@ def remove_organisation(file: ifcopenshell.file, organisation: ifcopenshell.enti
removed.
:param organisation: The IfcOrganization to remove
:type organisation: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -39,31 +37,29 @@ def remove_organisation(file: ifcopenshell.file, organisation: ifcopenshell.enti
identification="AWB", name="Architects Without Ballpens")
ifcopenshell.api.owner.remove_organisation(model, organisation=organisation)
"""
settings = {"organisation": organisation}
for role in settings["organisation"].Roles or []:
for role in organisation.Roles or []:
if len(file.get_inverse(role)) == 1:
ifcopenshell.api.owner.remove_role(file, role=role)
for address in settings["organisation"].Addresses or []:
for address in organisation.Addresses or []:
if len(file.get_inverse(address)) == 1:
ifcopenshell.api.owner.remove_address(file, address=address)
for inverse in file.get_inverse(settings["organisation"]):
for inverse in file.get_inverse(organisation):
if inverse.is_a("IfcOrganizationRelationship"):
if inverse.RelatingOrganization == settings["organisation"]:
if inverse.RelatingOrganization == organisation:
file.remove(inverse)
elif inverse.RelatedOrganizations == (settings["organisation"],):
elif inverse.RelatedOrganizations == (organisation,):
file.remove(inverse)
elif inverse.is_a("IfcDocumentInformation"):
if inverse.Editors == (settings["organisation"],):
if inverse.Editors == (organisation,):
inverse.Editors = None
elif inverse.is_a("IfcPersonAndOrganization"):
ifcopenshell.api.owner.remove_person_and_organisation(file, person_and_organisation=inverse)
elif inverse.is_a("IfcActor"):
ifcopenshell.api.root.remove_product(file, product=inverse)
elif inverse.is_a("IfcResourceLevelRelationship") and not inverse.is_a("IfcOrganizationRelationship"):
if inverse.RelatedResourceObjects == (settings["organisation"],):
if inverse.RelatedResourceObjects == (organisation,):
file.remove(inverse)
elif inverse.is_a("IfcApplication"):
ifcopenshell.api.owner.remove_application(file, application=inverse)
file.remove(settings["organisation"])
file.remove(organisation)
@@ -29,9 +29,7 @@ def remove_person(file: ifcopenshell.file, person: ifcopenshell.entity_instance)
the only responsile person for them.
:param person: The IfcPerson to remove
:type person: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -41,31 +39,30 @@ def remove_person(file: ifcopenshell.file, person: ifcopenshell.entity_instance)
identification="bobthebuilder", family_name="Thebuilder", given_name="Bob")
ifcopenshell.api.owner.remove_person(model, person=person)
"""
settings = {"person": person}
for role in settings["person"].Roles or []:
for role in person.Roles or []:
if len(file.get_inverse(role)) == 1:
ifcopenshell.api.owner.remove_role(file, role=role)
for address in settings["person"].Addresses or []:
for address in person.Addresses or []:
if len(file.get_inverse(address)) == 1:
ifcopenshell.api.owner.remove_address(file, address=address)
for inverse in file.get_inverse(settings["person"]):
for inverse in file.get_inverse(person):
if inverse.is_a("IfcWorkControl"):
if inverse.Creators == (settings["person"],):
if inverse.Creators == (person,):
inverse.Creators = None
elif inverse.is_a("IfcInventory"):
if inverse.ResponsiblePersons == (settings["person"],):
if inverse.ResponsiblePersons == (person,):
# in IFC2X3 ResponsiblePersons is not optional and without it IfcInventory is not valid
if file.schema == "IFC2X3":
ifcopenshell.api.root.remove_product(file, product=inverse)
elif inverse.is_a("IfcDocumentInformation"):
if inverse.Editors == (settings["person"],):
if inverse.Editors == (person,):
inverse.Editors = None
elif inverse.is_a("IfcPersonAndOrganization"):
ifcopenshell.api.owner.remove_person_and_organisation(file, person_and_organisation=inverse)
elif inverse.is_a("IfcActor"):
ifcopenshell.api.root.remove_product(file, product=inverse)
elif inverse.is_a("IfcResourceLevelRelationship"):
if inverse.RelatedResourceObjects == (settings["person"],):
if inverse.RelatedResourceObjects == (person,):
file.remove(inverse)
file.remove(settings["person"])
file.remove(person)
@@ -80,8 +80,8 @@ def assign_lag_time(
# for whatever reason.
ifcopenshell.api.sequence.assign_lag_time(model, rel_sequence=sequence, lag_value="P1D")
"""
lag_value = file.create_entity("IfcDuration", ifcopenshell.util.date.datetime2ifc(lag_value, "IfcDuration"))
lag_time = file.create_entity("IfcLagTime", DurationType=duration_type, LagValue=lag_value)
duration = file.create_entity("IfcDuration", ifcopenshell.util.date.datetime2ifc(lag_value, "IfcDuration"))
lag_time = file.create_entity("IfcLagTime", DurationType=duration_type, LagValue=duration)
if rel_sequence.is_a("IfcRelSequence"):
if rel_sequence.TimeLag and len(file.get_inverse(rel_sequence.TimeLag)) == 1:
file.remove(rel_sequence.TimeLag)
@@ -25,9 +25,7 @@ def unassign_lag_time(file: ifcopenshell.file, rel_sequence: ifcopenshell.entity
The schedule is cascaded afterwards.
:param rel_sequence: The sequence to remove the lag time from.
:type rel_sequence: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -57,12 +55,8 @@ def unassign_lag_time(file: ifcopenshell.file, rel_sequence: ifcopenshell.entity
# What if you didn't?
ifcopenshell.api.sequence.unassign_lag_time(model, rel_sequence=sequence)
"""
settings = {
"rel_sequence": rel_sequence,
}
if len(file.get_inverse(settings["rel_sequence"].TimeLag)) == 1:
file.remove(settings["rel_sequence"].TimeLag)
if len(file.get_inverse(rel_sequence.TimeLag)) == 1:
file.remove(rel_sequence.TimeLag)
else:
settings["rel_sequence"].TimeLag = None
ifcopenshell.api.sequence.cascade_schedule(file, task=settings["rel_sequence"].RelatedProcess)
rel_sequence.TimeLag = None
ifcopenshell.api.sequence.cascade_schedule(file, task=rel_sequence.RelatedProcess)
@@ -29,18 +29,14 @@ def remove_structural_analysis_model(
:param structural_analysis_model: The IfcStructuralAnalysisModel to
remove.
:type structural_analysis_model: ifcopenshell.entity_instance
:return: None
:rtype: None
"""
settings = {"structural_analysis_model": structural_analysis_model}
for rel in settings["structural_analysis_model"].IsGroupedBy or []:
for rel in structural_analysis_model.IsGroupedBy or []:
history = rel.OwnerHistory
file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
history = settings["structural_analysis_model"].OwnerHistory
file.remove(settings["structural_analysis_model"])
history = structural_analysis_model.OwnerHistory
file.remove(structural_analysis_model)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
@@ -28,23 +28,21 @@ def remove_structural_boundary_condition(
:param connection: The IfcStructuralConnection to remove the condition
from. If omitted, it is assumed to be an orphaned condition.
:type connection: ifcopenshell.entity_instance,optional
:param boundary_condition: The IfcBoundaryCondition to remove.
:type boundary_condition: ifcopenshell.entity_instance, optional.
:return: None
:rtype: None
"""
settings = {"connection": connection, "boundary_condition": boundary_condition}
if settings["connection"]:
if connection:
# remove boundary condition from a connection
if not settings["connection"].AppliedCondition:
if not connection.AppliedCondition:
return
if len(file.get_inverse(settings["connection"].AppliedCondition)) == 1:
file.remove(settings["connection"].AppliedCondition)
settings["connection"].AppliedCondition = None
applied_condition = connection.AppliedCondition
if file.get_total_inverses(applied_condition) == 1:
file.remove(applied_condition)
connection.AppliedCondition = None
else:
assert boundary_condition, "Either connection or boundary_condition must be provided."
# remove the boundary condition
for conn in file.get_inverse(settings["boundary_condition"]):
for conn in file.get_inverse(boundary_condition):
conn.AppliedCondition = None
file.remove(settings["boundary_condition"])
file.remove(boundary_condition)
@@ -22,10 +22,6 @@ def remove_structural_load(file: ifcopenshell.file, structural_load: ifcopenshel
"""Removes a structural load
:param structural_load: The IfcStructuralLoad to remove.
:type structural_load: ifcopenshell.entity_instance
:return: None
:rtype: None
"""
settings = {"structural_load": structural_load}
file.remove(settings["structural_load"])
file.remove(structural_load)
@@ -25,18 +25,14 @@ def remove_structural_load_case(file: ifcopenshell.file, load_case: ifcopenshell
"""Removes a structural load case
:param load_case: The IfcStructuralLoadCase to remove.
:type load_case: ifcopenshell.entity_instance
:return: None
:rtype: None
"""
settings = {"load_case": load_case}
# TODO: do a deep purge
for rel in settings["load_case"].IsGroupedBy or []:
for rel in load_case.IsGroupedBy or []:
history = rel.OwnerHistory
file.remove(rel)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
history = settings["load_case"].OwnerHistory
file.remove(settings["load_case"])
history = load_case.OwnerHistory
file.remove(load_case)
ifcopenshell.util.element.remove_deep2(file, history)
@@ -25,20 +25,16 @@ def remove_structural_load_group(file: ifcopenshell.file, load_group: ifcopenshe
"""Removes a structural load group
:param load_group: The IfcStructuralLoadGroup to remove.
:type load_group: ifcopenshell.entity_instance
:return: None
:rtype: None
"""
settings = {"load_group": load_group}
# TODO: do a deep purge
for inverse in file.get_inverse(settings["load_group"]):
for inverse in file.get_inverse(load_group):
if inverse.is_a("IfcRelAssignsToGroup") and len(inverse.RelatedObjects) == 1:
history = inverse.OwnerHistory
file.remove(inverse)
if history:
ifcopenshell.util.element.remove_deep2(file, history)
history = settings["load_group"].OwnerHistory
file.remove(settings["load_group"])
history = load_group.OwnerHistory
file.remove(load_group)
if history:
ifcopenshell.util.element.remove_deep2(file, history)