mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Merge branch 'v0.8.0' into fix-ifccircle-ifcellipse-processing
This commit is contained in:
@@ -52,8 +52,8 @@ ifeq ($(PLATFORM), win64)
|
||||
PLATFORMTAG:=win_amd64
|
||||
endif
|
||||
|
||||
IOS_URL:=https://s3.amazonaws.com/ifcopenshell-builds/ifcopenshell-python-$(PYNUMBER)-v0.7.11-03935a9-$(PLATFORM).zip
|
||||
IFCCONVERT_URL:=https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v0.7.11-03935a9-$(PLATFORM).zip
|
||||
IOS_URL:=https://s3.amazonaws.com/ifcopenshell-builds/ifcopenshell-python-$(PYNUMBER)-v$(VERSION)-f5e02d1-$(PLATFORM).zip
|
||||
IFCCONVERT_URL:=https://s3.amazonaws.com/ifcopenshell-builds/IfcConvert-v$(VERSION)-f5e02d1-$(PLATFORM).zip
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
|
||||
@@ -104,12 +104,14 @@ class Usecase:
|
||||
if self.settings["prop_name"]:
|
||||
self.quantities = set(self.settings["cost_item"].CostQuantities or [])
|
||||
for product in self.settings["products"]:
|
||||
if not product.is_a("IfcElement"):
|
||||
continue
|
||||
self.assign_cost_control(related_object=product, cost_item=self.settings["cost_item"])
|
||||
if self.settings["prop_name"]:
|
||||
if (
|
||||
self.settings["cost_item"].CostQuantities
|
||||
and self.settings["cost_item"].CostQuantities[0].Name.lower() != self.settings["prop_name"].lower()
|
||||
) or not product.is_a("IfcObject"):
|
||||
):
|
||||
continue
|
||||
self.add_quantity_from_related_object(product)
|
||||
if self.settings["prop_name"]:
|
||||
|
||||
@@ -102,9 +102,10 @@ def calculate_cost_item_resource_value(file: ifcopenshell.file, cost_item: ifcop
|
||||
for resource in resources:
|
||||
cost, unit = ifcopenshell.util.resource.get_cost(resource)
|
||||
if not cost:
|
||||
cost, unit = ifcopenshell.util.resource.get_parent_cost(
|
||||
resource
|
||||
) # Concept to standardise - Not defined in schema, but this makes manual scheduling of resources 10x faster and less duplicate data.
|
||||
# Concept to standardise - Not defined in schema, but this makes manual scheduling of resources 10x faster and less duplicate data.
|
||||
parent_cost = ifcopenshell.util.resource.get_parent_cost(resource)
|
||||
assert parent_cost
|
||||
cost, unit = parent_cost
|
||||
quantity = ifcopenshell.util.resource.get_quantity(resource)
|
||||
if not cost or not quantity:
|
||||
continue
|
||||
|
||||
@@ -42,6 +42,6 @@ def copy_profile(file: ifcopenshell.file, profile: ifcopenshell.entity_instance)
|
||||
inverses = file.get_inverse(profile)
|
||||
psets = [i for i in inverses if i.is_a("IfcProfileProperties")]
|
||||
for pset in psets:
|
||||
new_pset = ifcopenshell.util.element.copy_deep(file, pset, exclude=["IfcProfileDef"])
|
||||
new_pset = ifcopenshell.util.element.copy(file, pset)
|
||||
new_pset.ProfileDefinition = new_profile
|
||||
return new_profile
|
||||
|
||||
@@ -167,6 +167,9 @@ def edit_pset(
|
||||
|
||||
|
||||
class Usecase:
|
||||
file: ifcopenshell.file
|
||||
settings: dict[str, Any]
|
||||
|
||||
def execute(self) -> None:
|
||||
self.update_pset_name()
|
||||
self.load_pset_template()
|
||||
@@ -378,7 +381,7 @@ class Usecase:
|
||||
properties.append(self.file.create_entity("IfcPropertySingleValue", **args))
|
||||
return properties
|
||||
|
||||
def assign_new_properties(self, props: ifcopenshell.entity_instance) -> None:
|
||||
def assign_new_properties(self, props: list[ifcopenshell.entity_instance]) -> None:
|
||||
if hasattr(self.settings["pset"], "HasProperties"):
|
||||
self.settings["pset"].HasProperties = props
|
||||
|
||||
|
||||
@@ -87,7 +87,8 @@ def unshare_pset(
|
||||
for product in products:
|
||||
# No need to consider about profile/material properties since
|
||||
# they are assigned to 1 element directly and therefore cannot be shared.
|
||||
pset_copy = ifcopenshell.util.element.copy_deep(file, pset)
|
||||
# Don't copy_deep to keep it light - edit_pset supports unsharing shared props.
|
||||
pset_copy = ifcopenshell.util.element.copy(file, pset)
|
||||
pset_copies.append(pset_copy)
|
||||
ifcopenshell.api.pset.assign_pset(file, [product], pset_copy)
|
||||
|
||||
|
||||
@@ -445,7 +445,7 @@ def get_elements_by_pset(pset: ifcopenshell.entity_instance) -> set[ifcopenshell
|
||||
"""Retrieve the elements (or element types) that are using the provided property set."""
|
||||
is_ifc2x3 = pset.file.schema == "IFC2X3"
|
||||
elements = set()
|
||||
if pset.is_a("IfcPropertySet"):
|
||||
if pset.is_a("IfcPropertySet") or pset.is_a("IfcQuantitySet"):
|
||||
rels = pset.PropertyDefinitionOf if is_ifc2x3 else pset.DefinesOccurrence
|
||||
for rel in rels:
|
||||
elements.update(rel.RelatedObjects)
|
||||
|
||||
@@ -166,9 +166,9 @@ def get_quantity(resource: ifcopenshell.entity_instance) -> float:
|
||||
return duration.total_seconds() / 3600
|
||||
|
||||
|
||||
def get_parent_cost(resource: ifcopenshell.entity_instance) -> Union[None, tuple[float, Union[str, None]]]:
|
||||
if not resource.Nests:
|
||||
def get_parent_cost(resource: ifcopenshell.entity_instance) -> Union[tuple[float, Union[str, None]], None]:
|
||||
if not (nests := resource.Nests):
|
||||
return
|
||||
else:
|
||||
cost = get_cost(resource.Nests[0].RelatingObject)
|
||||
cost = get_cost(nests[0].RelatingObject)
|
||||
return cost
|
||||
|
||||
@@ -36,7 +36,18 @@ RECURRENCE_TYPE = Literal[
|
||||
]
|
||||
|
||||
|
||||
def derive_date(task, attribute_name, date=None, is_earliest=False, is_latest=False):
|
||||
def derive_date(
|
||||
task: ifcopenshell.entity_instance,
|
||||
attribute_name: str,
|
||||
date=None,
|
||||
is_earliest: bool = False,
|
||||
is_latest: bool = False,
|
||||
):
|
||||
"""
|
||||
|
||||
:param task: IfcTask.
|
||||
|
||||
"""
|
||||
if task.TaskTime:
|
||||
current_date = (
|
||||
ifcopenshell.util.date.ifc2datetime(getattr(task.TaskTime, attribute_name))
|
||||
@@ -268,7 +279,7 @@ def get_task_work_schedule(task: ifcopenshell.entity_instance) -> Union[ifcopens
|
||||
|
||||
|
||||
def get_nested_tasks(task: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
|
||||
return [object for rel in task.IsNestedBy or [] for object in rel.RelatedObjects]
|
||||
return [object for rel in task.IsNestedBy or [] for object in rel.RelatedObjects if object.is_a("IfcTask")]
|
||||
|
||||
|
||||
def get_parent_task(task: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
|
||||
@@ -448,12 +459,9 @@ def get_related_products(
|
||||
"""Gets the related products being output by a task
|
||||
|
||||
:param relating_product: One of the products already output by the task.
|
||||
:type relating_product: ifcopenshell.entity_instance, optional
|
||||
:param related_object: The IfcTask that you want to get all the related
|
||||
products for.
|
||||
:type related_object: ifcopenshell.entity_instance, optional
|
||||
:return: A set of IfcProducts output by the IfcTask.
|
||||
:rtype: set[ifcopenshell.entity_instance]
|
||||
|
||||
Example:
|
||||
|
||||
@@ -478,17 +486,18 @@ def get_related_products(
|
||||
products = ifcopenshell.util.sequence.get_related_products(related_object=task)
|
||||
"""
|
||||
|
||||
assert relating_product or related_object, "Either relating_product or related_object must be provided."
|
||||
|
||||
products = set()
|
||||
related_object = None
|
||||
if related_object:
|
||||
related_object = related_object
|
||||
elif relating_product:
|
||||
if not related_object and relating_product:
|
||||
for reference in relating_product.ReferencedBy:
|
||||
if reference.is_a("IfcRelAssignsToProduct"):
|
||||
related_object = reference.RelatedObjects[0]
|
||||
|
||||
if related_object:
|
||||
assignments = related_object.HasAssignments
|
||||
for assignment in assignments:
|
||||
if assignment.is_a("IfcRelAssignsToProduct"):
|
||||
products.add(assignment.RelatingProduct.id())
|
||||
|
||||
return products
|
||||
|
||||
@@ -368,6 +368,7 @@ class ShapeBuilder:
|
||||
"ProfileType": profile_type,
|
||||
"OuterCurve": outer_curve,
|
||||
}
|
||||
|
||||
if self.file.schema == "IFC2X3":
|
||||
kwargs["Position"] = self.create_axis2_placement_2d()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user