This commit is contained in:
Andrej730
2025-07-24 19:14:26 +05:00
parent cfd5d2a4eb
commit 05a8824019
22 changed files with 258 additions and 139 deletions
@@ -27,29 +27,28 @@ def assign_representation(
) -> None:
usecase = Usecase()
usecase.file = file
usecase.settings = {"product": product, "representation": representation}
return usecase.execute()
return usecase.execute(product, representation)
class Usecase:
file: ifcopenshell.file
settings: dict[str, Any]
def execute(self) -> None:
if self.settings["product"].is_a("IfcProduct"):
product_type = ifcopenshell.util.element.get_type(self.settings["product"])
def execute(self, product: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance) -> None:
if product.is_a("IfcProduct"):
product_type = ifcopenshell.util.element.get_type(product)
if (
product_type
and product_type.RepresentationMaps
and self.settings["representation"].RepresentationType != "MappedRepresentation"
and representation.RepresentationType != "MappedRepresentation"
):
self.settings["product"] = product_type
product = product_type
if self.settings["product"].is_a("IfcProduct"):
self.assign_product_representation(self.settings["product"], self.settings["representation"])
elif self.settings["product"].is_a("IfcTypeProduct"):
if self.settings["product"].RepresentationMaps:
maps = list(self.settings["product"].RepresentationMaps)
if product.is_a("IfcProduct"):
self.assign_product_representation(product, representation)
elif product.is_a("IfcTypeProduct"):
if product.RepresentationMaps:
maps = list(product.RepresentationMaps)
else:
maps = []
self.zero = self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))
@@ -60,22 +59,22 @@ class Usecase:
"IfcRepresentationMap",
**{
"MappingOrigin": self.file.createIfcAxis2Placement3D(self.zero, self.z_axis, self.x_axis),
"MappedRepresentation": self.settings["representation"],
"MappedRepresentation": representation,
}
)
)
self.settings["product"].RepresentationMaps = maps
product.RepresentationMaps = maps
if self.file.schema == "IFC2X3":
types = self.settings["product"].ObjectTypeOf
types = product.ObjectTypeOf
else:
types = self.settings["product"].Types
types = product.Types
if types:
for element in types[0].RelatedObjects:
mapped_representation = ifcopenshell.api.geometry.map_representation(
self.file, representation=self.settings["representation"]
self.file, representation=representation
)
self.assign_product_representation(element, mapped_representation)
ifcopenshell.api.owner.update_owner_history(self.file, element=self.settings["product"])
ifcopenshell.api.owner.update_owner_history(self.file, element=product)
def assign_product_representation(
self, product: ifcopenshell.entity_instance, representation: ifcopenshell.entity_instance
@@ -30,6 +30,8 @@ def assign_declaration(
) -> Union[ifcopenshell.entity_instance, None]:
"""Declares the list of elements to the project
Feature was added in IFC4.
All data in a model must be directly or indirectly related to the
project. Most data is indirectly related, existing instead within the
spatial decomposition tree. Other data, such as types, may be declared
@@ -82,21 +84,16 @@ def assign_declaration(
# All done, just for fun let's save our asset library to disk for later use.
library.write("/path/to/my-library.ifc")
"""
settings = {
"definitions": definitions,
"relating_context": relating_context,
}
relating_context = settings["relating_context"]
all_declares = relating_context.Declares
definitions = set(settings["definitions"])
definitions_set = set(definitions)
previous_declares_rels: set[ifcopenshell.entity_instance] = set()
objects_without_contexts: list[ifcopenshell.entity_instance] = []
objects_with_contexts: list[ifcopenshell.entity_instance] = []
# check if there is anything to change
for definition in definitions:
for definition in definitions_set:
has_context = getattr(definition, "HasContext", None)
if has_context is None:
continue
@@ -20,7 +20,6 @@ import ifcopenshell.api.control
import ifcopenshell.api.root
import ifcopenshell.api.nest
import ifcopenshell
import ifcopenshell.guid
from typing import Optional
@@ -23,14 +23,12 @@ 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
# TODO: inconsistent name with other copy_xxx api methods.
def duplicate_task(
file: ifcopenshell.file, task: ifcopenshell.entity_instance
) -> Union[ifcopenshell.entity_instance, list[ifcopenshell.entity_instance]]:
) -> tuple[list[ifcopenshell.entity_instance], list[ifcopenshell.entity_instance]]:
"""Duplicates a task in the project
The following relationships are also duplicated:
@@ -53,24 +51,27 @@ def duplicate_task(
"""
usecase = Usecase()
usecase.file = file
usecase.settings = {"task": task}
return usecase.execute()
return usecase.execute(task)
class Usecase:
file: ifcopenshell.file
settings: dict[str, list[ifcopenshell.entity_instance]]
current: list[ifcopenshell.entity_instance]
duplicate: list[ifcopenshell.entity_instance]
def execute(self):
self.tracker = {"current": [], "duplicate": []}
self.duplicate_task(self.settings["task"])
self.copy_sequence_relationship(self.tracker["current"], self.tracker["duplicate"])
return self.tracker["current"], self.tracker["duplicate"]
def execute(
self, task: ifcopenshell.entity_instance
) -> tuple[list[ifcopenshell.entity_instance], list[ifcopenshell.entity_instance]]:
self.current = []
self.duplicate = []
self.duplicate_task(task)
self.copy_sequence_relationship()
return self.current, self.duplicate
def duplicate_task(self, task: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
new_task = ifcopenshell.util.element.copy_deep(self.file, task)
self.tracker["current"].append(task)
self.tracker["duplicate"].append(new_task)
self.current.append(task)
self.duplicate.append(new_task)
self.copy_indirect_attributes(task, new_task)
return new_task
@@ -118,7 +119,9 @@ class Usecase:
new_value.append(to_element)
inverse[i] = new_value
def copy_sequence_relationship(self, original_tasks, duplicated_tasks):
def copy_sequence_relationship(self) -> None:
original_tasks = self.current
duplicated_tasks = self.duplicate
for i, original_task in enumerate(original_tasks):
for inverse in self.file.get_inverse(original_task):
if inverse.is_a("IfcRelSequence") and (
@@ -202,7 +202,7 @@ def get_root_cost_items(cost_schedule: ifcopenshell.entity_instance) -> list[ifc
def get_all_nested_cost_items(
cost_item: ifcopenshell.entity_instance,
) -> Generator[ifcopenshell.entity_instance, None, None]:
) -> Generator[ifcopenshell.entity_instance]:
for cost_item in get_nested_cost_items(cost_item):
yield cost_item
yield from get_all_nested_cost_items(cost_item)
@@ -217,7 +217,7 @@ def get_nested_cost_items(cost_item: ifcopenshell.entity_instance, is_deep=False
def get_schedule_cost_items(
cost_schedule: ifcopenshell.entity_instance,
) -> Generator[ifcopenshell.entity_instance, None, None]:
) -> Generator[ifcopenshell.entity_instance]:
"""Get all cost schedule cost items, including the nested ones."""
for cost_item in get_root_cost_items(cost_schedule):
yield cost_item