This commit is contained in:
Andrej730
2025-02-19 11:06:03 +05:00
parent 6c511f6b1b
commit 67bac441ad
92 changed files with 1261 additions and 837 deletions
@@ -30,11 +30,8 @@ def copy_cost_item_values(
parametrically linked, so if one value changes, the other will not.
:param source: The IfcCostItem to copy cost values from
:type source: ifcopenshell.entity_instance
:param destination: The IfcCostItem to copy cost values from
:type destination: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -53,11 +50,9 @@ def copy_cost_item_values(
# Let's copy the value from one item to another
ifcopenshell.api.cost.copy_cost_item_values(model, source=item1, destination=item2)
"""
settings = {"source": source, "destination": destination}
for cost_value in settings["destination"].CostValues or []:
for cost_value in destination.CostValues or []:
ifcopenshell.api.cost.remove_cost_item_value(file, cost_value=cost_value)
copied_cost_values = []
for cost_value in settings["source"].CostValues or []:
for cost_value in source.CostValues or []:
copied_cost_values.append(ifcopenshell.util.element.copy_deep(file, cost_value))
settings["destination"].CostValues = copied_cost_values
destination.CostValues = copied_cost_values
@@ -62,15 +62,10 @@ def assign_layer(
# only one item) to the layer.
ifcopenshell.api.layer.assign_layer(model, items=[representation.Items[0]], layer=layer)
"""
settings = {
"items": items,
"layer": layer,
}
# support AssignedItems == None since layer might just got created
layer = settings["layer"]
assigned_items: set[ifcopenshell.entity_instance]
assigned_items = set(layer.AssignedItems or [])
items = set(settings["items"])
if items.issubset(assigned_items):
items_set = set(items)
if items_set.issubset(assigned_items):
return
layer.AssignedItems = list(assigned_items | items)
layer.AssignedItems = list(assigned_items | items_set)
@@ -91,8 +91,7 @@ def edit_profile_usage(
usecase = Usecase()
usecase.file = file
usecase.settings = {"usage": usage, "attributes": attributes}
return usecase.execute()
return usecase.execute(usage, attributes)
class Usecase:
@@ -30,17 +30,15 @@ def get_application(ifc: ifcopenshell.file) -> Union[ifcopenshell.entity_instanc
IfcApplication. See ifcopenshell.api.owner.create_owner_history for details.
:param ifc: The IFC file object that is being edited.
:type ifc: ifcopenshell.file
:return: The IfcApplication with metadata of the authoring software.
:rtype: ifcopenshell.entity_instance
"""
app = ifc.by_type("IfcApplication")
app = next(iter(ifc.by_type("IfcApplication")), None)
if not app and ifc.schema == "IFC2X3":
raise Exception(
"Please create an application to continue. See the owner.create_owner_history docs for more info."
"https://docs.ifcopenshell.org/autoapi/ifcopenshell/api/owner/create_owner_history/index.html"
)
return (app or [None])[0]
return app
def get_user(ifc: ifcopenshell.file) -> Union[ifcopenshell.entity_instance, None]:
@@ -50,17 +48,15 @@ def get_user(ifc: ifcopenshell.file) -> Union[ifcopenshell.entity_instance, None
IfcApplication. See ifcopenshell.api.owner.create_owner_history for details.
:param ifc: The IFC file object that is being edited.
:type ifc: ifcopenshell.file
:return: The IfcPersonAndOrganization with metadata of the authoring user.
:rtype: ifcopenshell.entity_instance
"""
pao = ifc.by_type("IfcPersonAndOrganization")
pao = next(iter(ifc.by_type("IfcPersonAndOrganization")), None)
if not pao and ifc.schema == "IFC2X3":
raise Exception(
"Please create a user to continue. See the owner.create_owner_history docs for more info."
"https://docs.ifcopenshell.org/autoapi/ifcopenshell/api/owner/create_owner_history/index.html"
)
return (pao or [None])[0]
return pao
get_application_factory = get_application
@@ -19,6 +19,8 @@
import datetime
import ifcopenshell.util.date
import ifcopenshell.util.sequence
from ifcopenshell.util.sequence import DURATION_TYPE
from typing import Union, Optional
def cascade_schedule(file: ifcopenshell.file, task: ifcopenshell.entity_instance) -> None:
@@ -41,9 +43,7 @@ def cascade_schedule(file: ifcopenshell.file, task: ifcopenshell.entity_instance
be equivalent to be Tuesday 8am, for instance.
:param task: The start task to begin cascading from.
:type task: ifcopenshell.entity_instance
:return: None
:rtype: None
Example:
@@ -103,16 +103,22 @@ def cascade_schedule(file: ifcopenshell.file, task: ifcopenshell.entity_instance
"""
usecase = Usecase()
usecase.file = file
usecase.settings = {"task": task}
return usecase.execute()
return usecase.execute(task)
class Usecase:
def execute(self):
self.calendar_cache = {}
self.cascade_task(self.settings["task"], is_first_task=True)
file: ifcopenshell.file
def cascade_task(self, task, is_first_task=False, task_sequence=None):
def execute(self, task: ifcopenshell.entity_instance):
self.calendar_cache = {}
self.cascade_task(task, is_first_task=True)
def cascade_task(
self,
task: ifcopenshell.entity_instance,
is_first_task: bool = False,
task_sequence: Optional[list[ifcopenshell.entity_instance]] = None,
) -> None:
if task_sequence is None:
task_sequence = []
@@ -316,18 +322,22 @@ class Usecase:
for nested_task in rel.RelatedObjects or []
]
def get_lag_time_days(self, lag_time):
def get_lag_time_days(self, lag_time: ifcopenshell.entity_instance) -> int:
return ifcopenshell.util.date.ifc2datetime(lag_time.LagValue.wrappedValue).days
def get_calendar(self, task):
def get_calendar(self, task: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
if task.id() not in self.calendar_cache:
self.calendar_cache[task.id()] = ifcopenshell.util.sequence.derive_calendar(task)
return self.calendar_cache[task.id()]
def offset_date(self, date, days, duration_type, calendar):
def offset_date(
self, date: datetime.datetime, days: int, duration_type: DURATION_TYPE, calendar: ifcopenshell.entity_instance
) -> datetime.datetime:
return ifcopenshell.util.sequence.offset_date(date, datetime.timedelta(days=days), duration_type, calendar)
def get_task_time_attribute(self, task, attribute):
def get_task_time_attribute(
self, task: ifcopenshell.entity_instance, attribute: str
) -> Union[datetime.datetime, None]:
if task.TaskTime:
value = getattr(task.TaskTime, attribute)
if value:
@@ -75,7 +75,9 @@ class Usecase:
baseline_work_schedule.Name = name
self.create_baseline_reference(work_schedule, baseline_work_schedule)
for summary_task in ifcopenshell.util.sequence.get_root_tasks(work_schedule):
current, duplicate = ifcopenshell.api.sequence.duplicate_task(self.file, task=summary_task)
res = ifcopenshell.api.sequence.duplicate_task(self.file, task=summary_task)
assert isinstance(res, list)
current, duplicate = res
ifcopenshell.api.control.assign_control(
self.file, relating_control=baseline_work_schedule, related_object=duplicate[0]
)
@@ -16,42 +16,33 @@
# You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
from ifcopenshell.util.shape_builder import VectorType, ifc_safe_vector_type
def edit_structural_connection_cs(
file: ifcopenshell.file,
structural_item: ifcopenshell.entity_instance,
axis: tuple[float, float, float] = (0.0, 0.0, 1.0),
ref_direction: tuple[float, float, float] = (1.0, 0.0, 0.0),
axis: VectorType = (0.0, 0.0, 1.0),
ref_direction: VectorType = (1.0, 0.0, 0.0),
) -> None:
"""Edits the coordinate system of a structural connection
:param structural_item: The IfcStructuralItem you want to modify.
:type structural_item: ifcopenshell.entity_instance
:param axis: The unit Z axis vector defined as a list of 3 floats.
Defaults to (0., 0., 1.).
:type axis: tuple[float, float, float]
:param ref_direction: The unit X axis vector defined as a list of 3
floats. Defaults to (1., 0., 0.).
:type ref_direction: tuple[float, float, float]
:return: None
:rtype: None
"""
settings = {
"structural_item": structural_item,
"axis": axis,
"ref_direction": ref_direction,
}
if settings["structural_item"].ConditionCoordinateSystem is None:
if structural_item.ConditionCoordinateSystem is None:
point = file.createIfcCartesianPoint((0.0, 0.0, 0.0))
ccs = file.createIfcAxis2Placement3D(point, None, None)
settings["structural_item"].ConditionCoordinateSystem = ccs
structural_item.ConditionCoordinateSystem = ccs
ccs = settings["structural_item"].ConditionCoordinateSystem
ccs = structural_item.ConditionCoordinateSystem
if ccs.Axis and len(file.get_inverse(ccs.Axis)) == 1:
file.remove(ccs.Axis)
ccs.Axis = file.createIfcDirection(settings["axis"])
if ccs.RefDirection and len(file.get_inverse(ccs.RefDirection)) == 1:
file.remove(ccs.RefDirection)
ccs.RefDirection = file.createIfcDirection(settings["ref_direction"])
ccs.Axis = file.create_entity("IfcDirection", ifc_safe_vector_type(axis))
if (prev_ref_direction := ccs.RefDirection) and len(file.get_inverse(prev_ref_direction)) == 1:
file.remove(prev_ref_direction)
ccs.RefDirection = file.create_entity("IfcDirection", ifc_safe_vector_type(ref_direction))