mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +00:00
typing
This commit is contained in:
@@ -64,13 +64,10 @@ def assign_object(
|
||||
|
||||
:param products: The list of parts of the aggregate, typically of IfcElement or
|
||||
IfcSpatialStructureElement subclass
|
||||
:type product: list[ifcopenshell.entity_instance]
|
||||
:param relating_object: The whole of the aggregate, typically an
|
||||
IfcElement or IfcSpatialStructureElement subclass
|
||||
:type relating_object: ifcopenshell.entity_instance
|
||||
:return: The IfcRelAggregate relationship instance
|
||||
or `None` if `products` was empty list.
|
||||
:rtype: Union[ifcopenshell.entity_instance, None]
|
||||
|
||||
Example:
|
||||
|
||||
@@ -86,16 +83,10 @@ def assign_object(
|
||||
# The site has a building
|
||||
ifcopenshell.api.aggregate.assign_object(model, products=[subelement], relating_object=element)
|
||||
"""
|
||||
settings = {
|
||||
"products": products,
|
||||
"relating_object": relating_object,
|
||||
}
|
||||
|
||||
if not settings["products"]:
|
||||
if not products:
|
||||
return
|
||||
|
||||
products = set(settings["products"])
|
||||
relating_object = settings["relating_object"]
|
||||
products_set = set(products)
|
||||
is_decomposed_by = next((i for i in relating_object.IsDecomposedBy if i.is_a("IfcRelAggregates")), None)
|
||||
|
||||
previous_aggregates_rels: set[ifcopenshell.entity_instance] = set()
|
||||
@@ -103,7 +94,7 @@ def assign_object(
|
||||
products_with_aggregates: list[ifcopenshell.entity_instance] = []
|
||||
|
||||
# check if there is anything to change
|
||||
for product in products:
|
||||
for product in products_set:
|
||||
product_rel = next(iter(product.Decomposes), None)
|
||||
|
||||
if product_rel is None:
|
||||
@@ -129,7 +120,7 @@ def assign_object(
|
||||
|
||||
# unassign elements from previous aggregates
|
||||
for decomposes in previous_aggregates_rels:
|
||||
related_objects = set(decomposes.RelatedObjects) - products
|
||||
related_objects = set(decomposes.RelatedObjects) - products_set
|
||||
if related_objects:
|
||||
decomposes.RelatedObjects = list(related_objects)
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": decomposes})
|
||||
@@ -141,7 +132,7 @@ def assign_object(
|
||||
|
||||
# assign elements to a new aggregate
|
||||
if is_decomposed_by:
|
||||
is_decomposed_by.RelatedObjects = list(set(is_decomposed_by.RelatedObjects) | products)
|
||||
is_decomposed_by.RelatedObjects = list(set(is_decomposed_by.RelatedObjects) | products_set)
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": is_decomposed_by})
|
||||
else:
|
||||
is_decomposed_by = file.create_entity(
|
||||
@@ -149,7 +140,7 @@ def assign_object(
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"RelatedObjects": list(products),
|
||||
"RelatedObjects": list(products_set),
|
||||
"RelatingObject": relating_object,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -23,9 +23,7 @@ def copy_boundary(file: ifcopenshell.file, boundary: ifcopenshell.entity_instanc
|
||||
"""Copies a space boundary
|
||||
|
||||
:param boundary: The IfcRelSpaceBoundary you want to copy.
|
||||
:type boundary: ifcopenshell.entity_instance
|
||||
:return: Duplicate of the IfcRelSpaceBoundary
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -36,9 +34,7 @@ def copy_boundary(file: ifcopenshell.file, boundary: ifcopenshell.entity_instanc
|
||||
# And now we have two
|
||||
boundary_copy = ifcopenshell.api.boundary.copy_boundary(model, boundary=boundary)
|
||||
"""
|
||||
settings = {"boundary": boundary}
|
||||
|
||||
result = ifcopenshell.util.element.copy(file, settings["boundary"])
|
||||
result = ifcopenshell.util.element.copy(file, boundary)
|
||||
if result.ConnectionGeometry:
|
||||
result.ConnectionGeometry = ifcopenshell.util.element.copy_deep(file, result.ConnectionGeometry)
|
||||
return result
|
||||
|
||||
@@ -27,9 +27,7 @@ def remove_boundary(file: ifcopenshell.file, boundary: ifcopenshell.entity_insta
|
||||
boundary and its connection geometry is removed.
|
||||
|
||||
:param boundary: The IfcRelSpaceBoundary you want to remove.
|
||||
:type boundary: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -40,13 +38,11 @@ def remove_boundary(file: ifcopenshell.file, boundary: ifcopenshell.entity_insta
|
||||
# Let's remove it!
|
||||
ifcopenshell.api.boundary.remove_boundary(model, boundary=boundary)
|
||||
"""
|
||||
settings = {"boundary": boundary}
|
||||
|
||||
geometry = settings["boundary"].ConnectionGeometry
|
||||
geometry = boundary.ConnectionGeometry
|
||||
if geometry:
|
||||
settings["boundary"].ConnectionGeometry = None
|
||||
boundary.ConnectionGeometry = None
|
||||
ifcopenshell.util.element.remove_deep2(file, geometry)
|
||||
history = settings["boundary"].OwnerHistory
|
||||
file.remove(settings["boundary"])
|
||||
history = boundary.OwnerHistory
|
||||
file.remove(boundary)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -28,9 +28,7 @@ def add_metric(file: ifcopenshell.file, objective: ifcopenshell.entity_instance)
|
||||
to meet the objective of the constraint.
|
||||
|
||||
:param objective: The IfcObjective that this metric is a benchmark of.
|
||||
:type objective: ifcopenshell.entity_instance
|
||||
:return: The newly created IfcMetric entity
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -40,10 +38,6 @@ def add_metric(file: ifcopenshell.file, objective: ifcopenshell.entity_instance)
|
||||
metric = ifcopenshell.api.constraint.add_metric(model,
|
||||
objective=objective)
|
||||
"""
|
||||
settings = {
|
||||
"objective": objective,
|
||||
}
|
||||
|
||||
metric = file.create_entity(
|
||||
"IfcMetric",
|
||||
**{
|
||||
@@ -52,8 +46,9 @@ def add_metric(file: ifcopenshell.file, objective: ifcopenshell.entity_instance)
|
||||
"Benchmark": "EQUALTO",
|
||||
},
|
||||
)
|
||||
if settings["objective"]:
|
||||
benchmark_values = list(settings["objective"].BenchmarkValues or [])
|
||||
if objective:
|
||||
benchmark_values: list[ifcopenshell.entity_instance]
|
||||
benchmark_values = list(objective.BenchmarkValues or [])
|
||||
benchmark_values.append(metric)
|
||||
settings["objective"].BenchmarkValues = benchmark_values
|
||||
objective.BenchmarkValues = benchmark_values
|
||||
return metric
|
||||
|
||||
@@ -29,7 +29,6 @@ def add_objective(file: ifcopenshell.file) -> ifcopenshell.entity_instance:
|
||||
quantities. See ifcopenshell.api.constraint.add_metric for more information.
|
||||
|
||||
:return: The newly created IfcObjective entity
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -42,8 +41,6 @@ def add_objective(file: ifcopenshell.file) -> ifcopenshell.entity_instance:
|
||||
# Note: the objective right now is purely qualitative and for
|
||||
# information purposes. You may wish to add quantiative metrics.
|
||||
"""
|
||||
settings = {}
|
||||
|
||||
return file.create_entity(
|
||||
"IfcObjective", **{"Name": "Unnamed", "ConstraintGrade": "NOTDEFINED", "ObjectiveQualifier": "NOTDEFINED"}
|
||||
)
|
||||
|
||||
@@ -41,9 +41,7 @@ def remove_constraint(file: ifcopenshell.file, constraint: ifcopenshell.entity_i
|
||||
ifcopenshell.api.constraint.remove_constraint(model,
|
||||
constraint=objective)
|
||||
"""
|
||||
settings = {"constraint": constraint}
|
||||
|
||||
file.remove(settings["constraint"])
|
||||
file.remove(constraint)
|
||||
for rel in file.by_type("IfcRelAssociatesConstraint"):
|
||||
if not rel.RelatingConstraint:
|
||||
history = rel.OwnerHistory
|
||||
|
||||
@@ -29,9 +29,7 @@ def remove_context(file: ifcopenshell.file, context: ifcopenshell.entity_instanc
|
||||
removed. If a context is removed, then any subcontexts are also removed.
|
||||
|
||||
:param context: The IfcGeometricRepresentationContext entity to remove
|
||||
:type context: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -46,22 +44,20 @@ def remove_context(file: ifcopenshell.file, context: ifcopenshell.entity_instanc
|
||||
# Let's just get rid of it completely
|
||||
ifcopenshell.api.context.remove_context(model, context=body)
|
||||
"""
|
||||
settings = {"context": context}
|
||||
|
||||
for subcontext in settings["context"].HasSubContexts:
|
||||
for subcontext in context.HasSubContexts:
|
||||
ifcopenshell.api.context.remove_context(file, context=subcontext)
|
||||
|
||||
if getattr(settings["context"], "ParentContext", None):
|
||||
new = settings["context"].ParentContext
|
||||
for inverse in file.get_inverse(settings["context"]):
|
||||
if getattr(context, "ParentContext", None):
|
||||
new = context.ParentContext
|
||||
for inverse in file.get_inverse(context):
|
||||
if inverse.is_a("IfcCoordinateOperation"):
|
||||
inverse.SourceCRS = inverse.TargetCRS
|
||||
ifcopenshell.util.element.remove_deep(file, inverse)
|
||||
else:
|
||||
ifcopenshell.util.element.replace_attribute(inverse, settings["context"], new)
|
||||
file.remove(settings["context"])
|
||||
ifcopenshell.util.element.replace_attribute(inverse, context, new)
|
||||
file.remove(context)
|
||||
else:
|
||||
representations_in_context = settings["context"].RepresentationsInContext
|
||||
file.remove(settings["context"])
|
||||
representations_in_context = context.RepresentationsInContext
|
||||
file.remove(context)
|
||||
for element in representations_in_context:
|
||||
ifcopenshell.api.geometry.remove_representation(file, representation=element)
|
||||
|
||||
@@ -42,12 +42,9 @@ def assign_control(
|
||||
|
||||
:param relating_control: The IfcControl entity that is creating the
|
||||
control or constraint
|
||||
:type relating_control: ifcopenshell.entity_instance
|
||||
:param related_object: The IfcObjectDefinition that is being controlled
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: The newly created IfcRelAssignsToControl. If relationship already
|
||||
existed before and wasn't changed then returns None.
|
||||
:rtype: ifcopenshell.entity_instance, None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -72,25 +69,20 @@ def assign_control(
|
||||
ifcopenshell.api.control.assign_control(model,
|
||||
relating_control=cost_item, related_object=wall)
|
||||
"""
|
||||
settings = {
|
||||
"relating_control": relating_control,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
if settings["related_object"].HasAssignments:
|
||||
for assignment in settings["related_object"].HasAssignments:
|
||||
if assignment.is_a("IfcRelAssignsToControl") and assignment.RelatingControl == settings["relating_control"]:
|
||||
if related_object.HasAssignments:
|
||||
for assignment in related_object.HasAssignments:
|
||||
if assignment.is_a("IfcRelAssignsToControl") and assignment.RelatingControl == relating_control:
|
||||
return
|
||||
|
||||
controls = None
|
||||
if settings["relating_control"].Controls:
|
||||
controls = settings["relating_control"].Controls[0]
|
||||
if relating_control.Controls:
|
||||
controls = relating_control.Controls[0]
|
||||
|
||||
if controls:
|
||||
if settings["related_object"] in controls.RelatedObjects:
|
||||
if related_object in controls.RelatedObjects:
|
||||
return
|
||||
related_objects = set(controls.RelatedObjects)
|
||||
related_objects.add(settings["related_object"])
|
||||
related_objects.add(related_object)
|
||||
controls.RelatedObjects = list(related_objects)
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": controls})
|
||||
else:
|
||||
@@ -99,8 +91,8 @@ def assign_control(
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"RelatedObjects": [settings["related_object"]],
|
||||
"RelatingControl": settings["relating_control"],
|
||||
"RelatedObjects": [related_object],
|
||||
"RelatingControl": relating_control,
|
||||
},
|
||||
)
|
||||
return controls
|
||||
|
||||
@@ -31,12 +31,9 @@ def unassign_control(
|
||||
|
||||
:param relating_control: The IfcControl entity that is creating the
|
||||
control or constraint
|
||||
:type relating_control: ifcopenshell.entity_instance
|
||||
:param related_object: The IfcObjectDefinition that is being controlled
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: If the control still is related to other objects, the
|
||||
IfcRelAssignsToControl is returned, otherwise None.
|
||||
:rtype: ifcopenshell.entity_instance, None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -54,14 +51,8 @@ def unassign_control(
|
||||
ifcopenshell.api.control.unassign_control(model,
|
||||
relating_control=cost_item, related_object=wall)
|
||||
"""
|
||||
|
||||
settings = {
|
||||
"relating_control": relating_control,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
for rel in settings["related_object"].HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToControl") or rel.RelatingControl != settings["relating_control"]:
|
||||
for rel in related_object.HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToControl") or rel.RelatingControl != relating_control:
|
||||
continue
|
||||
if len(rel.RelatedObjects) == 1:
|
||||
history = rel.OwnerHistory
|
||||
@@ -70,7 +61,7 @@ def unassign_control(
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
return
|
||||
related_objects = list(rel.RelatedObjects)
|
||||
related_objects.remove(settings["related_object"])
|
||||
related_objects.remove(related_object)
|
||||
rel.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": rel})
|
||||
return rel
|
||||
|
||||
@@ -54,12 +54,9 @@ def add_cost_item_quantity(
|
||||
using another API call.
|
||||
|
||||
:param cost_item: The IfcCostItem to add the quantity to
|
||||
:type cost_item: ifcopenshell.entity_instance
|
||||
:param ifc_class: The type of quantity to add
|
||||
:type ifc_class: str, optional
|
||||
:return: The newly created quantity entity, chosen from the ifc_class
|
||||
parameter
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -76,20 +73,18 @@ def add_cost_item_quantity(
|
||||
ifcopenshell.api.cost.add_cost_item_quantity(model,
|
||||
cost_item=item, ifc_class="IfcQuantityCount")
|
||||
"""
|
||||
settings = {"cost_item": cost_item, "ifc_class": ifc_class}
|
||||
|
||||
quantity = file.create_entity(settings["ifc_class"], Name="Unnamed")
|
||||
quantity = file.create_entity(ifc_class, Name="Unnamed")
|
||||
# 3 IfcPhysicalSimpleQuantity Value
|
||||
# This is a bold assumption
|
||||
# https://forums.buildingsmart.org/t/how-does-a-cost-item-know-that-it-is-counting-a-controlled-product/3564
|
||||
if settings["ifc_class"] == "IfcQuantityCount":
|
||||
if ifc_class == "IfcQuantityCount":
|
||||
count = 0
|
||||
for rel in settings["cost_item"].Controls:
|
||||
for rel in cost_item.Controls:
|
||||
count += len(rel.RelatedObjects)
|
||||
quantity[3] = count
|
||||
else:
|
||||
quantity[3] = 0.0
|
||||
quantities = list(settings["cost_item"].CostQuantities or [])
|
||||
quantities = list(cost_item.CostQuantities or [])
|
||||
quantities.append(quantity)
|
||||
settings["cost_item"].CostQuantities = quantities
|
||||
cost_item.CostQuantities = quantities
|
||||
return quantity
|
||||
|
||||
@@ -39,13 +39,10 @@ def add_cost_schedule(
|
||||
managing any cost items.
|
||||
|
||||
:param name: The name of the cost schedule.
|
||||
:type name: str, optional
|
||||
:param predefined_type: The predefined type of the cost schedule, chosen
|
||||
from a valid type in the IFC documentation for
|
||||
IfcCostScheduleTypeEnum
|
||||
:type predefined_type: str, optional
|
||||
:return: The newly created IfcCostSchedule entity
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -55,13 +52,11 @@ def add_cost_schedule(
|
||||
# Now that we have a cost schedule, we may add cost items to it
|
||||
item = ifcopenshell.api.cost.add_cost_item(model, cost_schedule=schedule)
|
||||
"""
|
||||
settings = {"name": name, "predefined_type": predefined_type}
|
||||
|
||||
cost_schedule = ifcopenshell.api.root.create_entity(
|
||||
file,
|
||||
ifc_class="IfcCostSchedule",
|
||||
predefined_type=settings["predefined_type"],
|
||||
name=settings["name"],
|
||||
predefined_type=predefined_type,
|
||||
name=name,
|
||||
)
|
||||
if file.schema == "IFC2X3":
|
||||
cost_schedule.UpdateDate = createIfcDateAndTime(file, datetime.now())
|
||||
|
||||
@@ -46,9 +46,7 @@ def add_cost_value(file: ifcopenshell.file, parent: ifcopenshell.entity_instance
|
||||
:param parent: A parent IfcCostItem, if specifying a price directly to a
|
||||
cost item, or a top-level price component. Alternatively, this can
|
||||
be set to a IfcCostValue, if specifying price subcomponents.
|
||||
:type parent: ifcopenshell.entity_instance
|
||||
:return: The newly created IfcCostValue
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -91,19 +89,17 @@ def add_cost_value(file: ifcopenshell.file, parent: ifcopenshell.entity_instance
|
||||
ifcopenshell.api.cost.edit_cost_value(model,
|
||||
cost_value=subvalue2, attributes={"AppliedValue": 3.0})
|
||||
"""
|
||||
settings = {"parent": parent}
|
||||
|
||||
value = file.create_entity("IfcCostValue")
|
||||
if settings["parent"].is_a("IfcCostItem"):
|
||||
values = list(settings["parent"].CostValues or [])
|
||||
if parent.is_a("IfcCostItem"):
|
||||
values = list(parent.CostValues or [])
|
||||
values.append(value)
|
||||
settings["parent"].CostValues = values
|
||||
elif settings["parent"].is_a("IfcConstructionResource"):
|
||||
values = list(settings["parent"].BaseCosts or [])
|
||||
parent.CostValues = values
|
||||
elif parent.is_a("IfcConstructionResource"):
|
||||
values = list(parent.BaseCosts or [])
|
||||
values.append(value)
|
||||
settings["parent"].BaseCosts = values
|
||||
elif settings["parent"].is_a("IfcCostValue"):
|
||||
values = list(settings["parent"].Components or [])
|
||||
parent.BaseCosts = values
|
||||
elif parent.is_a("IfcCostValue"):
|
||||
values = list(parent.Components or [])
|
||||
values.append(value)
|
||||
settings["parent"].Components = values
|
||||
parent.Components = values
|
||||
return value
|
||||
|
||||
@@ -36,11 +36,8 @@ def assign_cost_value(
|
||||
rates as a "template" to quickly populate your rates from.
|
||||
|
||||
:param cost_item: The IfcCostItem that you want to copy the values to
|
||||
:type cost_item: ifcopenshell.entity_instance
|
||||
:param cost_rate: The IfcCostItem that you want to copy the values from
|
||||
:type cost_rate: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -61,16 +58,14 @@ def assign_cost_value(
|
||||
# Now the cost item has the same rate as the one from the schedule of rate's item
|
||||
ifcopenshell.api.cost.assign_cost_value(model, cost_item=item, cost_rate=rate)
|
||||
"""
|
||||
settings = {"cost_item": cost_item, "cost_rate": cost_rate}
|
||||
|
||||
if settings["cost_item"].CostValues:
|
||||
if cost_item.CostValues:
|
||||
[
|
||||
ifcopenshell.api.cost.remove_cost_value(
|
||||
file,
|
||||
parent=settings["cost_item"],
|
||||
parent=cost_item,
|
||||
cost_value=cost_value,
|
||||
)
|
||||
for cost_value in settings["cost_item"].CostValues
|
||||
for cost_value in cost_item.CostValues
|
||||
]
|
||||
# This is an assumption, and not part of the official IFC documentation
|
||||
settings["cost_item"].CostValues = settings["cost_rate"].CostValues
|
||||
cost_item.CostValues = cost_rate.CostValues
|
||||
|
||||
@@ -83,13 +83,11 @@ def calculate_cost_item_resource_value(file: ifcopenshell.file, cost_item: ifcop
|
||||
# (42 * 200) + 50000 = 58400 is our calculated cost
|
||||
ifcopenshell.api.cost.calculate_cost_item_resource_value(model, cost_item=item)
|
||||
"""
|
||||
settings = {"cost_item": cost_item}
|
||||
|
||||
for cost_value in settings["cost_item"].CostValues or []:
|
||||
ifcopenshell.api.cost.remove_cost_value(file, parent=settings["cost_item"], cost_value=cost_value)
|
||||
for cost_value in cost_item.CostValues or []:
|
||||
ifcopenshell.api.cost.remove_cost_value(file, parent=cost_item, cost_value=cost_value)
|
||||
|
||||
resources = []
|
||||
for rel in settings["cost_item"].Controls or []:
|
||||
for rel in cost_item.Controls or []:
|
||||
for related_object in rel.RelatedObjects:
|
||||
if related_object.is_a("IfcConstructionResource"):
|
||||
resources.append(related_object)
|
||||
@@ -112,6 +110,6 @@ def calculate_cost_item_resource_value(file: ifcopenshell.file, cost_item: ifcop
|
||||
if unit and "day" in unit:
|
||||
quantity = quantity / 8 # Assume 8 hour working day - TODO implement resource calendar
|
||||
formula = "{}*{}".format(cost, quantity)
|
||||
cost_value = ifcopenshell.api.cost.add_cost_value(file, parent=settings["cost_item"])
|
||||
cost_value = ifcopenshell.api.cost.add_cost_value(file, parent=cost_item)
|
||||
cost_value.Name = resource.Name
|
||||
ifcopenshell.api.cost.edit_cost_value_formula(file, cost_value=cost_value, formula=formula)
|
||||
|
||||
@@ -29,9 +29,7 @@ def remove_cost_item(file: ifcopenshell.file, cost_item: ifcopenshell.entity_ins
|
||||
retained.
|
||||
|
||||
:param cost_item: The IfcCostItem entity you want to remove
|
||||
:type cost_item: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -41,15 +39,13 @@ def remove_cost_item(file: ifcopenshell.file, cost_item: ifcopenshell.entity_ins
|
||||
item = ifcopenshell.api.cost.add_cost_item(model, cost_schedule=schedule)
|
||||
ifcopenshell.api.cost.remove_cost_item(model, cost_item=item)
|
||||
"""
|
||||
settings = {"cost_item": cost_item}
|
||||
|
||||
# TODO: do a deep purge
|
||||
for inverse in file.get_inverse(settings["cost_item"]):
|
||||
for inverse in file.get_inverse(cost_item):
|
||||
if inverse.is_a("IfcRelNests"):
|
||||
if inverse.RelatingObject == settings["cost_item"]:
|
||||
if inverse.RelatingObject == cost_item:
|
||||
for related_object in inverse.RelatedObjects:
|
||||
ifcopenshell.api.cost.remove_cost_item(file, cost_item=related_object)
|
||||
elif inverse.RelatedObjects == (settings["cost_item"],):
|
||||
elif inverse.RelatedObjects == (cost_item,):
|
||||
history = inverse.OwnerHistory
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
@@ -59,7 +55,7 @@ def remove_cost_item(file: ifcopenshell.file, cost_item: ifcopenshell.entity_ins
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
history = settings["cost_item"].OwnerHistory
|
||||
file.remove(settings["cost_item"])
|
||||
history = cost_item.OwnerHistory
|
||||
file.remove(cost_item)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -40,17 +40,15 @@ def remove_cost_schedule(file: ifcopenshell.file, cost_schedule: ifcopenshell.en
|
||||
item = ifcopenshell.api.cost.add_cost_item(model, cost_schedule=schedule)
|
||||
ifcopenshell.api.cost.remove_cost_schedule(model, cost_schedule=schedule)
|
||||
"""
|
||||
settings = {"cost_schedule": cost_schedule}
|
||||
|
||||
# TODO: do a deep purge
|
||||
for inverse in file.get_inverse(settings["cost_schedule"]):
|
||||
for inverse in file.get_inverse(cost_schedule):
|
||||
if inverse.is_a("IfcRelAssignsToControl"):
|
||||
[
|
||||
ifcopenshell.api.cost.remove_cost_item(file, cost_item=related_object)
|
||||
for related_object in inverse.RelatedObjects
|
||||
if related_object.is_a("IfcCostItem")
|
||||
]
|
||||
history = settings["cost_schedule"].OwnerHistory
|
||||
file.remove(settings["cost_schedule"])
|
||||
history = cost_schedule.OwnerHistory
|
||||
file.remove(cost_schedule)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -38,9 +38,7 @@ def add_reference(file: ifcopenshell.file, information: ifcopenshell.entity_inst
|
||||
|
||||
:param information: The IfcDocumentInformation that the reference will
|
||||
be created for
|
||||
:type information: ifcopenshell.entity_instance
|
||||
:return: The newly created IfcDocumentReference entity
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -63,13 +61,11 @@ def add_reference(file: ifcopenshell.file, information: ifcopenshell.entity_inst
|
||||
ifcopenshell.api.document.edit_reference(model,
|
||||
reference=reference2, attributes={"Identification": "2.1.15"})
|
||||
"""
|
||||
settings = {"information": information}
|
||||
|
||||
if file.schema == "IFC2X3":
|
||||
reference = file.create_entity("IfcDocumentReference", ItemReference="X")
|
||||
if settings["information"]:
|
||||
references = list(settings["information"].DocumentReferences or [])
|
||||
if information:
|
||||
references = list(information.DocumentReferences or [])
|
||||
references.append(reference)
|
||||
settings["information"].DocumentReferences = references
|
||||
information.DocumentReferences = references
|
||||
return reference
|
||||
return file.create_entity("IfcDocumentReference", ReferencedDocument=settings["information"], Identification="X")
|
||||
return file.create_entity("IfcDocumentReference", ReferencedDocument=information, Identification="X")
|
||||
|
||||
@@ -30,12 +30,9 @@ def unassign_document(
|
||||
|
||||
:param product: The list of objects that the document reference or information is
|
||||
related to.
|
||||
:type product: list[ifcopenshell.entity_instance]
|
||||
:param document: The IfcDocumentReference (typically) or in rare cases
|
||||
the IfcDocumentInformation that is associated with the product
|
||||
:type document: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -54,27 +51,21 @@ def unassign_document(
|
||||
# Now let's change our mind and remove the association
|
||||
ifcopenshell.api.document.unassign_document(model, products=[storey], document=reference)
|
||||
"""
|
||||
settings = {
|
||||
"products": products,
|
||||
"document": document,
|
||||
}
|
||||
|
||||
# TODO: do we need to support non-ifcroot elements like we do in classification.add_reference?
|
||||
# NOTE: reuses code from `library.un assign_reference`
|
||||
|
||||
reference_rels: set[ifcopenshell.entity_instance] = set()
|
||||
products = set(settings["products"])
|
||||
for product in products:
|
||||
products_set = set(products)
|
||||
for product in products_set:
|
||||
reference_rels.update(product.HasAssociations)
|
||||
|
||||
reference_rels = {
|
||||
rel
|
||||
for rel in reference_rels
|
||||
if rel.is_a("IfcRelAssociatesDocument") and rel.RelatingDocument == settings["document"]
|
||||
rel for rel in reference_rels if rel.is_a("IfcRelAssociatesDocument") and rel.RelatingDocument == document
|
||||
}
|
||||
|
||||
for rel in reference_rels:
|
||||
related_objects = set(rel.RelatedObjects) - products
|
||||
related_objects = set(rel.RelatedObjects) - products_set
|
||||
if related_objects:
|
||||
rel.RelatedObjects = list(related_objects)
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": rel})
|
||||
|
||||
@@ -46,12 +46,9 @@ def assign_product(
|
||||
in 3D.
|
||||
|
||||
:param relating_product: The IfcProduct the object is related to
|
||||
:type relating_product: ifcopenshell.entity_instance
|
||||
:param related_object: The object (typically IfcAnnotation) that the
|
||||
product is related to
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: The created IfcRelAssignsToProduct relationship
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -62,42 +59,36 @@ def assign_product(
|
||||
ifcopenshell.api.drawing.assign_product(model,
|
||||
relating_product=furniture, related_object=annotation)
|
||||
"""
|
||||
settings = {
|
||||
"relating_product": relating_product,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
is_grid_axis = settings["relating_product"].is_a("IfcGridAxis")
|
||||
is_grid_axis = relating_product.is_a("IfcGridAxis")
|
||||
|
||||
if is_grid_axis:
|
||||
if settings["related_object"].HasAssignments:
|
||||
for rel in settings["related_object"].HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToProduct") and rel.Name == settings["relating_product"].AxisTag:
|
||||
if related_object.HasAssignments:
|
||||
for rel in related_object.HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToProduct") and rel.Name == relating_product.AxisTag:
|
||||
return
|
||||
elif settings["related_object"].HasAssignments:
|
||||
for rel in settings["related_object"].HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToProduct") and rel.RelatingProduct == settings["relating_product"]:
|
||||
elif related_object.HasAssignments:
|
||||
for rel in related_object.HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToProduct") and rel.RelatingProduct == relating_product:
|
||||
return
|
||||
|
||||
referenced_by = None
|
||||
|
||||
if is_grid_axis:
|
||||
axis = settings["relating_product"]
|
||||
axis = relating_product
|
||||
grid = None
|
||||
for attribute in ("PartOfW", "PartOfV", "PartOfU"):
|
||||
if getattr(axis, attribute, None):
|
||||
grid = getattr(axis, attribute)[0]
|
||||
settings["relating_product"] = grid
|
||||
for rel in grid.ReferencedBy:
|
||||
if rel.Name == axis.AxisTag:
|
||||
referenced_by = rel
|
||||
break
|
||||
elif settings["relating_product"].ReferencedBy:
|
||||
referenced_by = settings["relating_product"].ReferencedBy[0]
|
||||
elif relating_product.ReferencedBy:
|
||||
referenced_by = relating_product.ReferencedBy[0]
|
||||
|
||||
if referenced_by:
|
||||
related_objects = list(referenced_by.RelatedObjects)
|
||||
related_objects.append(settings["related_object"])
|
||||
related_objects.append(related_object)
|
||||
referenced_by.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": referenced_by})
|
||||
else:
|
||||
@@ -106,8 +97,8 @@ def assign_product(
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"RelatedObjects": [settings["related_object"]],
|
||||
"RelatingProduct": settings["relating_product"],
|
||||
"RelatedObjects": [related_object],
|
||||
"RelatingProduct": relating_product,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
@@ -34,12 +34,9 @@ def unassign_product(
|
||||
object later or leave the annotation as a "dumb" annotation.
|
||||
|
||||
:param relating_product: The IfcProduct the object is related to
|
||||
:type relating_product: ifcopenshell.entity_instance
|
||||
:param related_object: The object (typically IfcAnnotation) that the
|
||||
product is related to
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -54,13 +51,8 @@ def unassign_product(
|
||||
ifcopenshell.api.drawing.unassign_product(model,
|
||||
relating_product=furniture, related_object=annotation)
|
||||
"""
|
||||
settings = {
|
||||
"relating_product": relating_product,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
for rel in settings["related_object"].HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToProduct") or rel.RelatingProduct != settings["relating_product"]:
|
||||
for rel in related_object.HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToProduct") or rel.RelatingProduct != relating_product:
|
||||
continue
|
||||
if len(rel.RelatedObjects) == 1:
|
||||
history = rel.OwnerHistory
|
||||
@@ -69,6 +61,6 @@ def unassign_product(
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
return
|
||||
related_objects = list(rel.RelatedObjects)
|
||||
related_objects.remove(settings["related_object"])
|
||||
related_objects.remove(related_object)
|
||||
rel.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, element=rel)
|
||||
|
||||
@@ -33,11 +33,8 @@ def add_filling(
|
||||
filled.
|
||||
|
||||
:param opening: The IfcOpeningElement to fill with the element.
|
||||
:type opening: ifcopenshell.entity_instance
|
||||
:param element: The IfcElement to be inserted into the opening.
|
||||
:type element: ifcopenshell.entity_instance
|
||||
:return: The new IfcRelFillsElement relationship
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -102,12 +99,10 @@ def add_filling(
|
||||
# The door will now fill the opening.
|
||||
ifcopenshell.api.feature.add_filling(model, opening=opening, element=door)
|
||||
"""
|
||||
settings = {"opening": opening, "element": element}
|
||||
|
||||
fills_voids = settings["element"].FillsVoids
|
||||
fills_voids = element.FillsVoids
|
||||
|
||||
if fills_voids:
|
||||
if fills_voids[0].RelatingOpeningElement == settings["opening"]:
|
||||
if fills_voids[0].RelatingOpeningElement == opening:
|
||||
return fills_voids[0]
|
||||
history = fills_voids[0].OwnerHistory
|
||||
file.remove(fills_voids[0])
|
||||
@@ -117,6 +112,6 @@ def add_filling(
|
||||
return file.create_entity(
|
||||
"IfcRelFillsElement",
|
||||
GlobalId=ifcopenshell.guid.new(),
|
||||
RelatingOpeningElement=settings["opening"],
|
||||
RelatedBuildingElement=settings["element"],
|
||||
RelatingOpeningElement=opening,
|
||||
RelatedBuildingElement=element,
|
||||
)
|
||||
|
||||
@@ -28,9 +28,7 @@ def remove_filling(file: ifcopenshell.file, element: ifcopenshell.entity_instanc
|
||||
fills the opening.
|
||||
|
||||
:param element: The element filling an opening.
|
||||
:type element: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -52,10 +50,8 @@ def remove_filling(file: ifcopenshell.file, element: ifcopenshell.entity_instanc
|
||||
# Not anymore!
|
||||
ifcopenshell.api.feature.remove_filling(model, element=door)
|
||||
"""
|
||||
settings = {"element": element}
|
||||
|
||||
for rel in file.by_type("IfcRelFillsElement"):
|
||||
if rel.RelatedBuildingElement == settings["element"]:
|
||||
if rel.RelatedBuildingElement == element:
|
||||
history = rel.OwnerHistory
|
||||
file.remove(rel)
|
||||
if history:
|
||||
|
||||
@@ -56,13 +56,10 @@ def add_axis_representation(
|
||||
:param context: The IfcGeometricRepresentationContext that the
|
||||
representation is part of. This must be either a
|
||||
Model/Axis/GRAPH_VIEW (3D) or Plan/Axis/GRAPH_VIEW (2D).
|
||||
:type context: ifcopenshell.entity_instance
|
||||
:param axis: The axis, as a list of two coordinates, the coordinates
|
||||
being either a list of 2 or 3 float coordinates depending on whether
|
||||
the axis is 2D or 3D.
|
||||
:type axis: list[list[float]]
|
||||
:return: The newly created IfcShapeRepresentation entity
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
@@ -29,20 +29,14 @@ def connect_element(
|
||||
related_element: ifcopenshell.entity_instance,
|
||||
description: Optional[str] = None,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
settings = {
|
||||
"relating_element": relating_element,
|
||||
"related_element": related_element,
|
||||
"description": description,
|
||||
}
|
||||
|
||||
incompatible_connections = []
|
||||
|
||||
for rel in settings["relating_element"].ConnectedFrom:
|
||||
if rel.is_a() == "IfcRelConnectsElements" and rel.RelatingElement == settings["related_element"]:
|
||||
for rel in relating_element.ConnectedFrom:
|
||||
if rel.is_a() == "IfcRelConnectsElements" and rel.RelatingElement == related_element:
|
||||
incompatible_connections.append(rel)
|
||||
|
||||
for rel in settings["related_element"].ConnectedTo:
|
||||
if rel.is_a() == "IfcRelConnectsElements" and rel.RelatedElement == settings["relating_element"]:
|
||||
for rel in related_element.ConnectedTo:
|
||||
if rel.is_a() == "IfcRelConnectsElements" and rel.RelatedElement == relating_element:
|
||||
incompatible_connections.append(rel)
|
||||
|
||||
if incompatible_connections:
|
||||
@@ -52,15 +46,15 @@ def connect_element(
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
for rel in settings["relating_element"].ConnectedTo:
|
||||
if rel.is_a() == "IfcRelConnectsElements" and rel.RelatedElement == settings["related_element"]:
|
||||
rel.Description = settings["description"]
|
||||
for rel in relating_element.ConnectedTo:
|
||||
if rel.is_a() == "IfcRelConnectsElements" and rel.RelatedElement == related_element:
|
||||
rel.Description = description
|
||||
return rel
|
||||
|
||||
return file.createIfcRelConnectsElements(
|
||||
ifcopenshell.guid.new(),
|
||||
OwnerHistory=ifcopenshell.api.owner.create_owner_history(file),
|
||||
Description=settings["description"],
|
||||
RelatingElement=settings["relating_element"],
|
||||
RelatedElement=settings["related_element"],
|
||||
Description=description,
|
||||
RelatingElement=relating_element,
|
||||
RelatedElement=related_element,
|
||||
)
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
|
||||
def map_representation(
|
||||
@@ -25,15 +24,14 @@ def map_representation(
|
||||
) -> ifcopenshell.entity_instance:
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
usecase.settings = {"representation": representation}
|
||||
return usecase.execute()
|
||||
return usecase.execute(representation)
|
||||
|
||||
|
||||
class Usecase:
|
||||
file: ifcopenshell.file
|
||||
settings: dict[str, Any]
|
||||
|
||||
def execute(self) -> ifcopenshell.entity_instance:
|
||||
def execute(self, representation: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
||||
self.representation = representation
|
||||
mapping_source = self.get_mapping_source()
|
||||
|
||||
zero = self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))
|
||||
@@ -46,15 +44,15 @@ class Usecase:
|
||||
return self.file.create_entity(
|
||||
"IfcShapeRepresentation",
|
||||
**{
|
||||
"ContextOfItems": self.settings["representation"].ContextOfItems,
|
||||
"RepresentationIdentifier": self.settings["representation"].RepresentationIdentifier,
|
||||
"ContextOfItems": representation.ContextOfItems,
|
||||
"RepresentationIdentifier": representation.RepresentationIdentifier,
|
||||
"RepresentationType": "MappedRepresentation",
|
||||
"Items": [mapped_item],
|
||||
}
|
||||
)
|
||||
|
||||
def get_mapping_source(self) -> ifcopenshell.entity_instance:
|
||||
for inverse in self.file.get_inverse(self.settings["representation"]):
|
||||
for inverse in self.file.get_inverse(self.representation):
|
||||
if inverse.is_a("IfcRepresentationMap"):
|
||||
return inverse
|
||||
zero = self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))
|
||||
@@ -62,5 +60,5 @@ class Usecase:
|
||||
z_axis = self.file.createIfcDirection((0.0, 0.0, 1.0))
|
||||
mapping_origin = self.file.createIfcAxis2Placement3D(zero, z_axis, x_axis)
|
||||
return self.file.createIfcRepresentationMap(
|
||||
MappingOrigin=mapping_origin, MappedRepresentation=self.settings["representation"]
|
||||
MappingOrigin=mapping_origin, MappedRepresentation=self.representation
|
||||
)
|
||||
|
||||
@@ -35,12 +35,9 @@ def add_group(
|
||||
or structural load groups, which group together loads for structural
|
||||
analysis, or inventories, which are groups of assets.
|
||||
|
||||
:param Name: The name of the group. Defaults to "Unnamed"
|
||||
:type Name: str, optional
|
||||
:param name: The name of the group. Defaults to "Unnamed"
|
||||
:param description: The description of the purpose of the group.
|
||||
:type description: str, optional
|
||||
:return: The newly created IfcGroup
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -48,17 +45,11 @@ def add_group(
|
||||
|
||||
ifcopenshell.api.group.add_group(model, name="Unit 1A")
|
||||
"""
|
||||
settings = {
|
||||
"name": name or "Unnamed",
|
||||
"description": description,
|
||||
}
|
||||
|
||||
return file.create_entity(
|
||||
"IfcGroup",
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"Name": settings["name"],
|
||||
"Description": settings["description"],
|
||||
}
|
||||
GlobalId=ifcopenshell.guid.new(),
|
||||
OwnerHistory=ifcopenshell.api.owner.create_owner_history(file),
|
||||
Name=name,
|
||||
Description=description,
|
||||
)
|
||||
|
||||
@@ -39,9 +39,7 @@ def remove_group(file: ifcopenshell.file, group: ifcopenshell.entity_instance) -
|
||||
group = ifcopenshell.api.group.add_group(model, name="Unit 1A")
|
||||
ifcopenshell.api.group.remove_group(model, group=group)
|
||||
"""
|
||||
settings = {"group": group}
|
||||
|
||||
for inverse_id in [i.id() for i in file.get_inverse(settings["group"])]:
|
||||
for inverse_id in [i.id() for i in file.get_inverse(group)]:
|
||||
try:
|
||||
inverse = file.by_id(inverse_id)
|
||||
except:
|
||||
@@ -49,11 +47,11 @@ def remove_group(file: ifcopenshell.file, group: ifcopenshell.entity_instance) -
|
||||
if inverse.is_a("IfcRelDefinesByProperties"):
|
||||
ifcopenshell.api.pset.remove_pset(
|
||||
file,
|
||||
product=settings["group"],
|
||||
product=group,
|
||||
pset=inverse.RelatingPropertyDefinition,
|
||||
)
|
||||
elif inverse.is_a("IfcRelAssignsToGroup"):
|
||||
if inverse.RelatingGroup == settings["group"]:
|
||||
if inverse.RelatingGroup == group:
|
||||
history = inverse.OwnerHistory
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
@@ -63,7 +61,7 @@ def remove_group(file: ifcopenshell.file, group: ifcopenshell.entity_instance) -
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
history = settings["group"].OwnerHistory
|
||||
file.remove(settings["group"])
|
||||
history = group.OwnerHistory
|
||||
file.remove(group)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -50,14 +50,10 @@ def add_reference(file: ifcopenshell.file, library: ifcopenshell.entity_instance
|
||||
ifcopenshell.api.library.edit_reference(model,
|
||||
reference=reference, attributes={"Identification": "http://example.org/digitaltwin#AHU01"})
|
||||
"""
|
||||
settings = {
|
||||
"library": library,
|
||||
}
|
||||
|
||||
if file.schema == "IFC2X3":
|
||||
reference = file.createIfcLibraryReference()
|
||||
references = list(settings["library"].LibraryReference or [])
|
||||
references = list(library.LibraryReference or [])
|
||||
references.append(reference)
|
||||
settings["library"].LibraryReference = references
|
||||
library.LibraryReference = references
|
||||
return reference
|
||||
return file.createIfcLibraryReference(ReferencedLibrary=settings["library"])
|
||||
return file.createIfcLibraryReference(ReferencedLibrary=library)
|
||||
|
||||
@@ -33,14 +33,11 @@ def assign_reference(
|
||||
detail about how references work.
|
||||
|
||||
:param products: The list of IfcProducts you want to associate with the reference
|
||||
:type products: list[ifcopenshell.entity_instance]
|
||||
:param reference: The IfcLibraryReference you want the product to be
|
||||
associated with.
|
||||
:type reference: ifcopenshell.entity_instance
|
||||
:return: The IfcRelAssociatesLibrary relationship entity
|
||||
or `None` if `products` was an empty list or all products were
|
||||
already assigned to the `reference`.
|
||||
:rtype: Union[ifcopenshell.entity_instance, None]
|
||||
|
||||
Example:
|
||||
|
||||
@@ -60,38 +57,33 @@ def assign_reference(
|
||||
# And now assign the IFC model's AHU with its Brickschema counterpart
|
||||
ifcopenshell.api.library.assign_reference(model, reference=reference, products=[ahu])
|
||||
"""
|
||||
settings = {
|
||||
"products": products,
|
||||
"reference": reference,
|
||||
}
|
||||
|
||||
# TODO: do we need to support non-ifcroot elements like we do in classification.add_reference?
|
||||
|
||||
referenced_elements = ifcopenshell.util.element.get_referenced_elements(settings["reference"])
|
||||
products: set[ifcopenshell.entity_instance] = set(settings["products"])
|
||||
products = products - referenced_elements
|
||||
referenced_elements = ifcopenshell.util.element.get_referenced_elements(reference)
|
||||
products_set: set[ifcopenshell.entity_instance] = set(products)
|
||||
products_set = products_set - referenced_elements
|
||||
|
||||
if not products:
|
||||
if not products_set:
|
||||
return
|
||||
|
||||
if file.schema == "IFC2X3":
|
||||
rel = next(
|
||||
(r for r in file.by_type("IfcRelAssociatesLibrary") if r.RelatingLibrary == settings["reference"]),
|
||||
(r for r in file.by_type("IfcRelAssociatesLibrary") if r.RelatingLibrary == reference),
|
||||
None,
|
||||
)
|
||||
else:
|
||||
rel = next(iter(settings["reference"].LibraryRefForObjects), None)
|
||||
rel = next(iter(reference.LibraryRefForObjects), None)
|
||||
|
||||
if not rel:
|
||||
return file.create_entity(
|
||||
"IfcRelAssociatesLibrary",
|
||||
GlobalId=ifcopenshell.guid.new(),
|
||||
OwnerHistory=ifcopenshell.api.owner.create_owner_history(file),
|
||||
RelatedObjects=list(products),
|
||||
RelatingLibrary=settings["reference"],
|
||||
RelatedObjects=list(products_set),
|
||||
RelatingLibrary=reference,
|
||||
)
|
||||
|
||||
related_objects = set(rel.RelatedObjects) | products
|
||||
related_objects = set(rel.RelatedObjects) | products_set
|
||||
rel.RelatedObjects = list(related_objects)
|
||||
ifcopenshell.api.owner.update_owner_history(file, element=rel)
|
||||
return rel
|
||||
|
||||
@@ -31,11 +31,8 @@ def unassign_reference(
|
||||
If the product isn't assigned to the reference, nothing will happen.
|
||||
|
||||
:param reference: The IfcLibraryReference to unassign from
|
||||
:type reference: ifcopenshell.entity_instance
|
||||
:param products: A list of IfcProduct elements to unassign from the reference
|
||||
:type products: list[ifcopenshell.entity_instance]
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -58,24 +55,19 @@ def unassign_reference(
|
||||
# Let's change our mind and unassign it.
|
||||
ifcopenshell.api.library.unassign_reference(model, reference=reference, products=[ahu])
|
||||
"""
|
||||
|
||||
settings = {"reference": reference, "products": products}
|
||||
|
||||
# TODO: do we need to support non-ifcroot elements like we do in classification.add_reference?
|
||||
|
||||
reference_rels: set[ifcopenshell.entity_instance] = set()
|
||||
products = set(settings["products"])
|
||||
for product in products:
|
||||
products_set = set(products)
|
||||
for product in products_set:
|
||||
reference_rels.update(product.HasAssociations)
|
||||
|
||||
reference_rels = {
|
||||
rel
|
||||
for rel in reference_rels
|
||||
if rel.is_a("IfcRelAssociatesLibrary") and rel.RelatingLibrary == settings["reference"]
|
||||
rel for rel in reference_rels if rel.is_a("IfcRelAssociatesLibrary") and rel.RelatingLibrary == reference
|
||||
}
|
||||
|
||||
for rel in reference_rels:
|
||||
related_objects = set(rel.RelatedObjects) - products
|
||||
related_objects = set(rel.RelatedObjects) - products_set
|
||||
if related_objects:
|
||||
rel.RelatedObjects = list(related_objects)
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": rel})
|
||||
|
||||
@@ -40,11 +40,8 @@ def add_list_item(
|
||||
|
||||
:param material_list: The IfcMaterialList the material should be added
|
||||
to.
|
||||
:type material_list: ifcopenshell.entity_instance
|
||||
:param material: The IfcMaterial to add to the list
|
||||
:type material: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -80,8 +77,6 @@ def add_list_item(
|
||||
# aluminium and glass.
|
||||
ifcopenshell.api.material.assign_material(model, products=[window_type], material=material_set)
|
||||
"""
|
||||
settings = {"material_list": material_list, "material": material}
|
||||
|
||||
materials = list(settings["material_list"].Materials or [])
|
||||
materials.append(settings["material"])
|
||||
settings["material_list"].Materials = materials
|
||||
materials = list(material_list.Materials or [])
|
||||
materials.append(material)
|
||||
material_list.Materials = materials
|
||||
|
||||
@@ -58,13 +58,9 @@ def add_material(
|
||||
|
||||
:param name: The name of the material, typically tagged in a finishes
|
||||
drawing or schedule.
|
||||
:type name: str, optional
|
||||
:param category: The category of the material.
|
||||
:type category: str, optional
|
||||
:param description: A description of the material.
|
||||
:type description: str, optional
|
||||
:return: The newly created IfcMaterial
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -81,11 +77,9 @@ def add_material(
|
||||
# "Style" has been specified.
|
||||
ifcopenshell.api.material.assign_material(model, products=[concrete_bench], material=concrete)
|
||||
"""
|
||||
settings = {"name": name or "Unnamed", "category": category, "description": description}
|
||||
|
||||
material = file.create_entity("IfcMaterial", **{"Name": settings["name"] or "Unnamed"})
|
||||
if settings["category"]:
|
||||
material.Category = settings["category"]
|
||||
if settings["description"]:
|
||||
material.Description = settings["description"]
|
||||
material = file.create_entity("IfcMaterial", **{"Name": name or "Unnamed"})
|
||||
if category:
|
||||
material.Category = category
|
||||
if description:
|
||||
material.Description = description
|
||||
return material
|
||||
|
||||
@@ -68,14 +68,11 @@ def add_material_set(
|
||||
|
||||
:param name: The name of the material set, which may be purely
|
||||
descriptive or annotated in drawings. Defaults to "Unnamed".
|
||||
:type name: str, optional
|
||||
:param set_type: What type of set you want to create, chosen from
|
||||
IfcMaterialLayerSet, IfcMaterialProfileSet,
|
||||
IfcMaterialConstituentSet, or IfcMaterialList. Defaults to
|
||||
IfcMaterialConstituentSet.
|
||||
:type set_type: str, optional
|
||||
:return: The newly created material set element
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -113,10 +110,8 @@ def add_material_set(
|
||||
# Great! Let's assign our material set to our wall type.
|
||||
ifcopenshell.api.material.assign_material(model, products=[wall_type], material=material_set)
|
||||
"""
|
||||
settings = {"name": name or "Unnamed", "set_type": set_type}
|
||||
|
||||
if settings["set_type"] == "IfcMaterialLayerSet":
|
||||
return file.create_entity("IfcMaterialLayerSet", LayerSetName=settings["name"] or "Unnamed")
|
||||
elif settings["set_type"] == "IfcMaterialList":
|
||||
if set_type == "IfcMaterialLayerSet":
|
||||
return file.create_entity("IfcMaterialLayerSet", LayerSetName=name or "Unnamed")
|
||||
elif set_type == "IfcMaterialList":
|
||||
return file.create_entity("IfcMaterialList")
|
||||
return file.create_entity(settings["set_type"], Name=settings["name"] or "Unnamed")
|
||||
return file.create_entity(set_type, Name=name or "Unnamed")
|
||||
|
||||
@@ -29,9 +29,7 @@ def remove_material(file: ifcopenshell.file, material: ifcopenshell.entity_insta
|
||||
take care of this situation themselves.
|
||||
|
||||
:param material: The IfcMaterial entity you want to remove
|
||||
:type material: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -43,10 +41,8 @@ def remove_material(file: ifcopenshell.file, material: ifcopenshell.entity_insta
|
||||
# ... and remove it
|
||||
ifcopenshell.api.material.remove_material(model, material=aluminium)
|
||||
"""
|
||||
settings = {"material": material}
|
||||
|
||||
inverse_elements = file.get_inverse(settings["material"])
|
||||
file.remove(settings["material"])
|
||||
inverse_elements = file.get_inverse(material)
|
||||
file.remove(material)
|
||||
# TODO: Right now, we we choose only to delete set items (e.g. a layer) but not the material set
|
||||
# This can lead to invalid material sets, but we assume the user will deal with it
|
||||
for inverse in inverse_elements:
|
||||
|
||||
@@ -29,9 +29,7 @@ def remove_material_set(file: ifcopenshell.file, material: ifcopenshell.entity_i
|
||||
|
||||
:param material: The IfcMaterialLayerSet, IfcMaterialConstituentSet,
|
||||
IfcMaterialProfileSet entity you want to remove.
|
||||
:type material: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -55,20 +53,18 @@ def remove_material_set(file: ifcopenshell.file, material: ifcopenshell.entity_i
|
||||
ifcopenshell.api.material.remove_material_set(model, material=material_set)
|
||||
"""
|
||||
|
||||
settings = {"material": material}
|
||||
|
||||
inverse_elements = file.get_inverse(settings["material"])
|
||||
if settings["material"].is_a("IfcMaterialLayerSet"):
|
||||
set_items = settings["material"].MaterialLayers or []
|
||||
elif settings["material"].is_a("IfcMaterialProfileSet"):
|
||||
set_items = settings["material"].MaterialProfiles or []
|
||||
elif settings["material"].is_a("IfcMaterialConstituentSet"):
|
||||
set_items = settings["material"].MaterialConstituents or []
|
||||
elif settings["material"].is_a("IfcMaterialList"):
|
||||
inverse_elements = file.get_inverse(material)
|
||||
if material.is_a("IfcMaterialLayerSet"):
|
||||
set_items = material.MaterialLayers or []
|
||||
elif material.is_a("IfcMaterialProfileSet"):
|
||||
set_items = material.MaterialProfiles or []
|
||||
elif material.is_a("IfcMaterialConstituentSet"):
|
||||
set_items = material.MaterialConstituents or []
|
||||
elif material.is_a("IfcMaterialList"):
|
||||
set_items = []
|
||||
for set_item in set_items:
|
||||
file.remove(set_item)
|
||||
file.remove(settings["material"])
|
||||
file.remove(material)
|
||||
for inverse in inverse_elements:
|
||||
if inverse.is_a("IfcRelAssociatesMaterial"):
|
||||
history = inverse.OwnerHistory
|
||||
|
||||
@@ -49,11 +49,8 @@ def add_actor(
|
||||
IfcPerson if it is a sole individual, or an IfcPersonAndOrganization
|
||||
if a specific person is liable within an organisation and must be
|
||||
legally nominated.
|
||||
:type actor: ifcopenshell.entity_instance
|
||||
:param ifc_class: Either "IfcActor" or "IfcOccupant".
|
||||
:type ifc_class: str, optional
|
||||
:return: The newly created IfcActor or IfcOccupant
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -67,8 +64,7 @@ def add_actor(
|
||||
# Assign that organisation to a newly created actor
|
||||
actor = ifcopenshell.api.owner.add_actor(model, actor=organisation)
|
||||
"""
|
||||
settings = {"actor": actor, "ifc_class": ifc_class or "IfcActor"}
|
||||
|
||||
actor = ifcopenshell.api.root.create_entity(file, ifc_class=settings["ifc_class"])
|
||||
actor.TheActor = settings["actor"]
|
||||
return actor
|
||||
ifc_class = ifc_class or "IfcActor"
|
||||
actor_ = ifcopenshell.api.root.create_entity(file, ifc_class=ifc_class)
|
||||
actor_.TheActor = actor
|
||||
return actor_
|
||||
|
||||
@@ -39,12 +39,9 @@ def add_address(
|
||||
|
||||
:param assigned_object: The IfcOrganization or IfcPerson the contact
|
||||
address belongs to.
|
||||
:type assigned_object: ifcopenshell.entity_instance
|
||||
:param ifc_class: Either IfcPostalAddress or IfcTelecomAddress. Defaults
|
||||
to IfcPostalAddress.
|
||||
:type ifc_class: str, optional
|
||||
:return: The new IfcPostalAddress or IfcTelecomAddress
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -67,10 +64,8 @@ def add_address(
|
||||
"ElectronicMailAddresses": ["bobthebuilder@example.com"],
|
||||
"WWWHomePageURL": "https://thinkmoult.com"})
|
||||
"""
|
||||
settings = {"assigned_object": assigned_object, "ifc_class": ifc_class}
|
||||
|
||||
address = file.create_entity(settings["ifc_class"], "OFFICE")
|
||||
addresses = list(settings["assigned_object"].Addresses) if settings["assigned_object"].Addresses else []
|
||||
address = file.create_entity(ifc_class, "OFFICE")
|
||||
addresses = list(assigned_object.Addresses) if assigned_object.Addresses else []
|
||||
addresses.append(address)
|
||||
settings["assigned_object"].Addresses = addresses
|
||||
assigned_object.Addresses = addresses
|
||||
return address
|
||||
|
||||
@@ -31,11 +31,8 @@ def add_organisation(
|
||||
Sometimes used in drawing naming schemes. Otherise used as a
|
||||
canonicalised way of computers to identify the organisation. Like
|
||||
their stock name.
|
||||
:type identification: str, optional
|
||||
:param name: The legal name of the organisation
|
||||
:type name: str, optional
|
||||
:return: The newly created IfcOrganization
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -44,11 +41,9 @@ def add_organisation(
|
||||
organisation = ifcopenshell.api.owner.add_organisation(model,
|
||||
identification="AWB", name="Architects Without Ballpens")
|
||||
"""
|
||||
settings = {"identification": identification, "name": name}
|
||||
|
||||
data = {"Name": settings["name"]}
|
||||
data = {"Name": name}
|
||||
if file.schema == "IFC2X3":
|
||||
data["Id"] = settings["identification"]
|
||||
data["Id"] = identification
|
||||
else:
|
||||
data["Identification"] = settings["identification"]
|
||||
data["Identification"] = identification
|
||||
return file.create_entity("IfcOrganization", **data)
|
||||
|
||||
@@ -31,13 +31,9 @@ def add_person(
|
||||
|
||||
:param identification: The computer readable unique identification of
|
||||
the person. For example, their username in a CDE or alias.
|
||||
:type identification: str, optional
|
||||
:param family_name: The family name
|
||||
:type family_name: str, optional
|
||||
:param given_name: The given name
|
||||
:type given_name: str, optional
|
||||
:return: The newly created IfcPerson
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -46,15 +42,9 @@ def add_person(
|
||||
ifcopenshell.api.owner.add_person(model,
|
||||
identification="bobthebuilder", family_name="Thebuilder", given_name="Bob")
|
||||
"""
|
||||
settings = {
|
||||
"identification": identification,
|
||||
"family_name": family_name,
|
||||
"given_name": given_name,
|
||||
}
|
||||
|
||||
data = {"FamilyName": settings["family_name"], "GivenName": settings["given_name"]}
|
||||
data = {"FamilyName": family_name, "GivenName": given_name}
|
||||
if file.schema == "IFC2X3":
|
||||
data["Id"] = settings["identification"]
|
||||
data["Id"] = identification
|
||||
else:
|
||||
data["Identification"] = settings["identification"]
|
||||
data["Identification"] = identification
|
||||
return file.create_entity("IfcPerson", **data)
|
||||
|
||||
@@ -30,11 +30,8 @@ def add_person_and_organisation(
|
||||
|
||||
:param person: The IfcPerson being the representative of the
|
||||
organisation.
|
||||
:type person: ifcopenshell.entity_instance
|
||||
:param organisation: The IfcOrganization it
|
||||
:type organisation: ifcopenshell.entity_instance
|
||||
:return: The newly created IfcPersonAndOrganization
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -48,6 +45,4 @@ def add_person_and_organisation(
|
||||
ifcopenshell.api.owner.add_person_and_organisation(model,
|
||||
person=person, organisation=organisation)
|
||||
"""
|
||||
settings = {"person": person, "organisation": organisation}
|
||||
|
||||
return file.createIfcPersonAndOrganization(settings["person"], settings["organisation"])
|
||||
return file.create_entity("IfcPersonAndOrganization", person, organisation)
|
||||
|
||||
@@ -43,11 +43,8 @@ def assign_actor(
|
||||
ifcopenshell.api.resource.assign_resource.
|
||||
|
||||
:param relating_actor: The IfcActor who is responsible for the object.
|
||||
:type relating_actor: ifcopenshell.entity_instance
|
||||
:param related_object: The object the actor is responsible for.
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: The newly created IfcRelAssignsToActor relationship.
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -74,24 +71,19 @@ def assign_actor(
|
||||
ifcopenshell.api.owner.assign_actor(model,
|
||||
relating_actor=manufacturer, related_object=pump_type)
|
||||
"""
|
||||
settings = {
|
||||
"relating_actor": relating_actor,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
if settings["related_object"].HasAssignments:
|
||||
for rel in settings["related_object"].HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToActor") and rel.RelatingActor == settings["relating_actor"]:
|
||||
if related_object.HasAssignments:
|
||||
for rel in related_object.HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToActor") and rel.RelatingActor == relating_actor:
|
||||
return rel
|
||||
|
||||
rel = None
|
||||
|
||||
if settings["relating_actor"].IsActingUpon:
|
||||
rel = settings["relating_actor"].IsActingUpon[0]
|
||||
if relating_actor.IsActingUpon:
|
||||
rel = relating_actor.IsActingUpon[0]
|
||||
|
||||
if rel:
|
||||
related_objects = list(rel.RelatedObjects)
|
||||
related_objects.append(settings["related_object"])
|
||||
related_objects.append(related_object)
|
||||
rel.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": rel})
|
||||
else:
|
||||
@@ -100,8 +92,8 @@ def assign_actor(
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"RelatedObjects": [settings["related_object"]],
|
||||
"RelatingActor": settings["relating_actor"],
|
||||
"RelatedObjects": [related_object],
|
||||
"RelatingActor": relating_actor,
|
||||
}
|
||||
)
|
||||
return rel
|
||||
|
||||
@@ -24,9 +24,7 @@ def remove_actor(file: ifcopenshell.file, actor: ifcopenshell.entity_instance) -
|
||||
"""Removes an actor
|
||||
|
||||
:param actor: The IfcActor to remove.
|
||||
:type actor: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -44,9 +42,7 @@ def remove_actor(file: ifcopenshell.file, actor: ifcopenshell.entity_instance) -
|
||||
# Actually we need ballpens on this project
|
||||
ifcopenshell.api.owner.remove_actor(model, actor=actor)
|
||||
"""
|
||||
settings = {"actor": actor}
|
||||
|
||||
history = settings["actor"].OwnerHistory
|
||||
file.remove(settings["actor"])
|
||||
history = actor.OwnerHistory
|
||||
file.remove(actor)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -25,9 +25,7 @@ def remove_address(file: ifcopenshell.file, address: ifcopenshell.entity_instanc
|
||||
relationship removed.
|
||||
|
||||
:param address: The IfcAddress to remove.
|
||||
:type address: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -40,10 +38,8 @@ def remove_address(file: ifcopenshell.file, address: ifcopenshell.entity_instanc
|
||||
# Change our mind and delete it
|
||||
ifcopenshell.api.owner.remove_address(model, address=address)
|
||||
"""
|
||||
settings = {"address": address}
|
||||
|
||||
for inverse in file.get_inverse(settings["address"]):
|
||||
for inverse in file.get_inverse(address):
|
||||
if inverse.is_a() in ("IfcOrganization", "IfcPerson"):
|
||||
if inverse.Addresses == (settings["address"],):
|
||||
if inverse.Addresses == (address,):
|
||||
inverse.Addresses = None
|
||||
file.remove(settings["address"])
|
||||
file.remove(address)
|
||||
|
||||
@@ -25,9 +25,7 @@ def remove_application(file: ifcopenshell.file, application: ifcopenshell.entity
|
||||
Check whether or not the application is used anywhere prior to removal.
|
||||
|
||||
:param address: The IfcApplication to remove.
|
||||
:type address: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -36,6 +34,4 @@ def remove_application(file: ifcopenshell.file, application: ifcopenshell.entity
|
||||
application = ifcopenshell.api.owner.add_application(model)
|
||||
ifcopenshell.api.owner.remove_address(model, application=application)
|
||||
"""
|
||||
settings = {"application": application}
|
||||
|
||||
file.remove(settings["application"])
|
||||
file.remove(application)
|
||||
|
||||
@@ -28,9 +28,7 @@ def remove_person_and_organisation(
|
||||
the "person and organisation" group.
|
||||
|
||||
:param person_and_organisation: The IfcPersonAndOrganization to remove.
|
||||
:type person_and_organisation: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -46,17 +44,15 @@ def remove_person_and_organisation(
|
||||
|
||||
ifcopenshell.api.owner.remove_person_and_organisation(model, person_and_organisation=user)
|
||||
"""
|
||||
settings = {"person_and_organisation": person_and_organisation}
|
||||
|
||||
for inverse in file.get_inverse(settings["person_and_organisation"]):
|
||||
for inverse in file.get_inverse(person_and_organisation):
|
||||
if inverse.is_a("IfcDocumentInformation"):
|
||||
if inverse.Editors == (settings["person_and_organisation"],):
|
||||
if inverse.Editors == (person_and_organisation,):
|
||||
inverse.Editors = None
|
||||
elif inverse.is_a("IfcActor"):
|
||||
ifcopenshell.api.root.remove_product(file, product=inverse)
|
||||
elif inverse.is_a("IfcResourceLevelRelationship"):
|
||||
if inverse.RelatedResourceObjects == (settings["person_and_organisation"],):
|
||||
if inverse.RelatedResourceObjects == (person_and_organisation,):
|
||||
file.remove(inverse)
|
||||
elif inverse.is_a("IfcOwnerHistory"):
|
||||
file.remove(inverse)
|
||||
file.remove(settings["person_and_organisation"])
|
||||
file.remove(person_and_organisation)
|
||||
|
||||
@@ -25,9 +25,7 @@ def remove_role(file: ifcopenshell.file, role: ifcopenshell.entity_instance) ->
|
||||
leave some of them without roles.
|
||||
|
||||
:param role: The IfcActorRole to remove.
|
||||
:type role: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -40,13 +38,11 @@ def remove_role(file: ifcopenshell.file, role: ifcopenshell.entity_instance) ->
|
||||
# After running this, the organisation will have no role again
|
||||
ifcopenshell.api.owner.remove_role(model, role=role)
|
||||
"""
|
||||
settings = {"role": role}
|
||||
|
||||
for inverse in file.get_inverse(settings["role"]):
|
||||
for inverse in file.get_inverse(role):
|
||||
if inverse.is_a() in ("IfcOrganization", "IfcPerson", "IfcPersonAndOrganization"):
|
||||
if inverse.Roles == (settings["role"],):
|
||||
if inverse.Roles == (role,):
|
||||
inverse.Roles = None
|
||||
elif inverse.is_a("IfcResourceLevelRelationship") and not inverse.is_a("IfcOrganizationRelationship"):
|
||||
if inverse.RelatedResourceObjects == (settings["organisation"],):
|
||||
if inverse.RelatedResourceObjects == (organisation,):
|
||||
file.remove(inverse)
|
||||
file.remove(settings["role"])
|
||||
file.remove(role)
|
||||
|
||||
@@ -29,11 +29,8 @@ def unassign_actor(
|
||||
This means that the actor is no longer responsible for the object.
|
||||
|
||||
:param relating_actor: The IfcActor who is responsible for the object.
|
||||
:type relating_actor: ifcopenshell.entity_instance
|
||||
:param related_object: The object the actor is responsible for.
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -55,13 +52,8 @@ def unassign_actor(
|
||||
ifcopenshell.api.owner.unassign_actor(model,
|
||||
relating_actor=manufacturer, related_object=pump_type)
|
||||
"""
|
||||
settings = {
|
||||
"relating_actor": relating_actor,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
for rel in settings["related_object"].HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToActor") or rel.RelatingActor != settings["relating_actor"]:
|
||||
for rel in related_object.HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToActor") or rel.RelatingActor != relating_actor:
|
||||
continue
|
||||
if len(rel.RelatedObjects) == 1:
|
||||
history = rel.OwnerHistory
|
||||
@@ -70,6 +62,6 @@ def unassign_actor(
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
return
|
||||
related_objects = list(rel.RelatedObjects)
|
||||
related_objects.remove(settings["related_object"])
|
||||
related_objects.remove(related_object)
|
||||
rel.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": rel})
|
||||
|
||||
@@ -59,9 +59,6 @@ def update_owner_history(
|
||||
# API calls either.
|
||||
ifcopenshell.api.attribute.edit_attributes(model, product=space, attributes={"Name": "Lobby"})
|
||||
"""
|
||||
settings = {"element": element}
|
||||
|
||||
element = settings["element"]
|
||||
if not element.is_a("IfcRoot"):
|
||||
return
|
||||
user = ifcopenshell.api.owner.settings.get_user(file)
|
||||
|
||||
@@ -30,9 +30,7 @@ def add_parameterized_profile(file: ifcopenshell.file, ifc_class: str) -> ifcope
|
||||
|
||||
:param ifc_class: The subclass of IfcParameterizedProfileDef that you'd
|
||||
like to create.
|
||||
:type ifc_class: str
|
||||
:return: The newly created element depending on the specified ifc_class.
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -42,6 +40,4 @@ def add_parameterized_profile(file: ifcopenshell.file, ifc_class: str) -> ifcope
|
||||
ifc_class="IfcCircleProfileDef")
|
||||
circle.Radius = 1.
|
||||
"""
|
||||
settings = {"ifc_class": ifc_class}
|
||||
|
||||
return file.create_entity(settings["ifc_class"])
|
||||
return file.create_entity(ifc_class)
|
||||
|
||||
@@ -35,11 +35,10 @@ def remove_profile(file: ifcopenshell.file, profile: ifcopenshell.entity_instanc
|
||||
circle = 1.
|
||||
ifcopenshell.api.profile.remove_profile(model, profile=circle)
|
||||
"""
|
||||
settings = {"profile": profile}
|
||||
is_ifc2x3 = file.schema == "IFC2X3"
|
||||
|
||||
subelements = set()
|
||||
for attribute in settings["profile"]:
|
||||
for attribute in profile:
|
||||
if isinstance(attribute, ifcopenshell.entity_instance):
|
||||
subelements.add(attribute)
|
||||
|
||||
@@ -56,6 +55,6 @@ def remove_profile(file: ifcopenshell.file, profile: ifcopenshell.entity_instanc
|
||||
for pset in profile_psets:
|
||||
ifcopenshell.api.pset.remove_pset(file, product=profile, pset=pset)
|
||||
|
||||
file.remove(settings["profile"])
|
||||
file.remove(profile)
|
||||
for subelement in subelements:
|
||||
ifcopenshell.util.element.remove_deep2(file, subelement)
|
||||
|
||||
@@ -50,9 +50,7 @@ def create_file(version: ifcopenshell.util.schema.IFC_SCHEMA = "IFC4") -> ifcope
|
||||
|
||||
# ... and off we go!
|
||||
"""
|
||||
settings = {"version": version}
|
||||
|
||||
file = ifcopenshell.file(schema=settings["version"])
|
||||
file = ifcopenshell.file(schema=version)
|
||||
file.wrapped_data.header.file_name.name = "/dev/null" # Hehehe
|
||||
file.wrapped_data.header.file_name.time_stamp = (
|
||||
datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc).astimezone().replace(microsecond=0).isoformat()
|
||||
|
||||
@@ -28,11 +28,8 @@ def remove_pset(
|
||||
All properties that are part of this property set are also removed.
|
||||
|
||||
:param product: The IfcObject to remove the property set from.
|
||||
:type product: ifcopenshell.entity_instance
|
||||
:param pset: The IfcPropertySet or IfcElementQuantity to remove.
|
||||
:type pset: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -45,27 +42,25 @@ def remove_pset(
|
||||
# Remove it!
|
||||
ifcopenshell.api.pset.remove_pset(model, product=wall_type, pset=pset)
|
||||
"""
|
||||
settings = {"product": product, "pset": pset}
|
||||
|
||||
to_purge = []
|
||||
should_remove_pset = True
|
||||
for inverse in file.get_inverse(settings["pset"]):
|
||||
for inverse in file.get_inverse(pset):
|
||||
if inverse.is_a("IfcRelDefinesByProperties"):
|
||||
if not inverse.RelatedObjects or len(inverse.RelatedObjects) == 1:
|
||||
to_purge.append(inverse)
|
||||
else:
|
||||
related_objects = list(inverse.RelatedObjects)
|
||||
related_objects.remove(settings["product"])
|
||||
related_objects.remove(product)
|
||||
inverse.RelatedObjects = related_objects
|
||||
should_remove_pset = False
|
||||
if should_remove_pset:
|
||||
properties = [] # Predefined psets have no properties
|
||||
if settings["pset"].is_a("IfcPropertySet"):
|
||||
properties = settings["pset"].HasProperties or []
|
||||
elif settings["pset"].is_a("IfcQuantitySet"):
|
||||
properties = settings["pset"].Quantities or []
|
||||
elif settings["pset"].is_a() in ("IfcMaterialProperties", "IfcProfileProperties"):
|
||||
properties = settings["pset"].Properties or []
|
||||
if pset.is_a("IfcPropertySet"):
|
||||
properties = pset.HasProperties or []
|
||||
elif pset.is_a("IfcQuantitySet"):
|
||||
properties = pset.Quantities or []
|
||||
elif pset.is_a() in ("IfcMaterialProperties", "IfcProfileProperties"):
|
||||
properties = pset.Properties or []
|
||||
for prop in properties:
|
||||
if file.get_total_inverses(prop) != 1:
|
||||
continue
|
||||
@@ -75,8 +70,8 @@ def remove_pset(
|
||||
file.remove(enumeration)
|
||||
file.remove(prop)
|
||||
# IfcMaterialProperties and IfcProfileProperties don't have OwnerHistory
|
||||
history = getattr(settings["pset"], "OwnerHistory", None)
|
||||
file.remove(settings["pset"])
|
||||
history = getattr(pset, "OwnerHistory", None)
|
||||
file.remove(pset)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
for element in to_purge:
|
||||
|
||||
@@ -71,19 +71,15 @@ def add_pset_template(
|
||||
overridden by occurrences, and is applicable to everything.
|
||||
|
||||
:param name: The name of the property set
|
||||
:type name: str,optional
|
||||
:param template_type: Choose from one of PSET_TYPEDRIVENONLY,
|
||||
PSET_TYPEDRIVENOVERRIDE, PSET_OCCURRENCEDRIVEN,
|
||||
PSET_PERFORMANCEDRIVEN, QTO_TYPEDRIVENONLY, QTO_TYPEDRIVENOVERRIDE,
|
||||
QTO_OCCURRENCEDRIVEN, NOTDEFINED
|
||||
:type template_type: str,optional
|
||||
:param applicable_entity: The entity that this template is allowed to be
|
||||
applied to. For example, IfcWall means that the property set may be
|
||||
assigned to walls only. IfcTypeObject, the default, means that the
|
||||
property set may be assigned to any type.
|
||||
:type applicable_entity: str,optional
|
||||
:return: The newly created IfcPropertySetTemplate
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -99,12 +95,10 @@ def add_pset_template(
|
||||
name="HighVoltage", description="Whether there is a risk of high voltage.",
|
||||
primary_measure_type="IfcBoolean")
|
||||
"""
|
||||
settings = {"name": name, "template_type": template_type, "applicable_entity": applicable_entity}
|
||||
|
||||
return file.create_entity(
|
||||
"IfcPropertySetTemplate",
|
||||
GlobalId=ifcopenshell.guid.new(),
|
||||
Name=settings["name"],
|
||||
TemplateType=settings["template_type"],
|
||||
ApplicableEntity=settings["applicable_entity"],
|
||||
Name=name,
|
||||
TemplateType=template_type,
|
||||
ApplicableEntity=applicable_entity,
|
||||
)
|
||||
|
||||
@@ -27,9 +27,7 @@ def remove_prop_template(file: ifcopenshell.file, prop_template: ifcopenshell.en
|
||||
templates.
|
||||
|
||||
:param prop_template: The IfcSimplePropertyTemplate to remove.
|
||||
:type prop_template: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -44,13 +42,11 @@ def remove_prop_template(file: ifcopenshell.file, prop_template: ifcopenshell.en
|
||||
# Let's remove the second one.
|
||||
ifcopenshell.api.pset_template.remove_prop_template(model, prop_template=prop2)
|
||||
"""
|
||||
settings = {"prop_template": prop_template}
|
||||
|
||||
for inverse in file.get_inverse(settings["prop_template"]):
|
||||
for inverse in file.get_inverse(prop_template):
|
||||
if len(inverse.HasPropertyTemplates) == 1:
|
||||
inverse.HasPropertyTemplates = []
|
||||
else:
|
||||
has_property_templates = list(inverse.HasPropertyTemplates)
|
||||
has_property_templates.remove(settings["prop_template"])
|
||||
has_property_templates.remove(prop_template)
|
||||
inverse.HasPropertyTemplates = has_property_templates
|
||||
ifcopenshell.util.element.remove_deep(file, settings["prop_template"])
|
||||
ifcopenshell.util.element.remove_deep(file, prop_template)
|
||||
|
||||
@@ -26,9 +26,7 @@ def remove_pset_template(file: ifcopenshell.file, pset_template: ifcopenshell.en
|
||||
along with it.
|
||||
|
||||
:param pset_template: The IfcPropertySetTemplate to remove.
|
||||
:type pset_template: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -40,6 +38,4 @@ def remove_pset_template(file: ifcopenshell.file, pset_template: ifcopenshell.en
|
||||
# Let's remove the template.
|
||||
ifcopenshell.api.pset_template.remove_pset_template(model, pset_template=template)
|
||||
"""
|
||||
settings = {"pset_template": pset_template}
|
||||
|
||||
ifcopenshell.util.element.remove_deep(file, settings["pset_template"])
|
||||
ifcopenshell.util.element.remove_deep(file, pset_template)
|
||||
|
||||
@@ -51,20 +51,15 @@ def add_resource(
|
||||
|
||||
:param parent_resource: If this is a child resource (typically to a crew
|
||||
resource), then nominate the parent IfcConstructionResource here.
|
||||
:type parent_resource: ifcopenshell.entity_instance, optional
|
||||
:param ifc_class: The class of resource chosen from
|
||||
IfcConstructionEquipmentResource, IfcConstructionMaterialResource,
|
||||
IfcConstructionProductResource, IfcCrewResource, IfcLaborResource,
|
||||
or IfcSubContractResource.
|
||||
:type ifc_class: str,optional
|
||||
:param name: The name of the resource
|
||||
:type name: str,optional
|
||||
:param predefined_type: Consult the IFC documentation for the valid
|
||||
predefined types for each type of resource class.
|
||||
:type predefined_type: str,optional
|
||||
:return: The newly created resource depending on the nominated IFC
|
||||
class.
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -76,25 +71,17 @@ def add_resource(
|
||||
# Add some labour to our crew.
|
||||
ifcopenshell.api.resource.add_resource(model, parent_resource=crew, ifc_class="IfcLaborResource")
|
||||
"""
|
||||
settings = {
|
||||
"parent_resource": parent_resource,
|
||||
"ifc_class": ifc_class,
|
||||
"name": name,
|
||||
"predefined_type": predefined_type,
|
||||
}
|
||||
|
||||
resource = ifcopenshell.api.root.create_entity(
|
||||
file,
|
||||
ifc_class=settings["ifc_class"],
|
||||
predefined_type=settings["predefined_type"],
|
||||
name=settings["name"] or "Unnamed",
|
||||
ifc_class=ifc_class,
|
||||
predefined_type=predefined_type,
|
||||
name=name or "Unnamed",
|
||||
)
|
||||
# TODO: this is an ambiguity by buildingSMART: Can we nest an IfcCrewResource under an IfcCrewResource ?
|
||||
# https://forums.buildingsmart.org/t/what-are-allowed-to-be-root-level-construction-resources/3550
|
||||
if settings["parent_resource"]:
|
||||
ifcopenshell.api.nest.assign_object(
|
||||
file, related_objects=[resource], relating_object=settings["parent_resource"]
|
||||
)
|
||||
if parent_resource:
|
||||
ifcopenshell.api.nest.assign_object(file, related_objects=[resource], relating_object=parent_resource)
|
||||
elif file.schema != "IFC2X3":
|
||||
context = file.by_type("IfcContext")[0]
|
||||
ifcopenshell.api.project.assign_declaration(file, definitions=[resource], relating_context=context)
|
||||
|
||||
@@ -42,12 +42,9 @@ def assign_resource(
|
||||
(e.g. if the resource is a labour resource).
|
||||
|
||||
:param relating_resource: The IfcResource to assign the object to.
|
||||
:type relating_resource: ifcopenshell.entity_instance
|
||||
:param related_object: The IfcProduct or IfcActor to assign to the
|
||||
object.
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: The newly created IfcRelAssignsToResource
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -82,26 +79,18 @@ def assign_resource(
|
||||
# This means that UCO is now our crane operator.
|
||||
ifcopenshell.api.resource.assign_resource(model, relating_resource=crane, related_object=actor)
|
||||
"""
|
||||
settings = {
|
||||
"relating_resource": relating_resource,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
if settings["related_object"].HasAssignments:
|
||||
for assignment in settings["related_object"].HasAssignments:
|
||||
if (
|
||||
assignment.is_a("IfclRelAssignsToResource")
|
||||
and assignment.RelatingResource == settings["relating_resource"]
|
||||
):
|
||||
if related_object.HasAssignments:
|
||||
for assignment in related_object.HasAssignments:
|
||||
if assignment.is_a("IfclRelAssignsToResource") and assignment.RelatingResource == relating_resource:
|
||||
return assignment
|
||||
|
||||
resource_of = None
|
||||
if settings["relating_resource"].ResourceOf:
|
||||
resource_of = settings["relating_resource"].ResourceOf[0]
|
||||
if relating_resource.ResourceOf:
|
||||
resource_of = relating_resource.ResourceOf[0]
|
||||
|
||||
if resource_of:
|
||||
related_objects = list(resource_of.RelatedObjects)
|
||||
related_objects.append(settings["related_object"])
|
||||
related_objects.append(related_object)
|
||||
resource_of.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": resource_of})
|
||||
else:
|
||||
@@ -110,8 +99,8 @@ def assign_resource(
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"RelatedObjects": [settings["related_object"]],
|
||||
"RelatingResource": settings["relating_resource"],
|
||||
"RelatedObjects": [related_object],
|
||||
"RelatingResource": relating_resource,
|
||||
}
|
||||
)
|
||||
return resource_of
|
||||
|
||||
@@ -25,15 +25,18 @@ import ifcopenshell.util.resource
|
||||
|
||||
|
||||
def calculate_resource_usage(file: ifcopenshell.file, resource: ifcopenshell.entity_instance) -> None:
|
||||
"""Calculates the number of resources required to perform scheduled work on a task."""
|
||||
settings = {"resource": resource}
|
||||
"""Calculates the number of resources required to perform scheduled work on a task.
|
||||
|
||||
if ifcopenshell.util.constraint.is_attribute_locked(settings["resource"], "Usage.ScheduleUsage"):
|
||||
:param resource: The IfcConstructionResource to calculate the usage for.
|
||||
:return: None
|
||||
"""
|
||||
|
||||
if ifcopenshell.util.constraint.is_attribute_locked(resource, "Usage.ScheduleUsage"):
|
||||
return
|
||||
if not settings["resource"].Usage or not settings["resource"].Usage.ScheduleWork:
|
||||
if not resource.Usage or not resource.Usage.ScheduleWork:
|
||||
return
|
||||
|
||||
task = ifcopenshell.util.resource.get_task_assignments(settings["resource"])
|
||||
task = ifcopenshell.util.resource.get_task_assignments(resource)
|
||||
if not task or not task.TaskTime:
|
||||
return
|
||||
|
||||
@@ -46,7 +49,7 @@ def calculate_resource_usage(file: ifcopenshell.file, resource: ifcopenshell.ent
|
||||
seconds = task_duration.days * hours_per_day * 60 * 60
|
||||
seconds += task_duration.seconds
|
||||
|
||||
person_hours = ifcopenshell.util.date.ifc2datetime(settings["resource"].Usage.ScheduleWork)
|
||||
person_hours = ifcopenshell.util.date.ifc2datetime(resource.Usage.ScheduleWork)
|
||||
|
||||
required_resources = person_hours.total_seconds() / seconds
|
||||
settings["resource"].Usage.ScheduleUsage = float(required_resources)
|
||||
resource.Usage.ScheduleUsage = float(required_resources)
|
||||
|
||||
@@ -22,6 +22,9 @@ import ifcopenshell.util.element
|
||||
def remove_resource_quantity(file: ifcopenshell.file, resource: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes the base quantity of a resource
|
||||
|
||||
:param resource: The IfcConstructionResource to remove the quantity from.
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
@@ -41,9 +44,7 @@ def remove_resource_quantity(file: ifcopenshell.file, resource: ifcopenshell.ent
|
||||
# let's clean up our mess and remove the quantity.
|
||||
ifcopenshell.api.resource.remove_resource_quantity(model, resource=labour)
|
||||
"""
|
||||
settings = {"resource": resource}
|
||||
|
||||
old_quantity = settings["resource"].BaseQuantity
|
||||
settings["resource"].BaseQuantity = None
|
||||
old_quantity = resource.BaseQuantity
|
||||
resource.BaseQuantity = None
|
||||
if old_quantity:
|
||||
ifcopenshell.util.element.remove_deep(file, old_quantity)
|
||||
|
||||
@@ -29,12 +29,9 @@ def unassign_resource(
|
||||
"""Removes the relationship between a resource and object
|
||||
|
||||
:param relating_resource: The IfcResource to assign the object to.
|
||||
:type relating_resource: ifcopenshell.entity_instance
|
||||
:param related_object: The IfcProduct or IfcActor to assign to the
|
||||
object.
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -60,13 +57,8 @@ def unassign_resource(
|
||||
ifcopenshell.api.resource.unassign_resource(model,
|
||||
relating_resource=crane, related_object=product)
|
||||
"""
|
||||
settings = {
|
||||
"relating_resource": relating_resource,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
for rel in settings["related_object"].HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToResource") or rel.RelatingResource != settings["relating_resource"]:
|
||||
for rel in related_object.HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToResource") or rel.RelatingResource != relating_resource:
|
||||
continue
|
||||
if len(rel.RelatedObjects) == 1:
|
||||
history = rel.OwnerHistory
|
||||
@@ -75,6 +67,6 @@ def unassign_resource(
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
return
|
||||
related_objects = list(rel.RelatedObjects)
|
||||
related_objects.remove(settings["related_object"])
|
||||
related_objects.remove(related_object)
|
||||
rel.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": rel})
|
||||
|
||||
@@ -71,48 +71,44 @@ def create_entity(
|
||||
"""
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
usecase.settings = {
|
||||
"ifc_class": ifc_class,
|
||||
"predefined_type": predefined_type,
|
||||
"name": name,
|
||||
}
|
||||
return usecase.execute()
|
||||
return usecase.execute(ifc_class, predefined_type, name)
|
||||
|
||||
|
||||
class Usecase:
|
||||
file: ifcopenshell.file
|
||||
settings: dict[str, Any]
|
||||
|
||||
def execute(self):
|
||||
def execute(
|
||||
self, ifc_class: str, predefined_type: Optional[str] = None, name: Optional[str] = None
|
||||
) -> ifcopenshell.entity_instance:
|
||||
element = self.file.create_entity(
|
||||
self.settings["ifc_class"],
|
||||
ifc_class,
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(self.file),
|
||||
}
|
||||
)
|
||||
element.Name = self.settings["name"] or None
|
||||
if self.settings["predefined_type"]:
|
||||
element.Name = name or None
|
||||
if predefined_type:
|
||||
if hasattr(element, "PredefinedType"):
|
||||
try:
|
||||
element.PredefinedType = self.settings["predefined_type"]
|
||||
element.PredefinedType = predefined_type
|
||||
except:
|
||||
element.PredefinedType = "USERDEFINED"
|
||||
if hasattr(element, "ObjectType"):
|
||||
element.ObjectType = self.settings["predefined_type"]
|
||||
element.ObjectType = predefined_type
|
||||
elif hasattr(element, "ElementType"):
|
||||
element.ElementType = self.settings["predefined_type"]
|
||||
element.ElementType = predefined_type
|
||||
elif hasattr(element, "ProcessType"):
|
||||
element.ProcessType = self.settings["predefined_type"]
|
||||
element.ProcessType = predefined_type
|
||||
elif hasattr(element, "ObjectType"):
|
||||
element.ObjectType = self.settings["predefined_type"]
|
||||
element.ObjectType = predefined_type
|
||||
if self.file.schema == "IFC2X3":
|
||||
self.handle_2x3_defaults(element)
|
||||
else:
|
||||
self.handle_4_defaults(element)
|
||||
return element
|
||||
|
||||
def handle_2x3_defaults(self, element):
|
||||
def handle_2x3_defaults(self, element: ifcopenshell.entity_instance) -> None:
|
||||
if element.is_a("IfcElementType"):
|
||||
if hasattr(element, "PredefinedType") and not element.PredefinedType:
|
||||
element.PredefinedType = "NOTDEFINED"
|
||||
@@ -129,7 +125,7 @@ class Usecase:
|
||||
element.ParameterTakesPrecedence = False
|
||||
element.Sizeable = False
|
||||
|
||||
def handle_4_defaults(self, element):
|
||||
def handle_4_defaults(self, element: ifcopenshell.entity_instance) -> None:
|
||||
if element.is_a("IfcElementType"):
|
||||
if hasattr(element, "PredefinedType") and not element.PredefinedType:
|
||||
element.PredefinedType = "NOTDEFINED"
|
||||
|
||||
@@ -69,23 +69,16 @@ def add_task(
|
||||
:param work_schedule: The work schedule to group the task in, if the
|
||||
task is to be a top-level or root task. This is mutually exclusive
|
||||
with the parent_task parameter.
|
||||
:type work_schedule: ifcopenshell.entity_instance, optional
|
||||
:param parent_task: The parent task, if the task is to be a subtask or
|
||||
child task. This is mutually exclusive with the work_schedule
|
||||
parameter.
|
||||
:type parent_task: ifcopenshell.entity_instance, optioanl
|
||||
:param name: The name of the task.
|
||||
:type name: str,optional
|
||||
:param description: The description of the task.
|
||||
:type description: str,optional
|
||||
:param identification: The identification code of the task.
|
||||
:type identification: str,optional
|
||||
:param predefined_type: The predefined type of the task. Common ones
|
||||
include CONSTRUCTION, DEMOLITION, or MAINTENANCE. Consultant the
|
||||
IFC documentation for IfcTaskTypeEnum for more information.
|
||||
:type predefined_type: str
|
||||
:return: The newly created IfcTask
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -139,39 +132,28 @@ def add_task(
|
||||
ifcopenshell.api.sequence.add_task(model, parent_task=cleaning, identification="3",
|
||||
description="Setup the water pressure by tapping to a water supply and connecting to a ...")
|
||||
"""
|
||||
settings = {
|
||||
"work_schedule": work_schedule,
|
||||
"parent_task": parent_task,
|
||||
"name": name,
|
||||
"description": description,
|
||||
"identification": identification,
|
||||
"predefined_type": predefined_type,
|
||||
}
|
||||
|
||||
task = ifcopenshell.api.root.create_entity(
|
||||
file, ifc_class="IfcTask", name=settings["name"], predefined_type=settings["predefined_type"]
|
||||
)
|
||||
if settings["description"]:
|
||||
task.Description = settings["description"]
|
||||
if settings["identification"]:
|
||||
task.Identification = settings["identification"]
|
||||
task = ifcopenshell.api.root.create_entity(file, ifc_class="IfcTask", name=name, predefined_type=predefined_type)
|
||||
if description:
|
||||
task.Description = description
|
||||
if identification:
|
||||
task.Identification = identification
|
||||
task.IsMilestone = False
|
||||
if settings["work_schedule"]:
|
||||
if work_schedule:
|
||||
file.create_entity(
|
||||
"IfcRelAssignsToControl",
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"RelatedObjects": [task],
|
||||
"RelatingControl": settings["work_schedule"],
|
||||
"RelatingControl": work_schedule,
|
||||
}
|
||||
)
|
||||
elif settings["parent_task"]:
|
||||
elif parent_task:
|
||||
rel = ifcopenshell.api.nest.assign_object(
|
||||
file,
|
||||
related_objects=[task],
|
||||
relating_object=settings["parent_task"],
|
||||
relating_object=parent_task,
|
||||
)
|
||||
if file.schema != "IFC2X3" and settings["parent_task"].Identification:
|
||||
task.Identification = settings["parent_task"].Identification + "." + str(len(rel.RelatedObjects))
|
||||
if file.schema != "IFC2X3" and parent_task.Identification:
|
||||
task.Identification = parent_task.Identification + "." + str(len(rel.RelatedObjects))
|
||||
return task
|
||||
|
||||
@@ -44,17 +44,13 @@ def add_time_period(
|
||||
|
||||
:param recurrence_pattern: The IfcRecurrencePattern to add the time
|
||||
period to. See ifcopenshell.api.sequence.assign_recurrence_pattern.
|
||||
:type recurrence_pattern: ifcopenshell.entity_instance
|
||||
:param start_time: The start time of the time period, in a format
|
||||
compatible with IfcTime, such as an ISO format time string or a
|
||||
datetime.time object.
|
||||
:type start_time: str,datetime.time
|
||||
:param end_time: The end time of the time period, in a format
|
||||
compatible with IfcTime, such as an ISO format time string or a
|
||||
datetime.time object.
|
||||
:type end_time: str,datetime.time
|
||||
:return: The newly created IfcTimePeriod
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -81,18 +77,12 @@ def add_time_period(
|
||||
ifcopenshell.api.sequence.add_time_period(model,
|
||||
recurrence_pattern=pattern, start_time="13:00", end_time="17:00")
|
||||
"""
|
||||
settings = {
|
||||
"recurrence_pattern": recurrence_pattern,
|
||||
"start_time": start_time,
|
||||
"end_time": end_time,
|
||||
}
|
||||
|
||||
time_period = file.create_entity("IfcTimePeriod")
|
||||
time_period.StartTime = ifcopenshell.util.date.datetime2ifc(settings["start_time"], "IfcTime")
|
||||
time_period.EndTime = ifcopenshell.util.date.datetime2ifc(settings["end_time"], "IfcTime")
|
||||
time_periods = list(settings["recurrence_pattern"].TimePeriods or [])
|
||||
time_period.StartTime = ifcopenshell.util.date.datetime2ifc(start_time, "IfcTime")
|
||||
time_period.EndTime = ifcopenshell.util.date.datetime2ifc(end_time, "IfcTime")
|
||||
time_periods = list(recurrence_pattern.TimePeriods or [])
|
||||
time_periods.append(time_period)
|
||||
settings["recurrence_pattern"].TimePeriods = time_periods
|
||||
recurrence_pattern.TimePeriods = time_periods
|
||||
|
||||
ifcopenshell.util.sequence.is_working_day.cache_clear()
|
||||
ifcopenshell.util.sequence.is_calendar_applicable.cache_clear()
|
||||
|
||||
@@ -38,12 +38,10 @@ def add_work_calendar(
|
||||
|
||||
:param name: The name of the calendar. Typically something like
|
||||
"5 Day Working Week" or "24/7".
|
||||
:type name: str, optional
|
||||
:param predefined_type: The type of calendar, typically used to more
|
||||
specifically define shifts, such as FIRSTSHIFT, SECONDSHIFT, or
|
||||
THIRDSHIFT. Leave as NOTDEFINED for basic calendar usage.
|
||||
:return: The newly created IfcWorkCalendar
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -79,13 +77,11 @@ def add_work_calendar(
|
||||
# this calendar by default (though you can override them).
|
||||
ifcopenshell.api.control.assign_control(model, relating_control=calendar, related_object=task)
|
||||
"""
|
||||
settings = {"name": name, "predefined_type": predefined_type}
|
||||
|
||||
work_calendar = ifcopenshell.api.root.create_entity(
|
||||
file,
|
||||
ifc_class="IfcWorkCalendar",
|
||||
predefined_type=settings["predefined_type"],
|
||||
name=settings["name"],
|
||||
predefined_type=predefined_type,
|
||||
name=name,
|
||||
)
|
||||
context = file.by_type("IfcContext")[0]
|
||||
ifcopenshell.api.project.assign_declaration(
|
||||
|
||||
@@ -41,15 +41,11 @@ def add_work_plan(
|
||||
|
||||
:param name: The name of the work plan. Recommended to be "Maintenance"
|
||||
or "Construction" for the two main purposes.
|
||||
:type name: str, optional
|
||||
:param predefined_type: The type of work plan, used for baselining.
|
||||
Leave as "NOTDEFINED" if unsure.
|
||||
:type predefined_type: str
|
||||
:param start_time: The earliest start time when the schedules grouped
|
||||
within the work plan are relevant.
|
||||
:type start_time: str,datetime.time
|
||||
:return: The newly created IfcWorkPlan
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -62,23 +58,18 @@ def add_work_plan(
|
||||
schedule = ifcopenshell.api.sequence.add_work_schedule(model,
|
||||
name="Construction Schedule A", work_plan=work_plan)
|
||||
"""
|
||||
settings = {
|
||||
"name": name,
|
||||
"predefined_type": predefined_type,
|
||||
"start_time": start_time or datetime.now(),
|
||||
}
|
||||
|
||||
start_time = start_time or datetime.now()
|
||||
work_plan = ifcopenshell.api.root.create_entity(
|
||||
file,
|
||||
ifc_class="IfcWorkPlan",
|
||||
predefined_type=settings["predefined_type"],
|
||||
name=settings["name"],
|
||||
predefined_type=predefined_type,
|
||||
name=name,
|
||||
)
|
||||
work_plan.CreationDate = ifcopenshell.util.date.datetime2ifc(datetime.now(), "IfcDateTime")
|
||||
user = ifcopenshell.api.owner.settings.get_user(file)
|
||||
if user:
|
||||
work_plan.Creators = [user.ThePerson]
|
||||
work_plan.StartTime = ifcopenshell.util.date.datetime2ifc(settings["start_time"], "IfcDateTime")
|
||||
work_plan.StartTime = ifcopenshell.util.date.datetime2ifc(start_time, "IfcDateTime")
|
||||
|
||||
context = file.by_type("IfcContext")[0]
|
||||
ifcopenshell.api.project.assign_declaration(
|
||||
|
||||
@@ -77,19 +77,12 @@ def add_work_schedule(
|
||||
construction = ifcopenshell.api.sequence.add_task(model,
|
||||
work_schedule=schedule, name="Construction", identification="C")
|
||||
"""
|
||||
settings = {
|
||||
"name": name,
|
||||
"predefined_type": predefined_type,
|
||||
"object_type": object_type,
|
||||
"start_time": start_time or datetime.now(),
|
||||
"work_plan": work_plan,
|
||||
}
|
||||
|
||||
start_time = start_time or datetime.now()
|
||||
work_schedule = ifcopenshell.api.root.create_entity(
|
||||
file,
|
||||
ifc_class="IfcWorkSchedule",
|
||||
predefined_type=settings["predefined_type"],
|
||||
name=settings["name"],
|
||||
predefined_type=predefined_type,
|
||||
name=name,
|
||||
)
|
||||
if file.schema == "IFC2X3":
|
||||
work_schedule.CreationDate = createIfcDateAndTime(file, datetime.now())
|
||||
@@ -99,17 +92,17 @@ def add_work_schedule(
|
||||
if user:
|
||||
work_schedule.Creators = [user.ThePerson]
|
||||
if file.schema == "IFC2X3":
|
||||
work_schedule.StartTime = createIfcDateAndTime(file, settings["start_time"])
|
||||
work_schedule.StartTime = createIfcDateAndTime(file, start_time)
|
||||
else:
|
||||
work_schedule.StartTime = ifcopenshell.util.date.datetime2ifc(settings["start_time"], "IfcDateTime")
|
||||
if settings["object_type"]:
|
||||
work_schedule.ObjectType = settings["object_type"]
|
||||
if settings["work_plan"]:
|
||||
work_schedule.StartTime = ifcopenshell.util.date.datetime2ifc(start_time, "IfcDateTime")
|
||||
if object_type:
|
||||
work_schedule.ObjectType = object_type
|
||||
if work_plan:
|
||||
ifcopenshell.api.aggregate.assign_object(
|
||||
file,
|
||||
**{
|
||||
"products": [work_schedule],
|
||||
"relating_object": settings["work_plan"],
|
||||
"relating_object": work_plan,
|
||||
}
|
||||
)
|
||||
elif file.schema != "IFC2X3":
|
||||
|
||||
@@ -36,12 +36,9 @@ def add_work_time(
|
||||
|
||||
:param work_calendar: The IfcWorkCalendar to add the work or holiday
|
||||
time definition to.
|
||||
:type work_calendar: ifcopenshell.entity_instance
|
||||
:param time_type: Either WorkingTimes or ExceptionTimes, depending on
|
||||
what you want to define.
|
||||
:type time_type: str
|
||||
:return: The newly created IfcWorkTime
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -74,15 +71,13 @@ def add_work_time(
|
||||
ifcopenshell.api.sequence.edit_recurrence_pattern(model,
|
||||
recurrence_pattern=pattern, attributes={"DayComponent": [1], "MonthComponent": [1]})
|
||||
"""
|
||||
settings = {"work_calendar": work_calendar, "time_type": time_type}
|
||||
|
||||
work_time = file.create_entity("IfcWorkTime")
|
||||
if settings["time_type"] == "WorkingTimes":
|
||||
working_times = list(settings["work_calendar"].WorkingTimes or [])
|
||||
if time_type == "WorkingTimes":
|
||||
working_times = list(work_calendar.WorkingTimes or [])
|
||||
working_times.append(work_time)
|
||||
settings["work_calendar"].WorkingTimes = working_times
|
||||
elif settings["time_type"] == "ExceptionTimes":
|
||||
exception_times = list(settings["work_calendar"].ExceptionTimes or [])
|
||||
work_calendar.WorkingTimes = working_times
|
||||
elif time_type == "ExceptionTimes":
|
||||
exception_times = list(work_calendar.ExceptionTimes or [])
|
||||
exception_times.append(work_time)
|
||||
settings["work_calendar"].ExceptionTimes = exception_times
|
||||
work_calendar.ExceptionTimes = exception_times
|
||||
return work_time
|
||||
|
||||
@@ -65,12 +65,9 @@ def assign_process(
|
||||
|
||||
:param relating_process: The IfcProcess (typically IfcTask) that the
|
||||
input, control, or resource is related to.
|
||||
:type relating_process: ifcopenshell.entity_instance
|
||||
:param related_object: The IfcProduct (for input), IfcCostItem (for
|
||||
control) or IfcConstructionResource (for resource).
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: The newly created IfcRelAssignsToProcess relationship
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -91,23 +88,18 @@ def assign_process(
|
||||
# Let's demolish that wall!
|
||||
ifcopenshell.api.sequence.assign_process(model, relating_process=task, related_object=wall)
|
||||
"""
|
||||
settings = {
|
||||
"relating_process": relating_process,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
if settings["related_object"].HasAssignments:
|
||||
for assignment in settings["related_object"].HasAssignments:
|
||||
if assignment.is_a("IfcRelAssignsToProcess") and assignment.RelatingProcess == settings["relating_process"]:
|
||||
if related_object.HasAssignments:
|
||||
for assignment in related_object.HasAssignments:
|
||||
if assignment.is_a("IfcRelAssignsToProcess") and assignment.RelatingProcess == relating_process:
|
||||
return
|
||||
|
||||
operates_on = None
|
||||
if settings["relating_process"].OperatesOn:
|
||||
operates_on = settings["relating_process"].OperatesOn[0]
|
||||
if relating_process.OperatesOn:
|
||||
operates_on = relating_process.OperatesOn[0]
|
||||
|
||||
if operates_on:
|
||||
related_objects = list(operates_on.RelatedObjects)
|
||||
related_objects.append(settings["related_object"])
|
||||
related_objects.append(related_object)
|
||||
operates_on.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": operates_on})
|
||||
else:
|
||||
@@ -116,8 +108,8 @@ def assign_process(
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"RelatedObjects": [settings["related_object"]],
|
||||
"RelatingProcess": settings["relating_process"],
|
||||
"RelatedObjects": [related_object],
|
||||
"RelatingProcess": relating_process,
|
||||
}
|
||||
)
|
||||
return operates_on
|
||||
|
||||
@@ -41,12 +41,9 @@ def assign_product(
|
||||
|
||||
:param relating_product: The IfcProduct that was constructed as a result
|
||||
of the task.
|
||||
:type relating_product: ifcopenshell.entity_instance
|
||||
:param related_object: The IfcProcess (typically IfcTask) of the
|
||||
construction task.
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: The newly created IfcRelAssignsToProduct relationship
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -67,23 +64,18 @@ def assign_product(
|
||||
# Let's construct that wall!
|
||||
ifcopenshell.api.sequence.assign_product(model, relating_product=wall, related_object=task)
|
||||
"""
|
||||
settings = {
|
||||
"relating_product": relating_product,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
if settings["related_object"].HasAssignments:
|
||||
for assignment in settings["related_object"].HasAssignments:
|
||||
if assignment.is_a("IfcRelAssignsToProduct") and assignment.RelatingProduct == settings["relating_product"]:
|
||||
if related_object.HasAssignments:
|
||||
for assignment in related_object.HasAssignments:
|
||||
if assignment.is_a("IfcRelAssignsToProduct") and assignment.RelatingProduct == relating_product:
|
||||
return assignment
|
||||
|
||||
referenced_by = None
|
||||
if settings["relating_product"].ReferencedBy:
|
||||
referenced_by = settings["relating_product"].ReferencedBy[0]
|
||||
if relating_product.ReferencedBy:
|
||||
referenced_by = relating_product.ReferencedBy[0]
|
||||
|
||||
if referenced_by:
|
||||
related_objects = list(referenced_by.RelatedObjects)
|
||||
related_objects.append(settings["related_object"])
|
||||
related_objects.append(related_object)
|
||||
referenced_by.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": referenced_by})
|
||||
else:
|
||||
@@ -92,8 +84,8 @@ def assign_product(
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"RelatedObjects": [settings["related_object"]],
|
||||
"RelatingProduct": settings["relating_product"],
|
||||
"RelatedObjects": [related_object],
|
||||
"RelatingProduct": relating_product,
|
||||
}
|
||||
)
|
||||
return referenced_by
|
||||
|
||||
@@ -19,11 +19,12 @@
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.project
|
||||
import ifcopenshell.api.aggregate
|
||||
from typing import Union
|
||||
|
||||
|
||||
def assign_work_plan(
|
||||
file: ifcopenshell.file, work_schedule: ifcopenshell.entity_instance, work_plan: ifcopenshell.entity_instance
|
||||
) -> ifcopenshell.entity_instance:
|
||||
) -> Union[ifcopenshell.entity_instance, None]:
|
||||
"""Assigns a work schedule to a work plan
|
||||
|
||||
Typically, work schedules would be assigned to a work plan at creation.
|
||||
@@ -31,11 +32,8 @@ def assign_work_plan(
|
||||
|
||||
:param work_schedule: The IfcWorkSchedule that will be assigned to the
|
||||
work plan.
|
||||
:type work_schedule: ifcopenshell.entity_instance
|
||||
:param work_plan: The IfcWorkPlan for the schedule to be assigned to.
|
||||
:type work_plan: ifcopenshell.entity_instance
|
||||
:return: The IfcRelAggregates relationship
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -50,20 +48,16 @@ def assign_work_plan(
|
||||
# ... you can assign the work plan afterwards.
|
||||
ifcopenshell.api.sequence.assign_work_plan(work_schedule=schedule, work_plan=work_plan)
|
||||
"""
|
||||
settings = {"work_schedule": work_schedule, "work_plan": work_plan}
|
||||
|
||||
# TODO: this is an ambiguity by buildingSMART
|
||||
# See https://forums.buildingsmart.org/t/is-the-ifcworkschedule-project-declaration-mutually-exclusive-to-aggregation-within-a-relating-ifcworkplan/3510
|
||||
ifcopenshell.api.project.unassign_declaration(
|
||||
file,
|
||||
definitions=[settings["work_schedule"]],
|
||||
definitions=[work_schedule],
|
||||
relating_context=file.by_type("IfcContext")[0],
|
||||
)
|
||||
rel_aggregates = ifcopenshell.api.aggregate.assign_object(
|
||||
file,
|
||||
**{
|
||||
"products": [settings["work_schedule"]],
|
||||
"relating_object": settings["work_plan"],
|
||||
}
|
||||
products=[work_schedule],
|
||||
relating_object=work_plan,
|
||||
)
|
||||
return rel_aggregates
|
||||
|
||||
@@ -21,6 +21,7 @@ import ifcopenshell.guid
|
||||
import ifcopenshell.api.nest
|
||||
import ifcopenshell.api.owner
|
||||
import ifcopenshell.api.sequence
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.sequence
|
||||
from typing import Union, Any
|
||||
@@ -155,7 +156,9 @@ class Usecase:
|
||||
duration_type=inverse.TimeLag.DurationType,
|
||||
)
|
||||
|
||||
def create_object_reference(self, relating_object, related_object):
|
||||
def create_object_reference(
|
||||
self, relating_object: ifcopenshell.entity_instance, related_object: ifcopenshell.entity_instance
|
||||
) -> ifcopenshell.entity_instance:
|
||||
referenced_by = None
|
||||
if relating_object.Declares:
|
||||
referenced_by = relating_object.Declares[0]
|
||||
|
||||
@@ -31,9 +31,7 @@ def remove_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance) ->
|
||||
sequences or controls are also removed.
|
||||
|
||||
:param task: The IfcTask to remove.
|
||||
:type task: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -56,76 +54,74 @@ def remove_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance) ->
|
||||
# just fix it on site.
|
||||
ifcopenshell.api.sequence.remove_task(model, task=design)
|
||||
"""
|
||||
settings = {"task": task}
|
||||
|
||||
# TODO: do a deep purge
|
||||
ifcopenshell.api.project.unassign_declaration(
|
||||
file,
|
||||
definitions=[settings["task"]],
|
||||
definitions=[task],
|
||||
relating_context=file.by_type("IfcContext")[0],
|
||||
)
|
||||
if task_time := settings["task"].TaskTime:
|
||||
if task_time := task.TaskTime:
|
||||
if task_time.is_a("IfcTaskTimeRecurring"):
|
||||
ifcopenshell.api.sequence.unassign_recurrence_pattern(file, task_time.Recurrence)
|
||||
file.remove(task_time)
|
||||
|
||||
# Handle IfcRelNests.
|
||||
if rels := settings["task"].IsNestedBy:
|
||||
if rels := task.IsNestedBy:
|
||||
subtasks = rels[0].RelatedObjects
|
||||
# Use batching for optimization.
|
||||
ifcopenshell.api.nest.unassign_object(file, subtasks)
|
||||
for task_ in subtasks:
|
||||
ifcopenshell.api.sequence.remove_task(file, task=task_)
|
||||
if settings["task"].Nests:
|
||||
ifcopenshell.api.nest.unassign_object(file, [settings["task"]])
|
||||
if task.Nests:
|
||||
ifcopenshell.api.nest.unassign_object(file, [task])
|
||||
|
||||
for inverse in file.get_inverse(settings["task"]):
|
||||
for inverse in file.get_inverse(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("IfcRelAssignsToControl"):
|
||||
if inverse.RelatingControl == settings["task"] or len(inverse.RelatedObjects) == 1:
|
||||
if inverse.RelatingControl == task or len(inverse.RelatedObjects) == 1:
|
||||
history = inverse.OwnerHistory
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
else:
|
||||
related_objects = list(inverse.RelatedObjects)
|
||||
related_objects.remove(settings["task"])
|
||||
related_objects.remove(task)
|
||||
inverse.RelatedObjects = related_objects
|
||||
elif inverse.is_a("IfcRelDefinesByProperties"):
|
||||
ifcopenshell.api.pset.remove_pset(
|
||||
file,
|
||||
product=settings["task"],
|
||||
product=task,
|
||||
pset=inverse.RelatingPropertyDefinition,
|
||||
)
|
||||
elif inverse.is_a("IfcRelAssignsToProcess"):
|
||||
if inverse.RelatingProcess == settings["task"] or len(inverse.RelatedObjects) == 1:
|
||||
if inverse.RelatingProcess == task or len(inverse.RelatedObjects) == 1:
|
||||
history = inverse.OwnerHistory
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
elif inverse.is_a("IfcRelAssignsToProduct"):
|
||||
if inverse.RelatingProduct == settings["task"] or len(inverse.RelatedObjects) == 1:
|
||||
if inverse.RelatingProduct == task or len(inverse.RelatedObjects) == 1:
|
||||
history = inverse.OwnerHistory
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
else:
|
||||
related_objects = list(inverse.RelatedObjects)
|
||||
related_objects.remove(settings["task"])
|
||||
related_objects.remove(task)
|
||||
inverse.RelatedObjects = related_objects
|
||||
elif inverse.is_a("IfcRelAssignsToObject"):
|
||||
if inverse.RelatingObject == settings["task"] or len(inverse.RelatedObjects) == 1:
|
||||
if inverse.RelatingObject == task or len(inverse.RelatedObjects) == 1:
|
||||
history = inverse.OwnerHistory
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
else:
|
||||
related_objects = list(inverse.RelatedObjects)
|
||||
related_objects.remove(settings["task"])
|
||||
related_objects.remove(task)
|
||||
inverse.RelatedObjects = related_objects
|
||||
elif inverse.is_a("IfcRelAssignsToProcess"):
|
||||
history = inverse.OwnerHistory
|
||||
@@ -133,7 +129,7 @@ def remove_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance) ->
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
history = settings["task"].OwnerHistory
|
||||
file.remove(settings["task"])
|
||||
history = task.OwnerHistory
|
||||
file.remove(task)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -23,9 +23,7 @@ def remove_time_period(file: ifcopenshell.file, time_period: ifcopenshell.entity
|
||||
"""Removes a time period
|
||||
|
||||
:param time_period: The IfcTimePeriod to remove.
|
||||
:type time_period: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -55,6 +53,4 @@ def remove_time_period(file: ifcopenshell.file, time_period: ifcopenshell.entity
|
||||
# Let's take the afternoon off!
|
||||
ifcopenshell.api.sequence.remove_time_period(model, time_period=afternoon)
|
||||
"""
|
||||
settings = {"time_period": time_period}
|
||||
|
||||
file.remove(settings["time_period"])
|
||||
file.remove(time_period)
|
||||
|
||||
@@ -30,9 +30,7 @@ def remove_work_calendar(file: ifcopenshell.file, work_calendar: ifcopenshell.en
|
||||
calendar.
|
||||
|
||||
:param work_calendar: The IfcWorkCalendar to remove
|
||||
:type work_calendar: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -44,32 +42,30 @@ def remove_work_calendar(file: ifcopenshell.file, work_calendar: ifcopenshell.en
|
||||
# And remove it immediately
|
||||
ifcopenshell.api.sequence.remove_work_calendar(model, work_calendar=calendar)
|
||||
"""
|
||||
settings = {"work_calendar": work_calendar}
|
||||
|
||||
# TODO: do a deep purge
|
||||
ifcopenshell.api.project.unassign_declaration(
|
||||
file,
|
||||
definitions=[settings["work_calendar"]],
|
||||
definitions=[work_calendar],
|
||||
relating_context=file.by_type("IfcContext")[0],
|
||||
)
|
||||
if settings["work_calendar"].Controls:
|
||||
for rel in settings["work_calendar"].Controls:
|
||||
if work_calendar.Controls:
|
||||
for rel in work_calendar.Controls:
|
||||
for related_object in rel.RelatedObjects:
|
||||
ifcopenshell.api.control.unassign_control(
|
||||
file,
|
||||
relating_control=settings["work_calendar"],
|
||||
relating_control=work_calendar,
|
||||
related_object=related_object,
|
||||
)
|
||||
|
||||
# Currently in API work times are created already attached
|
||||
# to the work calendar, so they are never reused.
|
||||
for working_time in settings["work_calendar"].WorkingTimes or []:
|
||||
for working_time in work_calendar.WorkingTimes or []:
|
||||
ifcopenshell.api.sequence.remove_work_time(file, work_time=working_time)
|
||||
|
||||
for exception_time in settings["work_calendar"].ExceptionTimes or []:
|
||||
for exception_time in work_calendar.ExceptionTimes or []:
|
||||
ifcopenshell.api.sequence.remove_work_time(file, work_time=exception_time)
|
||||
|
||||
history = settings["work_calendar"].OwnerHistory
|
||||
file.remove(settings["work_calendar"])
|
||||
history = work_calendar.OwnerHistory
|
||||
file.remove(work_calendar)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -29,9 +29,7 @@ def remove_work_plan(file: ifcopenshell.file, work_plan: ifcopenshell.entity_ins
|
||||
removed.
|
||||
|
||||
:param work_plan: The IfcWorkPlan to remove.
|
||||
:type work_plan: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -43,11 +41,9 @@ def remove_work_plan(file: ifcopenshell.file, work_plan: ifcopenshell.entity_ins
|
||||
# And remove it immediately
|
||||
ifcopenshell.api.sequence.remove_work_plan(model, work_plan=work_plan)
|
||||
"""
|
||||
settings = {"work_plan": work_plan}
|
||||
|
||||
ifcopenshell.api.project.unassign_declaration(
|
||||
file,
|
||||
definitions=[settings["work_plan"]],
|
||||
definitions=[work_plan],
|
||||
relating_context=file.by_type("IfcContext")[0],
|
||||
)
|
||||
|
||||
@@ -55,7 +51,7 @@ def remove_work_plan(file: ifcopenshell.file, work_plan: ifcopenshell.entity_ins
|
||||
if related_objects:
|
||||
ifcopenshell.api.aggregate.unassign_object(file, related_objects)
|
||||
|
||||
history = settings["work_plan"].OwnerHistory
|
||||
file.remove(settings["work_plan"])
|
||||
history = work_plan.OwnerHistory
|
||||
file.remove(work_plan)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -47,32 +47,30 @@ def remove_work_schedule(file: ifcopenshell.file, work_schedule: ifcopenshell.en
|
||||
# And remove it immediately
|
||||
ifcopenshell.api.sequence.remove_work_schedule(model, work_schedule=schedule)
|
||||
"""
|
||||
settings = {"work_schedule": work_schedule}
|
||||
|
||||
# TODO: do a deep purge
|
||||
ifcopenshell.api.project.unassign_declaration(
|
||||
file, definitions=[settings["work_schedule"]], relating_context=file.by_type("IfcContext")[0]
|
||||
file, definitions=[work_schedule], relating_context=file.by_type("IfcContext")[0]
|
||||
)
|
||||
|
||||
if settings["work_schedule"].Declares:
|
||||
for rel in settings["work_schedule"].Declares:
|
||||
for work_schedule in rel.RelatedObjects:
|
||||
ifcopenshell.api.sequence.remove_work_schedule(file, work_schedule=work_schedule)
|
||||
if work_schedule.Declares:
|
||||
for rel in work_schedule.Declares:
|
||||
for work_schedule_ in rel.RelatedObjects:
|
||||
ifcopenshell.api.sequence.remove_work_schedule(file, work_schedule=work_schedule_)
|
||||
|
||||
# Unassign from work plans.
|
||||
if settings["work_schedule"].Decomposes:
|
||||
ifcopenshell.api.aggregate.unassign_object(file, [settings["work_schedule"]])
|
||||
if work_schedule.Decomposes:
|
||||
ifcopenshell.api.aggregate.unassign_object(file, [work_schedule])
|
||||
|
||||
for inverse in file.get_inverse(settings["work_schedule"]):
|
||||
for inverse in file.get_inverse(work_schedule):
|
||||
if inverse.is_a("IfcRelDefinesByObject"):
|
||||
if inverse.RelatingObject == settings["work_schedule"] or len(inverse.RelatedObjects) == 1:
|
||||
if inverse.RelatingObject == work_schedule or len(inverse.RelatedObjects) == 1:
|
||||
history = inverse.OwnerHistory
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
else:
|
||||
related_objects = list(inverse.RelatedObjects)
|
||||
related_objects.remove(settings["work_schedule"])
|
||||
related_objects.remove(work_schedule)
|
||||
inverse.RelatedObjects = related_objects
|
||||
elif inverse.is_a("IfcRelAssignsToControl"):
|
||||
[
|
||||
@@ -81,7 +79,7 @@ def remove_work_schedule(file: ifcopenshell.file, work_schedule: ifcopenshell.en
|
||||
if related_object.is_a("IfcTask")
|
||||
]
|
||||
|
||||
history = settings["work_schedule"].OwnerHistory
|
||||
file.remove(settings["work_schedule"])
|
||||
history = work_schedule.OwnerHistory
|
||||
file.remove(work_schedule)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -31,11 +31,8 @@ def unassign_process(
|
||||
See ifcopenshell.api.sequence.assign_process for details.
|
||||
|
||||
:param relating_process: The IfcTask in the relationship.
|
||||
:type relating_process: ifcopenshell.entity_instance
|
||||
:param related_object: The related object.
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -59,13 +56,8 @@ def unassign_process(
|
||||
# Change our mind.
|
||||
ifcopenshell.api.sequence.unassign_process(model, relating_process=task, related_object=wall)
|
||||
"""
|
||||
settings = {
|
||||
"relating_process": relating_process,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
for rel in settings["related_object"].HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToProcess") or rel.RelatingProcess != settings["relating_process"]:
|
||||
for rel in related_object.HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToProcess") or rel.RelatingProcess != relating_process:
|
||||
continue
|
||||
if len(rel.RelatedObjects) == 1:
|
||||
history = rel.OwnerHistory
|
||||
@@ -74,7 +66,7 @@ def unassign_process(
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
return
|
||||
related_objects = list(rel.RelatedObjects)
|
||||
related_objects.remove(settings["related_object"])
|
||||
related_objects.remove(related_object)
|
||||
rel.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, element=rel)
|
||||
return rel
|
||||
|
||||
@@ -31,11 +31,8 @@ def unassign_product(
|
||||
See ifcopenshell.api.sequence.assign_product for details.
|
||||
|
||||
:param relating_product: The IfcProduct in the relationship.
|
||||
:type relating_product: ifcopenshell.entity_instance
|
||||
:param related_object: The IfcTask in the relationship.
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -59,13 +56,8 @@ def unassign_product(
|
||||
# Change our mind.
|
||||
ifcopenshell.api.sequence.unassign_product(relating_product=wall, related_object=task)
|
||||
"""
|
||||
settings = {
|
||||
"relating_product": relating_product,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
for rel in settings["related_object"].HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToProduct") or rel.RelatingProduct != settings["relating_product"]:
|
||||
for rel in related_object.HasAssignments or []:
|
||||
if not rel.is_a("IfcRelAssignsToProduct") or rel.RelatingProduct != relating_product:
|
||||
continue
|
||||
if len(rel.RelatedObjects) == 1:
|
||||
history = rel.OwnerHistory
|
||||
@@ -74,7 +66,7 @@ def unassign_product(
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
return
|
||||
related_objects = list(rel.RelatedObjects)
|
||||
related_objects.remove(settings["related_object"])
|
||||
related_objects.remove(related_object)
|
||||
rel.RelatedObjects = related_objects
|
||||
ifcopenshell.api.owner.update_owner_history(file, element=rel)
|
||||
return rel
|
||||
|
||||
@@ -28,9 +28,7 @@ def unassign_recurrence_pattern(file: ifcopenshell.file, recurrence_pattern: ifc
|
||||
or replace IfcTaskTimeRecurring with IfcTaskTime).
|
||||
|
||||
:param recurrence_pattern: The IfcRecurrencePattern to remove.
|
||||
:type recurrence_pattern: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -50,8 +48,6 @@ def unassign_recurrence_pattern(file: ifcopenshell.file, recurrence_pattern: ifc
|
||||
# Change our mind, let's just maintain it whenever we feel like it.
|
||||
ifcopenshell.api.sequence.unassign_recurrence_pattern(recurrence_pattern=pattern)
|
||||
"""
|
||||
settings = {"recurrence_pattern": recurrence_pattern}
|
||||
|
||||
for time_period in settings["recurrence_pattern"].TimePeriods or []:
|
||||
for time_period in recurrence_pattern.TimePeriods or []:
|
||||
file.remove(time_period)
|
||||
file.remove(settings["recurrence_pattern"])
|
||||
file.remove(recurrence_pattern)
|
||||
|
||||
@@ -29,11 +29,8 @@ def unassign_sequence(
|
||||
"""Removes a sequence relationship between tasks
|
||||
|
||||
:param relating_process: The previous / predecessor task.
|
||||
:type relating_process: ifcopenshell.entity_instance
|
||||
:param related_process: The next / successor task.
|
||||
:type related_process: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -60,15 +57,10 @@ def unassign_sequence(
|
||||
ifcopenshell.api.sequence.unassign_sequence(model,
|
||||
relating_process=zone1, related_process=zone2)
|
||||
"""
|
||||
settings = {
|
||||
"relating_process": relating_process,
|
||||
"related_process": related_process,
|
||||
}
|
||||
|
||||
for rel in settings["related_process"].IsSuccessorFrom or []:
|
||||
if rel.RelatingProcess == settings["relating_process"]:
|
||||
for rel in related_process.IsSuccessorFrom or []:
|
||||
if rel.RelatingProcess == relating_process:
|
||||
history = rel.OwnerHistory
|
||||
file.remove(rel)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
ifcopenshell.api.sequence.cascade_schedule(file, task=settings["related_process"])
|
||||
ifcopenshell.api.sequence.cascade_schedule(file, task=related_process)
|
||||
|
||||
@@ -69,13 +69,11 @@ def assign_container(
|
||||
previous aggregation, containment, or nesting relationships it may have.
|
||||
|
||||
:param products: A list of physical IfcElements existing in the space.
|
||||
:type products: list[ifcopenshell.entity_instance]
|
||||
:param relating_structure: The IfcSpatialStructureElement element, such
|
||||
as IfcBuilding, IfcBuildingStorey, or IfcSpace that the element
|
||||
exists in.
|
||||
:return: The IfcRelContainedInSpatialStructure relationship instance
|
||||
or `None` if `products` was empty list.
|
||||
:rtype: Union[ifcopenshell.entity_instance, None]
|
||||
|
||||
Example:
|
||||
|
||||
@@ -103,16 +101,10 @@ def assign_container(
|
||||
ifcopenshell.api.spatial.assign_container(model, products=[wall], relating_structure=storey)
|
||||
ifcopenshell.api.spatial.assign_container(model, products=[furniture], relating_structure=space)
|
||||
"""
|
||||
settings = {
|
||||
"products": products,
|
||||
"relating_structure": relating_structure,
|
||||
}
|
||||
|
||||
if not settings["products"]:
|
||||
if not products:
|
||||
return
|
||||
|
||||
products = set(settings["products"])
|
||||
relating_structure = settings["relating_structure"]
|
||||
products_set = set(products)
|
||||
structure_rel = next(iter(relating_structure.ContainsElements), None)
|
||||
|
||||
previous_containers_rels: set[ifcopenshell.entity_instance] = set()
|
||||
@@ -120,7 +112,7 @@ def assign_container(
|
||||
products_with_containers: list[ifcopenshell.entity_instance] = []
|
||||
|
||||
# check if there is anything to change
|
||||
for product in products:
|
||||
for product in products_set:
|
||||
product_rel = next(iter(product.ContainedInStructure), None)
|
||||
|
||||
if product_rel is None:
|
||||
@@ -144,7 +136,7 @@ def assign_container(
|
||||
|
||||
# unassign elements from previous containers
|
||||
for rel in previous_containers_rels:
|
||||
related_elements = set(rel.RelatedElements) - products
|
||||
related_elements = set(rel.RelatedElements) - products_set
|
||||
if related_elements:
|
||||
rel.RelatedElements = list(related_elements)
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": rel})
|
||||
@@ -156,7 +148,7 @@ def assign_container(
|
||||
|
||||
# assign elements to a new container
|
||||
if structure_rel:
|
||||
structure_rel.RelatedElements = list(set(structure_rel.RelatedElements) | products)
|
||||
structure_rel.RelatedElements = list(set(structure_rel.RelatedElements) | products_set)
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": structure_rel})
|
||||
else:
|
||||
structure_rel = file.create_entity(
|
||||
@@ -164,8 +156,8 @@ def assign_container(
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"RelatedElements": list(products),
|
||||
"RelatingStructure": settings["relating_structure"],
|
||||
"RelatedElements": list(products_set),
|
||||
"RelatingStructure": relating_structure,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -25,9 +25,7 @@ def unassign_container(file: ifcopenshell.file, products: list[ifcopenshell.enti
|
||||
"""Unassigns a container from products.
|
||||
|
||||
:param product: A list of IfcProducts to remove the containment from.
|
||||
:type product: list[ifcopenshell.entity_instance]
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -54,15 +52,11 @@ def unassign_container(file: ifcopenshell.file, products: list[ifcopenshell.enti
|
||||
# Not anymore!
|
||||
ifcopenshell.api.spatial.unassign_container(model, products=[wall])
|
||||
"""
|
||||
settings = {
|
||||
"products": products,
|
||||
}
|
||||
|
||||
products = set(settings["products"])
|
||||
rels = set(rel for product in products if (rel := next(iter(product.ContainedInStructure), None)))
|
||||
products_set = set(products)
|
||||
rels = set(rel for product in products_set if (rel := next(iter(product.ContainedInStructure), None)))
|
||||
|
||||
for rel in rels:
|
||||
related_elements = set(rel.RelatedElements) - products
|
||||
related_elements = set(rel.RelatedElements) - products_set
|
||||
if related_elements:
|
||||
rel.RelatedElements = list(related_elements)
|
||||
ifcopenshell.api.owner.update_owner_history(file, element=rel)
|
||||
|
||||
@@ -27,7 +27,7 @@ def add_structural_activity(
|
||||
ifc_class: str = "IfcStructuralPlanarAction",
|
||||
predefined_type: str = "CONST",
|
||||
global_or_local: Literal["GLOBAL_COORDS", "LOCAL_COORDS"] = "GLOBAL_COORDS",
|
||||
) -> None:
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new structural activity
|
||||
|
||||
A structural activity is either a structural action or a reaction. It
|
||||
@@ -38,42 +38,29 @@ def add_structural_activity(
|
||||
a structural member.
|
||||
|
||||
:param ifc_class: Choose from any subtype of IfcStructuralActivity.
|
||||
:type ifc_class: str
|
||||
:param predefined_type: View the IFC documentation for what valid
|
||||
predefined types may be chosen.
|
||||
:type predefined_type: str
|
||||
:param global_or_local: The location coordinates of the load is always
|
||||
defined locally relative to the structural member the activity is
|
||||
assigned to. However, the directions of the applied load may either
|
||||
be specified globally or locally depending on how this argument is
|
||||
set. Choose from GLOBAL_COORDS or LOCAL_COORDS.
|
||||
:type global_or_local: str
|
||||
:param applied_load: The IfcStructuralLoad that is applied in this
|
||||
activity.
|
||||
:type applied_load: ifcopenshell.entity_instance
|
||||
:param structural_member: The IfcStructuralMember that the load is
|
||||
applied to.
|
||||
:type structural_member: ifcopenshell.entity_instance
|
||||
:return: The newly created entity based on the ifc_class
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
"""
|
||||
settings = {
|
||||
"ifc_class": ifc_class,
|
||||
"predefined_type": predefined_type,
|
||||
"global_or_local": global_or_local,
|
||||
"applied_load": applied_load,
|
||||
"structural_member": structural_member,
|
||||
}
|
||||
|
||||
activity = ifcopenshell.api.root.create_entity(
|
||||
file,
|
||||
ifc_class=settings["ifc_class"],
|
||||
predefined_type=settings["predefined_type"],
|
||||
ifc_class=ifc_class,
|
||||
predefined_type=predefined_type,
|
||||
)
|
||||
activity.AppliedLoad = settings["applied_load"]
|
||||
activity.GlobalOrLocal = settings["global_or_local"]
|
||||
activity.AppliedLoad = applied_load
|
||||
activity.GlobalOrLocal = global_or_local
|
||||
|
||||
rel = ifcopenshell.api.root.create_entity(file, ifc_class="IfcRelConnectsStructuralActivity")
|
||||
rel.RelatingElement = settings["structural_member"]
|
||||
rel.RelatingElement = structural_member
|
||||
rel.RelatedStructuralActivity = activity
|
||||
return activity
|
||||
|
||||
+7
-13
@@ -32,18 +32,14 @@ def add_structural_boundary_condition(
|
||||
edge condition, and surface connections will have a face condition.
|
||||
|
||||
:param name: The name of the boundary condition.
|
||||
:type name: str,optional
|
||||
:param connection: The IfcStructuralConnection to apply the boundary
|
||||
condition to. This will determine the type of condition that is
|
||||
created. If no connection is supplied, an orphan boundary condition
|
||||
will be created using the ifc_class that you specify.
|
||||
:type connection: ifcopenshell.entity_instance,optional
|
||||
:param ifc_class: The class of IfcBoundaryCondition to create, only
|
||||
relevant if you do not specify a connection and want to create an
|
||||
orphaned boundary condition.
|
||||
:type ifc_class: str,optional
|
||||
:return: The newly created IfcBoundaryCondition
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -51,14 +47,12 @@ def add_structural_boundary_condition(
|
||||
|
||||
ifcopenshell.api.structural.add_structural_boundary_condition(model, connection=connection)
|
||||
"""
|
||||
settings = {"name": name, "connection": connection, "ifc_class": ifc_class}
|
||||
|
||||
if settings["connection"]:
|
||||
if connection:
|
||||
# assign boundary condition to a connection
|
||||
if settings["connection"].is_a("IfcRelConnectsStructuralMember"):
|
||||
related_connection = settings["connection"].RelatedStructuralConnection
|
||||
if connection.is_a("IfcRelConnectsStructuralMember"):
|
||||
related_connection = connection.RelatedStructuralConnection
|
||||
else:
|
||||
related_connection = settings["connection"]
|
||||
related_connection = connection
|
||||
|
||||
if related_connection.is_a("IfcStructuralPointConnection"):
|
||||
boundary_class = "IfcBoundaryNodeCondition"
|
||||
@@ -67,9 +61,9 @@ def add_structural_boundary_condition(
|
||||
elif related_connection.is_a("IfcStructuralSurfaceConnection"):
|
||||
boundary_class = "IfcBoundaryFaceCondition"
|
||||
|
||||
condition = file.create_entity(boundary_class, Name=settings["name"])
|
||||
settings["connection"].AppliedCondition = condition
|
||||
condition = file.create_entity(boundary_class, Name=name)
|
||||
connection.AppliedCondition = condition
|
||||
return condition
|
||||
else:
|
||||
# add an orphan boundary condition
|
||||
return file.create_entity(settings["ifc_class"], Name=settings["name"])
|
||||
return file.create_entity(ifc_class, Name=name)
|
||||
|
||||
+4
-11
@@ -29,22 +29,15 @@ def add_structural_member_connection(
|
||||
|
||||
:param relating_structural_member: The IfcStructuralMember to have a
|
||||
connection added to it.
|
||||
:type relating_structural_member: ifcopenshell.entity_instance
|
||||
:param related_structural_connection: The IfcStructuralConnection to add
|
||||
to the IfcStructuralMember.
|
||||
:type related_structural_connection: ifcopenshell.entity_instance
|
||||
:return: The IfcRelConnectsStructuralMember relationship
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
"""
|
||||
settings = {
|
||||
"relating_structural_member": relating_structural_member,
|
||||
"related_structural_connection": related_structural_connection,
|
||||
}
|
||||
|
||||
for connection in settings["related_structural_connection"].ConnectsStructuralMembers or []:
|
||||
if connection.RelatingStructuralMember == settings["relating_structural_member"]:
|
||||
for connection in related_structural_connection.ConnectsStructuralMembers or []:
|
||||
if connection.RelatingStructuralMember == relating_structural_member:
|
||||
return connection
|
||||
rel = ifcopenshell.api.root.create_entity(file, ifc_class="IfcRelConnectsStructuralMember")
|
||||
rel.RelatingStructuralMember = settings["relating_structural_member"]
|
||||
rel.RelatedStructuralConnection = settings["related_structural_connection"]
|
||||
rel.RelatingStructuralMember = relating_structural_member
|
||||
rel.RelatedStructuralConnection = related_structural_connection
|
||||
return rel
|
||||
|
||||
+4
-8
@@ -27,18 +27,14 @@ def remove_structural_connection_condition(file: ifcopenshell.file, relation: if
|
||||
The condition and the member itself is preserved.
|
||||
|
||||
:param relation: The IfcRelConnectsStructuralMember to remove.
|
||||
:type relation: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
"""
|
||||
settings = {"relation": relation}
|
||||
|
||||
if settings["relation"].AppliedCondition:
|
||||
if relation.AppliedCondition:
|
||||
ifcopenshell.api.structural.remove_structural_boundary_condition(
|
||||
file,
|
||||
connection=settings["relation"].RelatedStructuralConnection,
|
||||
connection=relation.RelatedStructuralConnection,
|
||||
)
|
||||
history = settings["relation"].OwnerHistory
|
||||
file.remove(settings["relation"])
|
||||
history = relation.OwnerHistory
|
||||
file.remove(relation)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -25,9 +25,7 @@ def remove_styled_representation(file: ifcopenshell.file, representation: ifcope
|
||||
removes the representation but not the underlying styles.
|
||||
|
||||
:param representation: The IfcStyledRepresentation to remove.
|
||||
:type representation: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -36,17 +34,15 @@ def remove_styled_representation(file: ifcopenshell.file, representation: ifcope
|
||||
# Remove a styled representation
|
||||
ifcopenshell.api.style.remove_styled_representation(model, representation=representation)
|
||||
"""
|
||||
settings = {"representation": representation}
|
||||
|
||||
for inverse in file.get_inverse(settings["representation"]):
|
||||
for inverse in file.get_inverse(representation):
|
||||
if inverse.is_a("IfcMaterialDefinitionRepresentation") and len(inverse.Representations) == 1:
|
||||
file.remove(inverse)
|
||||
|
||||
for item in settings["representation"].Items:
|
||||
for item in representation.Items:
|
||||
if item.is_a("IfcStyledItem") and file.get_total_inverses(item) == 1:
|
||||
for style in item.Styles:
|
||||
if style.is_a("IfcPresentationStyleAssignment"):
|
||||
file.remove(style)
|
||||
file.remove(item)
|
||||
|
||||
file.remove(settings["representation"])
|
||||
file.remove(representation)
|
||||
|
||||
@@ -22,7 +22,9 @@ import ifcopenshell.api.system
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def add_port(file: ifcopenshell.file, element: Optional[ifcopenshell.entity_instance] = None) -> None:
|
||||
def add_port(
|
||||
file: ifcopenshell.file, element: Optional[ifcopenshell.entity_instance] = None
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new distribution port to an element
|
||||
|
||||
A distribution port represents a connection point on an element, where
|
||||
@@ -36,9 +38,7 @@ def add_port(file: ifcopenshell.file, element: Optional[ifcopenshell.entity_inst
|
||||
|
||||
:param element: The IfcDistributionElement you want to add a
|
||||
distribution port to.
|
||||
:type element: ifcopenshell.entity_instance, optional
|
||||
:return: The newly created IfcDistributionPort
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -52,11 +52,7 @@ def add_port(file: ifcopenshell.file, element: Optional[ifcopenshell.entity_inst
|
||||
port1 = ifcopenshell.api.system.add_port(model, element=duct)
|
||||
port2 = ifcopenshell.api.system.add_port(model, element=duct)
|
||||
"""
|
||||
settings = {
|
||||
"element": element,
|
||||
}
|
||||
|
||||
port = ifcopenshell.api.root.create_entity(file, ifc_class="IfcDistributionPort")
|
||||
if settings["element"]:
|
||||
ifcopenshell.api.system.assign_port(file, element=settings["element"], port=port)
|
||||
if element:
|
||||
ifcopenshell.api.system.assign_port(file, element=element, port=port)
|
||||
return port
|
||||
|
||||
@@ -34,9 +34,7 @@ def add_system(file: ifcopenshell.file, ifc_class: str = "IfcDistributionSystem"
|
||||
security systems. Alternatively you may choose IfcBuildingSystem for
|
||||
specialised building facade systems or similar. For IFC2X3, choose
|
||||
IfcSystem.
|
||||
:type ifc_class: str
|
||||
:return: The newly created IfcSystem.
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -45,9 +43,7 @@ def add_system(file: ifcopenshell.file, ifc_class: str = "IfcDistributionSystem"
|
||||
# A completely empty distribution system
|
||||
system = ifcopenshell.api.system.add_system(model)
|
||||
"""
|
||||
settings = {"ifc_class": ifc_class}
|
||||
|
||||
ifc_class = settings["ifc_class"]
|
||||
ifc_class = ifc_class
|
||||
# workaround for failing default argument in ifc2x3
|
||||
if file.schema == "IFC2X3" and ifc_class == "IfcDistributionSystem":
|
||||
ifc_class = "IfcSystem"
|
||||
|
||||
@@ -34,12 +34,9 @@ def assign_flow_control(
|
||||
|
||||
:param related_flow_control: IfcDistributionControlElement
|
||||
which may be used to impart control on the flow element
|
||||
:type related_flow_control: ifcopenshell.entity_instance
|
||||
:param relating_flow_element: The IfcDistributionFlowElement that is being controlled / sensed
|
||||
:type relating_flow_element: ifcopenshell.entity_instance
|
||||
:return: Matching or newly created IfcRelFlowControlElements. If control
|
||||
is already assigned to some other element method will return None.
|
||||
:rtype: ifcopenshell.entity_instance, None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -51,26 +48,21 @@ def assign_flow_control(
|
||||
model, related_flow_control=flow_control, relating_flow_element=flow_element
|
||||
)
|
||||
"""
|
||||
settings = {
|
||||
"relating_flow_element": relating_flow_element,
|
||||
"related_flow_control": related_flow_control,
|
||||
}
|
||||
|
||||
if settings["related_flow_control"].AssignedToFlowElement:
|
||||
if related_flow_control.AssignedToFlowElement:
|
||||
# only 1 control per 1 flow element is possible
|
||||
assignment = settings["related_flow_control"].AssignedToFlowElement[0]
|
||||
if assignment.RelatingFlowElement == settings["relating_flow_element"]:
|
||||
assignment = related_flow_control.AssignedToFlowElement[0]
|
||||
if assignment.RelatingFlowElement == relating_flow_element:
|
||||
return assignment
|
||||
# return None if this control is already assigned to another flow element
|
||||
return
|
||||
|
||||
if settings["relating_flow_element"].HasControlElements:
|
||||
assignment = settings["relating_flow_element"].HasControlElements[0]
|
||||
if settings["related_flow_control"] in assignment.RelatedControlElements:
|
||||
if relating_flow_element.HasControlElements:
|
||||
assignment = relating_flow_element.HasControlElements[0]
|
||||
if related_flow_control in assignment.RelatedControlElements:
|
||||
return assignment
|
||||
|
||||
related_flow_controls = set(assignment.RelatedControlElements)
|
||||
related_flow_controls.add(settings["related_flow_control"])
|
||||
related_flow_controls.add(related_flow_control)
|
||||
assignment.RelatedControlElements = list(related_flow_controls)
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": assignment})
|
||||
return assignment
|
||||
@@ -80,8 +72,8 @@ def assign_flow_control(
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.owner.create_owner_history(file),
|
||||
"RelatedControlElements": [settings["related_flow_control"]],
|
||||
"RelatingFlowElement": settings["relating_flow_element"],
|
||||
"RelatedControlElements": [related_flow_control],
|
||||
"RelatingFlowElement": relating_flow_element,
|
||||
},
|
||||
)
|
||||
return assignment
|
||||
|
||||
@@ -34,12 +34,9 @@ def assign_port(
|
||||
it may be useful when patching up models.
|
||||
|
||||
:param element: The IfcDistributionElement to assign the port to.
|
||||
:type element: ifcopenshell.entity_instance
|
||||
:param port: The IfcDistributionPort you want to assign.
|
||||
:type port: ifcopenshell.entity_instance
|
||||
:return: The IfcRelNests relationship, or the
|
||||
IfcRelConnectsPortToElement for IFC2X3.
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -61,31 +58,30 @@ def assign_port(
|
||||
"""
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
usecase.settings = {
|
||||
"element": element,
|
||||
"port": port,
|
||||
}
|
||||
return usecase.execute()
|
||||
return usecase.execute(element, port)
|
||||
|
||||
|
||||
class Usecase:
|
||||
file: ifcopenshell.file
|
||||
settings: dict[str, Any]
|
||||
|
||||
def execute(self):
|
||||
def execute(
|
||||
self, element: ifcopenshell.entity_instance, port: ifcopenshell.entity_instance
|
||||
) -> ifcopenshell.entity_instance:
|
||||
self.element = element
|
||||
self.port = port
|
||||
if self.file.schema == "IFC2X3":
|
||||
return self.execute_ifc2x3()
|
||||
|
||||
rels = self.settings["element"].IsNestedBy or []
|
||||
rels = self.element.IsNestedBy or []
|
||||
|
||||
for rel in rels:
|
||||
if self.settings["port"] in rel.RelatedObjects:
|
||||
if self.port in rel.RelatedObjects:
|
||||
return rel
|
||||
|
||||
if rels:
|
||||
rel = rels[0]
|
||||
related_objects = set(rel.RelatedObjects) or set()
|
||||
related_objects.add(self.settings["port"])
|
||||
related_objects.add(self.port)
|
||||
rel.RelatedObjects = list(related_objects)
|
||||
ifcopenshell.api.owner.update_owner_history(self.file, **{"element": rel})
|
||||
else:
|
||||
@@ -93,34 +89,34 @@ class Usecase:
|
||||
"IfcRelNests",
|
||||
GlobalId=ifcopenshell.guid.new(),
|
||||
OwnerHistory=ifcopenshell.api.owner.create_owner_history(self.file),
|
||||
RelatedObjects=[self.settings["port"]],
|
||||
RelatingObject=self.settings["element"],
|
||||
RelatedObjects=[self.port],
|
||||
RelatingObject=self.element,
|
||||
)
|
||||
|
||||
self.update_port_placement()
|
||||
|
||||
return rel
|
||||
|
||||
def execute_ifc2x3(self):
|
||||
for rel in self.settings["element"].HasPorts or []:
|
||||
if rel.RelatingPort == self.settings["port"]:
|
||||
def execute_ifc2x3(self) -> ifcopenshell.entity_instance:
|
||||
for rel in self.element.HasPorts or []:
|
||||
if rel.RelatingPort == self.port:
|
||||
return rel
|
||||
rel = self.file.create_entity(
|
||||
"IfcRelConnectsPortToElement",
|
||||
GlobalId=ifcopenshell.guid.new(),
|
||||
OwnerHistory=ifcopenshell.api.owner.create_owner_history(self.file),
|
||||
RelatingPort=self.settings["port"],
|
||||
RelatedElement=self.settings["element"],
|
||||
RelatingPort=self.port,
|
||||
RelatedElement=self.element,
|
||||
)
|
||||
self.update_port_placement()
|
||||
return rel
|
||||
|
||||
def update_port_placement(self):
|
||||
placement = getattr(self.settings["port"], "ObjectPlacement", None)
|
||||
def update_port_placement(self) -> None:
|
||||
placement = getattr(self.port, "ObjectPlacement", None)
|
||||
if placement and placement.is_a("IfcLocalPlacement"):
|
||||
ifcopenshell.api.geometry.edit_object_placement(
|
||||
self.file,
|
||||
product=self.settings["port"],
|
||||
matrix=ifcopenshell.util.placement.get_local_placement(self.settings["port"].ObjectPlacement),
|
||||
product=self.port,
|
||||
matrix=ifcopenshell.util.placement.get_local_placement(self.port.ObjectPlacement),
|
||||
is_si=False,
|
||||
)
|
||||
|
||||
@@ -64,12 +64,8 @@ def disconnect_port(file: ifcopenshell.file, port: ifcopenshell.entity_instance)
|
||||
# fitting_port1 instead of duct_port2
|
||||
ifcopenshell.api.system.disconnect_port(model, port=duct_port2)
|
||||
"""
|
||||
settings = {
|
||||
"port": port,
|
||||
}
|
||||
|
||||
rels = settings["port"].ConnectedTo or ()
|
||||
rels += settings["port"].ConnectedFrom or ()
|
||||
rels = port.ConnectedTo or ()
|
||||
rels += port.ConnectedFrom or ()
|
||||
|
||||
for rel in rels:
|
||||
rel.RelatingPort.FlowDirection = None
|
||||
|
||||
@@ -27,9 +27,7 @@ def remove_system(file: ifcopenshell.file, system: ifcopenshell.entity_instance)
|
||||
All the distribution elements within the system are retained.
|
||||
|
||||
:param system: The IfcSystem to remove.
|
||||
:type system: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -41,9 +39,7 @@ def remove_system(file: ifcopenshell.file, system: ifcopenshell.entity_instance)
|
||||
# Delete it.
|
||||
ifcopenshell.api.system.remove_system(model, system=system)
|
||||
"""
|
||||
settings = {"system": system}
|
||||
|
||||
for inverse_id in [i.id() for i in file.get_inverse(settings["system"])]:
|
||||
for inverse_id in [i.id() for i in file.get_inverse(system)]:
|
||||
try:
|
||||
inverse = file.by_id(inverse_id)
|
||||
except:
|
||||
@@ -51,11 +47,11 @@ def remove_system(file: ifcopenshell.file, system: ifcopenshell.entity_instance)
|
||||
if inverse.is_a("IfcRelDefinesByProperties"):
|
||||
ifcopenshell.api.pset.remove_pset(
|
||||
file,
|
||||
product=settings["system"],
|
||||
product=system,
|
||||
pset=inverse.RelatingPropertyDefinition,
|
||||
)
|
||||
elif inverse.is_a("IfcRelAssignsToGroup"):
|
||||
if inverse.RelatingGroup == settings["system"]:
|
||||
if inverse.RelatingGroup == system:
|
||||
history = inverse.OwnerHistory
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
@@ -65,7 +61,7 @@ def remove_system(file: ifcopenshell.file, system: ifcopenshell.entity_instance)
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
history = settings["system"].OwnerHistory
|
||||
file.remove(settings["system"])
|
||||
history = system.OwnerHistory
|
||||
file.remove(system)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
|
||||
@@ -30,11 +30,8 @@ def unassign_flow_control(
|
||||
|
||||
:param related_flow_control: IfcDistributionControlElement controling the
|
||||
flow element
|
||||
:type related_flow_control: ifcopenshell.entity_instance
|
||||
:param relating_flow_element: The IfcDistributionFlowElement that is being controlled
|
||||
:type relating_flow_element: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -53,15 +50,10 @@ def unassign_flow_control(
|
||||
)
|
||||
"""
|
||||
|
||||
settings = {
|
||||
"relating_flow_element": relating_flow_element,
|
||||
"related_flow_control": related_flow_control,
|
||||
}
|
||||
|
||||
if not settings["related_flow_control"].AssignedToFlowElement:
|
||||
if not related_flow_control.AssignedToFlowElement:
|
||||
return
|
||||
assignment = settings["related_flow_control"].AssignedToFlowElement[0]
|
||||
if assignment.RelatingFlowElement != settings["relating_flow_element"]:
|
||||
assignment = related_flow_control.AssignedToFlowElement[0]
|
||||
if assignment.RelatingFlowElement != relating_flow_element:
|
||||
return
|
||||
if len(assignment.RelatedControlElements) == 1:
|
||||
history = assignment.OwnerHistory
|
||||
@@ -70,6 +62,6 @@ def unassign_flow_control(
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
return
|
||||
related_flow_controls = list(assignment.RelatedControlElements)
|
||||
related_flow_controls.remove(settings["related_flow_control"])
|
||||
related_flow_controls.remove(related_flow_control)
|
||||
assignment.RelatedControlElements = related_flow_controls
|
||||
ifcopenshell.api.owner.update_owner_history(file, **{"element": assignment})
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api.owner
|
||||
import ifcopenshell.util.element
|
||||
from typing import Any
|
||||
|
||||
|
||||
def unassign_port(
|
||||
@@ -32,11 +31,8 @@ def unassign_port(
|
||||
port for cleaning or patchin purposes.
|
||||
|
||||
:param element: The IfcDistributionElement to unassign the port from.
|
||||
:type element: ifcopenshell.entity_instance
|
||||
:param port: The IfcDistributionPort you want to unassign.
|
||||
:type port: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -55,23 +51,20 @@ def unassign_port(
|
||||
"""
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
usecase.settings = {
|
||||
"element": element,
|
||||
"port": port,
|
||||
}
|
||||
return usecase.execute()
|
||||
return usecase.execute(element, port)
|
||||
|
||||
|
||||
class Usecase:
|
||||
file: ifcopenshell.file
|
||||
settings: dict[str, Any]
|
||||
|
||||
def execute(self):
|
||||
def execute(self, element: ifcopenshell.entity_instance, port: ifcopenshell.entity_instance) -> None:
|
||||
if self.file.schema == "IFC2X3":
|
||||
self.element = element
|
||||
self.port = port
|
||||
return self.execute_ifc2x3()
|
||||
|
||||
for rel in self.settings["element"].IsNestedBy or []:
|
||||
if self.settings["port"] in rel.RelatedObjects:
|
||||
for rel in element.IsNestedBy or []:
|
||||
if port in rel.RelatedObjects:
|
||||
if len(rel.RelatedObjects) == 1:
|
||||
history = rel.OwnerHistory
|
||||
self.file.remove(rel)
|
||||
@@ -79,13 +72,13 @@ class Usecase:
|
||||
ifcopenshell.util.element.remove_deep2(self.file, history)
|
||||
return
|
||||
related_objects = set(rel.RelatedObjects) or set()
|
||||
related_objects.remove(self.settings["port"])
|
||||
related_objects.remove(port)
|
||||
rel.RelatedObjects = list(related_objects)
|
||||
ifcopenshell.api.owner.update_owner_history(self.file, **{"element": rel})
|
||||
|
||||
def execute_ifc2x3(self):
|
||||
for rel in self.settings["element"].HasPorts or []:
|
||||
if rel.RelatingPort == self.settings["port"]:
|
||||
def execute_ifc2x3(self) -> None:
|
||||
for rel in self.element.HasPorts or []:
|
||||
if rel.RelatingPort == self.port:
|
||||
history = rel.OwnerHistory
|
||||
self.file.remove(rel)
|
||||
if history:
|
||||
|
||||
@@ -33,11 +33,8 @@ def map_type_representations(
|
||||
be used to ensure consistency of the occurrence's representations.
|
||||
|
||||
:param related_object: The IfcElement occurrence.
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:param relating_type: The IfcElementType type.
|
||||
:type relating_type: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -84,28 +81,23 @@ def map_type_representations(
|
||||
# ifcopenshell.api.type.map_type_representations(model,
|
||||
# related_object=furniture, relating_type=furniture_type)
|
||||
"""
|
||||
settings = {
|
||||
"related_object": related_object,
|
||||
"relating_type": relating_type,
|
||||
}
|
||||
|
||||
if not settings["relating_type"].RepresentationMaps:
|
||||
if not relating_type.RepresentationMaps:
|
||||
return
|
||||
representations = []
|
||||
if settings["related_object"].Representation:
|
||||
representations = settings["related_object"].Representation.Representations
|
||||
if related_object.Representation:
|
||||
representations = related_object.Representation.Representations
|
||||
for representation in representations:
|
||||
ifcopenshell.api.geometry.unassign_representation(
|
||||
file,
|
||||
product=settings["related_object"],
|
||||
product=related_object,
|
||||
representation=representation,
|
||||
)
|
||||
ifcopenshell.api.geometry.remove_representation(file, **{"representation": representation})
|
||||
for representation_map in settings["relating_type"].RepresentationMaps:
|
||||
ifcopenshell.api.geometry.remove_representation(file, representation=representation)
|
||||
for representation_map in relating_type.RepresentationMaps:
|
||||
representation = representation_map.MappedRepresentation
|
||||
mapped_representation = ifcopenshell.api.geometry.map_representation(file, representation=representation)
|
||||
ifcopenshell.api.geometry.assign_representation(
|
||||
file,
|
||||
product=settings["related_object"],
|
||||
product=related_object,
|
||||
representation=mapped_representation,
|
||||
)
|
||||
|
||||
@@ -35,9 +35,7 @@ def add_context_dependent_unit(
|
||||
sensible normal unit for. In that case, firstly stop whatever you're
|
||||
doing and have a hard think about your life, and then if life really
|
||||
is going that badly for you, check out the IFC docs for IfcUnitEnum.
|
||||
:type unit_type: str
|
||||
:param name: Give your unit a name. X what? X bananas?
|
||||
:type name: str
|
||||
:param dimensions: Units typically measure one of 7 fundamental physical
|
||||
dimensions: length, mass, time, electric current, temperature,
|
||||
substance amount, or luminous intensity. These are represented as a
|
||||
@@ -46,9 +44,7 @@ def add_context_dependent_unit(
|
||||
where as an area unit is (2, 0, 0, 0, 0, 0, 0). A unit of meters per
|
||||
second is (1, 0, -1, 0, 0, 0, 0). For context dependent units, it is
|
||||
recommended to leave this as the default of (0, 0, 0, 0, 0, 0, 0).
|
||||
:type dimensions: list[int]
|
||||
:return: The new IfcContextDependentUnit
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -57,11 +53,9 @@ def add_context_dependent_unit(
|
||||
# Boxes of things
|
||||
ifcopenshell.api.unit.add_context_dependent_unit(model, name="BOXES")
|
||||
"""
|
||||
settings = {"unit_type": unit_type, "name": name, "dimensions": dimensions}
|
||||
|
||||
return file.create_entity(
|
||||
"IfcContextDependentUnit",
|
||||
Dimensions=file.createIfcDimensionalExponents(*settings["dimensions"]),
|
||||
UnitType=settings["unit_type"],
|
||||
Name=settings["name"],
|
||||
Dimensions=file.createIfcDimensionalExponents(*dimensions),
|
||||
UnitType=unit_type,
|
||||
Name=name,
|
||||
)
|
||||
|
||||
@@ -36,17 +36,14 @@ def add_conversion_based_unit(
|
||||
kip, psi, ksi, minute, hour, day, btu, and fahrenheit.
|
||||
|
||||
:param name: A converted name chosen from the list above.
|
||||
:type name: str
|
||||
:param conversion_offset: If you want to offset the conversion further
|
||||
by a set number, you may specify it here. For example, fahrenheit is
|
||||
1.8 * kelvin - 459.67. The -459.67 is the conversion offset. Note
|
||||
that this is just an example and you don't actually need to specify
|
||||
that for fahrenheit as it's built into this API function. For
|
||||
advanced users only.
|
||||
:type conversion_offset: float, optional
|
||||
:return: The new IfcConversionBasedUnit or
|
||||
IfcConversionBasedUnitWithOffset
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -59,28 +56,26 @@ def add_conversion_based_unit(
|
||||
# Make it our default units, if we are doing an imperial building
|
||||
ifcopenshell.api.unit.assign_unit(model, units=[length, area])
|
||||
"""
|
||||
settings = {"name": name, "conversion_offset": conversion_offset}
|
||||
|
||||
unit_type = ifcopenshell.util.unit.imperial_types.get(settings["name"], "USERDEFINED")
|
||||
unit_type = ifcopenshell.util.unit.imperial_types.get(name, "USERDEFINED")
|
||||
dimensions = ifcopenshell.util.unit.named_dimensions[unit_type]
|
||||
exponents = file.createIfcDimensionalExponents(*dimensions)
|
||||
si_name = ifcopenshell.util.unit.si_type_names[unit_type]
|
||||
si_unit = file.createIfcSIUnit(UnitType=unit_type, Name=si_name)
|
||||
|
||||
conversion_real = ifcopenshell.util.unit.si_conversions.get(settings["name"], 1)
|
||||
conversion_real = ifcopenshell.util.unit.si_conversions.get(name, 1)
|
||||
value_component = file.create_entity("IfcReal", **{"wrappedValue": conversion_real})
|
||||
conversion_factor = file.createIfcMeasureWithUnit(value_component, si_unit)
|
||||
|
||||
conversion_offset = settings["conversion_offset"]
|
||||
if not conversion_offset:
|
||||
conversion_offset = ifcopenshell.util.unit.si_offsets.get(settings["name"], 0)
|
||||
conversion_offset = ifcopenshell.util.unit.si_offsets.get(name, 0)
|
||||
|
||||
if conversion_offset:
|
||||
return file.createIfcConversionBasedUnitWithOffset(
|
||||
exponents,
|
||||
unit_type,
|
||||
settings["name"],
|
||||
name,
|
||||
conversion_factor,
|
||||
conversion_offset,
|
||||
)
|
||||
return file.createIfcConversionBasedUnit(exponents, unit_type, settings["name"], conversion_factor)
|
||||
return file.createIfcConversionBasedUnit(exponents, unit_type, name, conversion_factor)
|
||||
|
||||
@@ -26,9 +26,7 @@ def add_monetary_unit(file: ifcopenshell.file, currency: str = "DOLLARYDOO") ->
|
||||
USD, GBP, AUD, MYR, etc.
|
||||
|
||||
:param currency: The currency code
|
||||
:type currency: str
|
||||
:return: The newly created IfcMonetaryUnit
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -41,6 +39,4 @@ def add_monetary_unit(file: ifcopenshell.file, currency: str = "DOLLARYDOO") ->
|
||||
# Make it our default currency
|
||||
ifcopenshell.api.unit.assign_unit(model, units=[zwl])
|
||||
"""
|
||||
settings = {"currency": currency}
|
||||
|
||||
return file.create_entity("IfcMonetaryUnit", settings["currency"])
|
||||
return file.create_entity("IfcMonetaryUnit", currency)
|
||||
|
||||
@@ -40,12 +40,9 @@ def add_si_unit(
|
||||
|
||||
:param unit_type: A type of unit chosen from the list above. For
|
||||
example, choosing LENGTHUNIT will give you a metre.
|
||||
:type unit_type: str
|
||||
:param prefix: A prefix chosen from the list above, or None for no
|
||||
prefix.
|
||||
:type prefix: str,optional
|
||||
:return: The newly created IfcSIUnit
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
Example:
|
||||
|
||||
@@ -58,7 +55,5 @@ def add_si_unit(
|
||||
# Make it our default units, if we are doing a metric building
|
||||
ifcopenshell.api.unit.assign_unit(model, units=[length, area])
|
||||
"""
|
||||
settings = {"unit_type": unit_type, "prefix": prefix}
|
||||
|
||||
name = ifcopenshell.util.unit.si_type_names.get(settings["unit_type"], None)
|
||||
return file.create_entity("IfcSIUnit", UnitType=settings["unit_type"], Name=name, Prefix=settings["prefix"])
|
||||
name = ifcopenshell.util.unit.si_type_names.get(unit_type, None)
|
||||
return file.create_entity("IfcSIUnit", UnitType=unit_type, Name=name, Prefix=prefix)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user