This commit is contained in:
Andrej
2025-06-06 12:40:08 +05:00
parent a374a7e3ff
commit bf4a3f074f
10 changed files with 160 additions and 103 deletions
@@ -21,6 +21,7 @@ import ifcopenshell
import ifcopenshell.util.date import ifcopenshell.util.date
import ifcopenshell.util.classification import ifcopenshell.util.classification
import bonsai.tool as tool import bonsai.tool as tool
from typing import Any
from bonsai.bim.ifc import IfcStore from bonsai.bim.ifc import IfcStore
@@ -157,8 +158,8 @@ class CostClassificationsData(ReferencesData):
cls.data["object_type"] = "Cost" cls.data["object_type"] = "Cost"
@classmethod @classmethod
def references(cls): def references(cls) -> list[dict[str, Any]]:
results = [] results: list[dict[str, Any]] = []
props = tool.Cost.get_cost_props() props = tool.Cost.get_cost_props()
element = tool.Ifc.get().by_id(props.cost_items[props.active_cost_item_index].ifc_definition_id) element = tool.Ifc.get().by_id(props.cost_items[props.active_cost_item_index].ifc_definition_id)
if element: if element:
@@ -46,6 +46,7 @@ class AddCostSchedule(bpy.types.Operator, tool.Ifc.Operator):
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
assert layout
props = tool.Cost.get_cost_props() props = tool.Cost.get_cost_props()
layout.prop(self, "name", text="Name") layout.prop(self, "name", text="Name")
layout.prop(props, "cost_schedule_predefined_types", text="Type") layout.prop(props, "cost_schedule_predefined_types", text="Type")
@@ -149,6 +150,9 @@ class ExpandCostItem(bpy.types.Operator, tool.Ifc.Operator):
bl_description = "Expand this cost item" bl_description = "Expand this cost item"
cost_item: bpy.props.IntProperty() cost_item: bpy.props.IntProperty()
if TYPE_CHECKING:
cost_item: int
def _execute(self, context): def _execute(self, context):
core.expand_cost_item(tool.Cost, cost_item=tool.Ifc.get().by_id(self.cost_item)) core.expand_cost_item(tool.Cost, cost_item=tool.Ifc.get().by_id(self.cost_item))
@@ -171,6 +175,9 @@ class ContractCostItem(bpy.types.Operator, tool.Ifc.Operator):
bl_description = "Contract a cost item" bl_description = "Contract a cost item"
cost_item: bpy.props.IntProperty() cost_item: bpy.props.IntProperty()
if TYPE_CHECKING:
cost_item: int
def _execute(self, context): def _execute(self, context):
core.contract_cost_item(tool.Cost, cost_item=tool.Ifc.get().by_id(self.cost_item)) core.contract_cost_item(tool.Cost, cost_item=tool.Ifc.get().by_id(self.cost_item))
@@ -192,6 +199,9 @@ class RemoveCostItem(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
cost_item: bpy.props.IntProperty() cost_item: bpy.props.IntProperty()
if TYPE_CHECKING:
cost_item: int
def _execute(self, context): def _execute(self, context):
core.remove_cost_item(tool.Ifc, tool.Cost, cost_item_id=self.cost_item) core.remove_cost_item(tool.Ifc, tool.Cost, cost_item_id=self.cost_item)
@@ -700,6 +710,9 @@ class ExpandCostItemRate(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
cost_item: bpy.props.IntProperty() cost_item: bpy.props.IntProperty()
if TYPE_CHECKING:
cost_item: int
def _execute(self, context): def _execute(self, context):
core.expand_cost_item_rate(tool.Cost, self.cost_item) core.expand_cost_item_rate(tool.Cost, self.cost_item)
return {"FINISHED"} return {"FINISHED"}
@@ -711,6 +724,9 @@ class ContractCostItemRate(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
cost_item: bpy.props.IntProperty() cost_item: bpy.props.IntProperty()
if TYPE_CHECKING:
cost_item: int
def _execute(self, context): def _execute(self, context):
core.contract_cost_item_rate(tool.Cost, self.cost_item) core.contract_cost_item_rate(tool.Cost, self.cost_item)
return {"FINISHED"} return {"FINISHED"}
+24 -17
View File
@@ -18,6 +18,7 @@
import bpy import bpy
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.api.cost
import bonsai.tool as tool import bonsai.tool as tool
from bonsai.bim.module.classification.data import CostClassificationsData from bonsai.bim.module.classification.data import CostClassificationsData
from bonsai.bim.module.cost.data import CostSchedulesData, CostItemRatesData, CostItemQuantitiesData from bonsai.bim.module.cost.data import CostSchedulesData, CostItemRatesData, CostItemQuantitiesData
@@ -36,42 +37,48 @@ from bpy.props import (
from typing import TYPE_CHECKING, Literal from typing import TYPE_CHECKING, Literal
def get_schedule_of_rates(self, context): def get_schedule_of_rates(self: "BIMCostProperties", context: bpy.types.Context) -> tool.Blender.BLENDER_ENUM_ITEMS:
if not CostItemRatesData.is_loaded: if not CostItemRatesData.is_loaded:
CostItemRatesData.load() CostItemRatesData.load()
# return CostItemRatesData.data["schedule_of_rates"] # return CostItemRatesData.data["schedule_of_rates"]
return CostItemRatesData.data["cost_schedules"] return CostItemRatesData.data["cost_schedules"]
def update_schedule_of_rates(self, context): def update_schedule_of_rates(self: "BIMCostProperties", context: bpy.types.Context) -> None:
tool.Cost.load_schedule_of_rates_tree(schedule_of_rates=tool.Ifc.get().by_id(int(self.schedule_of_rates))) tool.Cost.load_schedule_of_rates_tree(schedule_of_rates=tool.Ifc.get().by_id(int(self.schedule_of_rates)))
def get_quantity_types(self, context): def get_quantity_types(self: "BIMCostProperties", context: bpy.types.Context) -> tool.Blender.BLENDER_ENUM_ITEMS:
if not CostSchedulesData.is_loaded: if not CostSchedulesData.is_loaded:
CostSchedulesData.load() CostSchedulesData.load()
return CostSchedulesData.data["quantity_types"] return CostSchedulesData.data["quantity_types"]
def get_product_quantity_names(self, context): def get_product_quantity_names(
self: "BIMCostProperties", context: bpy.types.Context
) -> tool.Blender.BLENDER_ENUM_ITEMS:
if not CostItemQuantitiesData.is_loaded: if not CostItemQuantitiesData.is_loaded:
CostItemQuantitiesData.load() CostItemQuantitiesData.load()
return CostItemQuantitiesData.data["product_quantity_names"] return CostItemQuantitiesData.data["product_quantity_names"]
def get_process_quantity_names(self, context): def get_process_quantity_names(
self: "BIMCostProperties", context: bpy.types.Context
) -> tool.Blender.BLENDER_ENUM_ITEMS:
if not CostItemQuantitiesData.is_loaded: if not CostItemQuantitiesData.is_loaded:
CostItemQuantitiesData.load() CostItemQuantitiesData.load()
return CostItemQuantitiesData.data["process_quantity_names"] return CostItemQuantitiesData.data["process_quantity_names"]
def get_resource_quantity_names(self, context): def get_resource_quantity_names(
self: "BIMCostProperties", context: bpy.types.Context
) -> tool.Blender.BLENDER_ENUM_ITEMS:
if not CostItemQuantitiesData.is_loaded: if not CostItemQuantitiesData.is_loaded:
CostItemQuantitiesData.load() CostItemQuantitiesData.load()
return CostItemQuantitiesData.data["resource_quantity_names"] return CostItemQuantitiesData.data["resource_quantity_names"]
def update_active_cost_item_index(self, context): def update_active_cost_item_index(self: "BIMCostProperties", context: bpy.types.Context) -> None:
schedule = tool.Ifc.get().by_id(self.active_cost_schedule_id) schedule = tool.Ifc.get().by_id(self.active_cost_schedule_id)
if schedule.PredefinedType == "SCHEDULEOFRATES": if schedule.PredefinedType == "SCHEDULEOFRATES":
tool.Cost.load_cost_item_types() tool.Cost.load_cost_item_types()
@@ -84,11 +91,11 @@ def update_cost_item_identification(self: "CostItem", context: bpy.types.Context
props = tool.Cost.get_cost_props() props = tool.Cost.get_cost_props()
if not props.is_cost_update_enabled or self.identification == "XXX": if not props.is_cost_update_enabled or self.identification == "XXX":
return return
self.file = tool.Ifc.get() ifc_file = tool.Ifc.get()
ifcopenshell.api.run( ifcopenshell.api.cost.edit_cost_item(
"cost.edit_cost_item", ifc_file,
self.file, cost_item=ifc_file.by_id(self.ifc_definition_id),
**{"cost_item": self.file.by_id(self.ifc_definition_id), "attributes": {"Identification": self.identification}}, attributes={"Identification": self.identification},
) )
if props.active_cost_item_id == self.ifc_definition_id: if props.active_cost_item_id == self.ifc_definition_id:
attribute = props.cost_item_attributes["Identification"] attribute = props.cost_item_attributes["Identification"]
@@ -99,11 +106,11 @@ def update_cost_item_name(self: "CostItem", context: bpy.types.Context) -> None:
props = tool.Cost.get_cost_props() props = tool.Cost.get_cost_props()
if not props.is_cost_update_enabled or self.name == "Unnamed": if not props.is_cost_update_enabled or self.name == "Unnamed":
return return
self.file = tool.Ifc.get() ifc_file = tool.Ifc.get()
ifcopenshell.api.run( ifcopenshell.api.cost.edit_cost_item(
"cost.edit_cost_item", ifc_file,
self.file, cost_item=ifc_file.by_id(self.ifc_definition_id),
**{"cost_item": self.file.by_id(self.ifc_definition_id), "attributes": {"Name": self.name}}, attributes={"Name": self.name},
) )
if props.active_cost_item_id == self.ifc_definition_id: if props.active_cost_item_id == self.ifc_definition_id:
attribute = props.cost_item_attributes["Name"] attribute = props.cost_item_attributes["Name"]
@@ -102,7 +102,7 @@ class RemoveProfileDef(bpy.types.Operator, tool.Ifc.Operator):
self.report({"ERROR"}, error_msg) self.report({"ERROR"}, error_msg)
return {"CANCELLED"} return {"CANCELLED"}
ifcopenshell.api.run("profile.remove_profile", ifc_file, profile=profile) ifcopenshell.api.profile.remove_profile(ifc_file, profile=profile)
bpy.ops.bim.load_profiles() bpy.ops.bim.load_profiles()
# preserve selected index if possible # preserve selected index if possible
@@ -145,7 +145,7 @@ class EditProfile(bpy.types.Operator, tool.Ifc.Operator):
props = tool.Profile.get_profile_props() props = tool.Profile.get_profile_props()
attributes = bonsai.bim.helper.export_attributes(props.profile_attributes) attributes = bonsai.bim.helper.export_attributes(props.profile_attributes)
profile = tool.Ifc.get().by_id(props.active_profile_id) profile = tool.Ifc.get().by_id(props.active_profile_id)
ifcopenshell.api.run("profile.edit_profile", tool.Ifc.get(), profile=profile, attributes=attributes) ifcopenshell.api.profile.edit_profile(tool.Ifc.get(), profile=profile, attributes=attributes)
model_profile.DumbProfileRegenerator().regenerate_from_profile_def(profile) model_profile.DumbProfileRegenerator().regenerate_from_profile_def(profile)
bpy.ops.bim.load_profiles() bpy.ops.bim.load_profiles()
generate_thumbnail_for_active_profile() generate_thumbnail_for_active_profile()
@@ -179,6 +179,7 @@ class AddProfileDef(bpy.types.Operator, tool.Ifc.Operator):
points = [(0, 0), (0.1, 0), (0.1, 0.1), (0, 0.1), (0, 0)] points = [(0, 0), (0.1, 0), (0.1, 0.1), (0, 0.1), (0, 0)]
profile = ifcopenshell.api.profile.add_arbitrary_profile(tool.Ifc.get(), profile=points) profile = ifcopenshell.api.profile.add_arbitrary_profile(tool.Ifc.get(), profile=points)
else: else:
assert obj and isinstance(obj.data, bpy.types.Mesh)
if "inner_curves" not in indices: if "inner_curves" not in indices:
points = [(obj.data.vertices[i].co.x, obj.data.vertices[i].co.y) for i in indices["profile"]] points = [(obj.data.vertices[i].co.x, obj.data.vertices[i].co.y) for i in indices["profile"]]
points.append(points[0]) points.append(points[0])
@@ -199,7 +200,7 @@ class AddProfileDef(bpy.types.Operator, tool.Ifc.Operator):
) )
else: else:
profile = ifcopenshell.api.run("profile.add_parameterized_profile", tool.Ifc.get(), ifc_class=profile_class) profile = ifcopenshell.api.profile.add_parameterized_profile(tool.Ifc.get(), ifc_class=profile_class)
tool.Profile.set_default_profile_attrs(profile) tool.Profile.set_default_profile_attrs(profile)
profile.ProfileName = "New Profile" profile.ProfileName = "New Profile"
bpy.ops.bim.load_profiles() bpy.ops.bim.load_profiles()
@@ -93,11 +93,14 @@ class ReassignClass(bpy.types.Operator, tool.Ifc.Operator):
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
obj: bpy.props.StringProperty() obj: bpy.props.StringProperty()
if TYPE_CHECKING:
obj: str
def _execute(self, context): def _execute(self, context):
if self.obj: if self.obj:
objects = [bpy.data.objects.get(self.obj)] objects = [bpy.data.objects[self.obj]]
else: else:
objects = set(context.selected_objects + [context.active_object]) objects = tool.Blender.get_selected_objects()
self.file = tool.Ifc.get() self.file = tool.Ifc.get()
root_props = tool.Root.get_root_props() root_props = tool.Root.get_root_props()
ifc_product = root_props.ifc_product ifc_product = root_props.ifc_product
+91 -69
View File
@@ -26,32 +26,34 @@ if TYPE_CHECKING:
import bonsai.tool as tool import bonsai.tool as tool
def add_cost_schedule(ifc: tool.Ifc, name: str, predefined_type: str) -> None: def add_cost_schedule(ifc: type[tool.Ifc], name: str, predefined_type: str) -> None:
ifc.run("cost.add_cost_schedule", name=name, predefined_type=predefined_type) ifc.run("cost.add_cost_schedule", name=name, predefined_type=predefined_type)
def edit_cost_schedule(ifc: tool.Ifc, cost: tool.Cost, cost_schedule: ifcopenshell.entity_instance) -> None: def edit_cost_schedule(ifc: type[tool.Ifc], cost: type[tool.Cost], cost_schedule: ifcopenshell.entity_instance) -> None:
attributes = cost.get_cost_schedule_attributes() attributes = cost.get_cost_schedule_attributes()
ifc.run("cost.edit_cost_schedule", cost_schedule=cost_schedule, attributes=attributes) ifc.run("cost.edit_cost_schedule", cost_schedule=cost_schedule, attributes=attributes)
cost.disable_editing_cost_schedule() cost.disable_editing_cost_schedule()
def disable_editing_cost_schedule(cost: tool.Cost) -> None: def disable_editing_cost_schedule(cost: type[tool.Cost]) -> None:
cost.disable_editing_cost_schedule() cost.disable_editing_cost_schedule()
def remove_cost_schedule(ifc: tool.Ifc, cost: tool.Cost, cost_schedule: ifcopenshell.entity_instance) -> None: def remove_cost_schedule(
ifc: type[tool.Ifc], cost: type[tool.Cost], cost_schedule: ifcopenshell.entity_instance
) -> None:
cost.remove_stored_schedule_columns(cost_schedule) cost.remove_stored_schedule_columns(cost_schedule)
cost.remove_csv_filepath(cost_schedule) cost.remove_csv_filepath(cost_schedule)
ifc.run("cost.remove_cost_schedule", cost_schedule=cost_schedule) ifc.run("cost.remove_cost_schedule", cost_schedule=cost_schedule)
def enable_editing_cost_schedule_attributes(cost: tool.Cost, cost_schedule: ifcopenshell.entity_instance) -> None: def enable_editing_cost_schedule_attributes(cost: type[tool.Cost], cost_schedule: ifcopenshell.entity_instance) -> None:
cost.load_cost_schedule_attributes(cost_schedule) cost.load_cost_schedule_attributes(cost_schedule)
cost.enable_editing_cost_schedule_attributes(cost_schedule) cost.enable_editing_cost_schedule_attributes(cost_schedule)
def enable_editing_cost_items(cost: tool.Cost, cost_schedule: ifcopenshell.entity_instance) -> None: def enable_editing_cost_items(cost: type[tool.Cost], cost_schedule: ifcopenshell.entity_instance) -> None:
cost.enable_editing_cost_items(cost_schedule) cost.enable_editing_cost_items(cost_schedule)
cost.load_active_schedule_columns() cost.load_active_schedule_columns()
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
@@ -60,55 +62,57 @@ def enable_editing_cost_items(cost: tool.Cost, cost_schedule: ifcopenshell.entit
cost.play_sound() cost.play_sound()
def add_summary_cost_item(ifc: tool.Ifc, cost: tool.Cost, cost_schedule: ifcopenshell.entity_instance) -> None: def add_summary_cost_item(
ifc: type[tool.Ifc], cost: type[tool.Cost], cost_schedule: ifcopenshell.entity_instance
) -> None:
ifc.run("cost.add_cost_item", cost_schedule=cost_schedule) ifc.run("cost.add_cost_item", cost_schedule=cost_schedule)
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
# cost.play_sound() # cost.play_sound()
def add_cost_item(ifc: tool.Ifc, cost: tool.Cost, cost_item: ifcopenshell.entity_instance) -> None: def add_cost_item(ifc: type[tool.Ifc], cost: type[tool.Cost], cost_item: ifcopenshell.entity_instance) -> None:
ifc.run("cost.add_cost_item", cost_item=cost_item) ifc.run("cost.add_cost_item", cost_item=cost_item)
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
# cost.enable_editing_cost_schedule_attributes(cost_schedule) # cost.enable_editing_cost_schedule_attributes(cost_schedule)
def expand_cost_item(cost: tool.Cost, cost_item: ifcopenshell.entity_instance) -> None: def expand_cost_item(cost: type[tool.Cost], cost_item: ifcopenshell.entity_instance) -> None:
cost.expand_cost_item(cost_item) cost.expand_cost_item(cost_item)
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
def expand_cost_items(cost: tool.Cost) -> None: def expand_cost_items(cost: type[tool.Cost]) -> None:
cost.expand_cost_items() cost.expand_cost_items()
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
def contract_cost_item(cost: tool.Cost, cost_item: ifcopenshell.entity_instance) -> None: def contract_cost_item(cost: type[tool.Cost], cost_item: ifcopenshell.entity_instance) -> None:
cost.contract_cost_item(cost_item) cost.contract_cost_item(cost_item)
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
def contract_cost_items(cost: tool.Cost) -> None: def contract_cost_items(cost: type[tool.Cost]) -> None:
cost.contract_cost_items() cost.contract_cost_items()
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
def remove_cost_item(ifc: tool.Ifc, cost: tool.Cost, cost_item_id: int) -> None: def remove_cost_item(ifc: type[tool.Ifc], cost: type[tool.Cost], cost_item_id: int) -> None:
cost_item = ifc.get().by_id(cost_item_id) cost_item = ifc.get().by_id(cost_item_id)
ifc.run("cost.remove_cost_item", cost_item=cost_item) ifc.run("cost.remove_cost_item", cost_item=cost_item)
cost.clean_up_cost_item_tree(cost_item_id) cost.clean_up_cost_item_tree(cost_item_id)
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
def enable_editing_cost_item_attributes(cost: tool.Cost, cost_item: ifcopenshell.entity_instance) -> None: def enable_editing_cost_item_attributes(cost: type[tool.Cost], cost_item: ifcopenshell.entity_instance) -> None:
cost.enable_editing_cost_item_attributes(cost_item) cost.enable_editing_cost_item_attributes(cost_item)
cost.load_cost_item_attributes(cost_item) cost.load_cost_item_attributes(cost_item)
def disable_editing_cost_item(cost: tool.Cost) -> None: def disable_editing_cost_item(cost: type[tool.Cost]) -> None:
cost.disable_editing_cost_item() cost.disable_editing_cost_item()
def edit_cost_item(ifc: tool.Ifc, cost: tool.Cost) -> None: def edit_cost_item(ifc: type[tool.Ifc], cost: type[tool.Cost]) -> None:
attributes = cost.get_cost_item_attributes() attributes = cost.get_cost_item_attributes()
ifc.run("cost.edit_cost_item", cost_item=cost.get_active_cost_item(), attributes=attributes) ifc.run("cost.edit_cost_item", cost_item=cost.get_active_cost_item(), attributes=attributes)
cost.disable_editing_cost_item() cost.disable_editing_cost_item()
@@ -116,7 +120,11 @@ def edit_cost_item(ifc: tool.Ifc, cost: tool.Cost) -> None:
def assign_cost_item_type( def assign_cost_item_type(
ifc: tool.Ifc, cost: tool.Cost, spatial: tool.Spatial, cost_item: ifcopenshell.entity_instance, prop_name ifc: type[tool.Ifc],
cost: type[tool.Cost],
spatial: type[tool.Spatial],
cost_item: ifcopenshell.entity_instance,
prop_name,
) -> list[ifcopenshell.entity_instance]: ) -> list[ifcopenshell.entity_instance]:
""" """
Returns: Returns:
@@ -132,9 +140,9 @@ def assign_cost_item_type(
def unassign_cost_item_type( def unassign_cost_item_type(
ifc: tool.Ifc, ifc: type[tool.Ifc],
cost: tool.Cost, cost: type[tool.Cost],
spatial: tool.Spatial, spatial: type[tool.Spatial],
cost_item: ifcopenshell.entity_instance, cost_item: ifcopenshell.entity_instance,
product_types: Optional[list[ifcopenshell.entity_instance]] = None, product_types: Optional[list[ifcopenshell.entity_instance]] = None,
) -> list[ifcopenshell.entity_instance]: ) -> list[ifcopenshell.entity_instance]:
@@ -152,16 +160,16 @@ def unassign_cost_item_type(
return product_types return product_types
def load_cost_item_types(cost: tool.Cost) -> None: def load_cost_item_types(cost: type[tool.Cost]) -> None:
cost_item = cost.get_active_cost_item() cost_item = cost.get_active_cost_item()
cost.load_cost_item_types(cost_item) cost.load_cost_item_types(cost_item)
def assign_cost_item_quantity( def assign_cost_item_quantity(
ifc: tool.Ifc, ifc: type[tool.Ifc],
cost: tool.Cost, cost: type[tool.Cost],
cost_item: ifcopenshell.entity_instance, cost_item: ifcopenshell.entity_instance,
related_object_type: tool.Cost.RELATED_OBJECT_TYPE, related_object_type: type[tool.Cost].RELATED_OBJECT_TYPE,
prop_name: str, prop_name: str,
) -> bool: ) -> bool:
products = cost.get_products(related_object_type) products = cost.get_products(related_object_type)
@@ -173,27 +181,30 @@ def assign_cost_item_quantity(
return False return False
def load_cost_item_quantities(cost: tool.Cost) -> None: def load_cost_item_quantities(cost: type[tool.Cost]) -> None:
cost.load_cost_item_quantities() cost.load_cost_item_quantities()
def load_cost_item_element_quantities(cost: tool.Cost) -> None: def load_cost_item_element_quantities(cost: type[tool.Cost]) -> None:
cost_item = cost.get_highlighted_cost_item() cost_item = cost.get_highlighted_cost_item()
cost.load_cost_item_quantity_assignments(cost_item, related_object_type="PRODUCT") cost.load_cost_item_quantity_assignments(cost_item, related_object_type="PRODUCT")
def load_cost_item_task_quantities(cost: tool.Cost) -> None: def load_cost_item_task_quantities(cost: type[tool.Cost]) -> None:
cost_item = cost.get_highlighted_cost_item() cost_item = cost.get_highlighted_cost_item()
cost.load_cost_item_quantity_assignments(cost_item, related_object_type="PROCESS") cost.load_cost_item_quantity_assignments(cost_item, related_object_type="PROCESS")
def load_cost_item_resource_quantities(cost: tool.Cost) -> None: def load_cost_item_resource_quantities(cost: type[tool.Cost]) -> None:
cost_item = cost.get_highlighted_cost_item() cost_item = cost.get_highlighted_cost_item()
cost.load_cost_item_quantity_assignments(cost_item, related_object_type="RESOURCE") cost.load_cost_item_quantity_assignments(cost_item, related_object_type="RESOURCE")
def assign_cost_value( def assign_cost_value(
ifc: tool.Ifc, cost: tool.Cost, cost_item: ifcopenshell.entity_instance, cost_rate: ifcopenshell.entity_instance ifc: type[tool.Ifc],
cost: type[tool.Cost],
cost_item: ifcopenshell.entity_instance,
cost_rate: ifcopenshell.entity_instance,
) -> None: ) -> None:
ifc.run("cost.assign_cost_value", cost_item=cost_item, cost_rate=cost_rate) ifc.run("cost.assign_cost_value", cost_item=cost_item, cost_rate=cost_rate)
existing_cost_rate = cost.get_assigned_rate_cost_item(cost_item) existing_cost_rate = cost.get_assigned_rate_cost_item(cost_item)
@@ -204,13 +215,13 @@ def assign_cost_value(
ifc.run("control.assign_control", relating_control=cost_rate, related_object=cost_item) ifc.run("control.assign_control", relating_control=cost_rate, related_object=cost_item)
def load_schedule_of_rates(cost: tool.Cost, schedule_of_rates: ifcopenshell.entity_instance) -> None: def load_schedule_of_rates(cost: type[tool.Cost], schedule_of_rates: ifcopenshell.entity_instance) -> None:
cost.load_schedule_of_rates_tree(schedule_of_rates) cost.load_schedule_of_rates_tree(schedule_of_rates)
def unassign_cost_item_quantity( def unassign_cost_item_quantity(
ifc: tool.Ifc, ifc: type[tool.Ifc],
cost: tool.Cost, cost: type[tool.Cost],
cost_item: ifcopenshell.entity_instance, cost_item: ifcopenshell.entity_instance,
products: list[ifcopenshell.entity_instance], products: list[ifcopenshell.entity_instance],
) -> None: ) -> None:
@@ -218,34 +229,36 @@ def unassign_cost_item_quantity(
cost.load_cost_item_quantities() cost.load_cost_item_quantities()
def enable_editing_cost_item_quantities(cost: tool.Cost, cost_item: ifcopenshell.entity_instance) -> None: def enable_editing_cost_item_quantities(cost: type[tool.Cost], cost_item: ifcopenshell.entity_instance) -> None:
cost.enable_editing_cost_item_quantities(cost_item) cost.enable_editing_cost_item_quantities(cost_item)
def enable_editing_cost_item_values(cost: tool.Cost, cost_item: ifcopenshell.entity_instance) -> None: def enable_editing_cost_item_values(cost: type[tool.Cost], cost_item: ifcopenshell.entity_instance) -> None:
cost.enable_editing_cost_item_values(cost_item) cost.enable_editing_cost_item_values(cost_item)
def add_cost_item_quantity(ifc: tool.Ifc, cost_item: ifcopenshell.entity_instance, ifc_class: str) -> None: def add_cost_item_quantity(ifc: type[tool.Ifc], cost_item: ifcopenshell.entity_instance, ifc_class: str) -> None:
ifc.run("cost.add_cost_item_quantity", cost_item=cost_item, ifc_class=ifc_class) ifc.run("cost.add_cost_item_quantity", cost_item=cost_item, ifc_class=ifc_class)
def remove_cost_item_quantity( def remove_cost_item_quantity(
ifc: tool.Ifc, cost_item: ifcopenshell.entity_instance, physical_quantity: ifcopenshell.entity_instance ifc: type[tool.Ifc], cost_item: ifcopenshell.entity_instance, physical_quantity: ifcopenshell.entity_instance
) -> None: ) -> None:
ifc.run("cost.remove_cost_item_quantity", cost_item=cost_item, physical_quantity=physical_quantity) ifc.run("cost.remove_cost_item_quantity", cost_item=cost_item, physical_quantity=physical_quantity)
def enable_editing_cost_item_quantity(cost: tool.Cost, physical_quantity: ifcopenshell.entity_instance) -> None: def enable_editing_cost_item_quantity(cost: type[tool.Cost], physical_quantity: ifcopenshell.entity_instance) -> None:
cost.load_cost_item_quantity_attributes(physical_quantity) cost.load_cost_item_quantity_attributes(physical_quantity)
cost.enable_editing_cost_item_quantity(physical_quantity) cost.enable_editing_cost_item_quantity(physical_quantity)
def disable_editing_cost_item_quantity(cost: tool.Cost) -> None: def disable_editing_cost_item_quantity(cost: type[tool.Cost]) -> None:
cost.disable_editing_cost_item_quantity() cost.disable_editing_cost_item_quantity()
def edit_cost_item_quantity(ifc: tool.Ifc, cost: tool.Cost, physical_quantity: ifcopenshell.entity_instance) -> None: def edit_cost_item_quantity(
ifc: type[tool.Ifc], cost: type[tool.Cost], physical_quantity: ifcopenshell.entity_instance
) -> None:
attributes = cost.get_cost_item_quantity_attributes() attributes = cost.get_cost_item_quantity_attributes()
ifc.run("cost.edit_cost_item_quantity", physical_quantity=physical_quantity, attributes=attributes) ifc.run("cost.edit_cost_item_quantity", physical_quantity=physical_quantity, attributes=attributes)
cost.disable_editing_cost_item_quantity() cost.disable_editing_cost_item_quantity()
@@ -253,8 +266,8 @@ def edit_cost_item_quantity(ifc: tool.Ifc, cost: tool.Cost, physical_quantity: i
def add_cost_value( def add_cost_value(
ifc: tool.Ifc, ifc: type[tool.Ifc],
cost: tool.Cost, cost: type[tool.Cost],
parent: ifcopenshell.entity_instance, parent: ifcopenshell.entity_instance,
cost_type: Literal["FIXED", "SUM", "CATEGORY"], cost_type: Literal["FIXED", "SUM", "CATEGORY"],
cost_category: Optional[str] = None, cost_category: Optional[str] = None,
@@ -268,32 +281,34 @@ def add_cost_value(
def remove_cost_value( def remove_cost_value(
ifc: tool.Ifc, parent: ifcopenshell.entity_instance, cost_value: ifcopenshell.entity_instance ifc: type[tool.Ifc], parent: ifcopenshell.entity_instance, cost_value: ifcopenshell.entity_instance
) -> None: ) -> None:
ifc.run("cost.remove_cost_value", parent=parent, cost_value=cost_value) ifc.run("cost.remove_cost_value", parent=parent, cost_value=cost_value)
def enable_editing_cost_item_value(cost: tool.Cost, cost_value: ifcopenshell.entity_instance) -> None: def enable_editing_cost_item_value(cost: type[tool.Cost], cost_value: ifcopenshell.entity_instance) -> None:
cost.load_cost_item_value_attributes(cost_value) cost.load_cost_item_value_attributes(cost_value)
cost.enable_editing_cost_item_value(cost_value) cost.enable_editing_cost_item_value(cost_value)
def disable_editing_cost_item_value(cost: tool.Cost) -> None: def disable_editing_cost_item_value(cost: type[tool.Cost]) -> None:
cost.disable_editing_cost_item_value() cost.disable_editing_cost_item_value()
def enable_editing_cost_item_value_formula(cost: tool.Cost, cost_value: ifcopenshell.entity_instance) -> None: def enable_editing_cost_item_value_formula(cost: type[tool.Cost], cost_value: ifcopenshell.entity_instance) -> None:
cost.load_cost_item_value_formula_attributes(cost_value) cost.load_cost_item_value_formula_attributes(cost_value)
cost.enable_editing_cost_item_value_formula(cost_value) cost.enable_editing_cost_item_value_formula(cost_value)
def edit_cost_item_value_formula(ifc: tool.Ifc, cost: tool.Cost, cost_value: ifcopenshell.entity_instance) -> None: def edit_cost_item_value_formula(
ifc: type[tool.Ifc], cost: type[tool.Cost], cost_value: ifcopenshell.entity_instance
) -> None:
formula = cost.get_cost_item_value_formula() formula = cost.get_cost_item_value_formula()
ifc.run("cost.edit_cost_value_formula", cost_value=cost_value, formula=formula) ifc.run("cost.edit_cost_value_formula", cost_value=cost_value, formula=formula)
cost.disable_editing_cost_item_value() cost.disable_editing_cost_item_value()
def edit_cost_value(ifc: tool.Ifc, cost: tool.Cost, cost_value: ifcopenshell.entity_instance) -> None: def edit_cost_value(ifc: type[tool.Ifc], cost: type[tool.Cost], cost_value: ifcopenshell.entity_instance) -> None:
attributes = cost.get_cost_value_attributes() attributes = cost.get_cost_value_attributes()
ifc.run("cost.edit_cost_value", cost_value=cost_value, attributes=attributes) ifc.run("cost.edit_cost_value", cost_value=cost_value, attributes=attributes)
cost.disable_editing_cost_item_value() cost.disable_editing_cost_item_value()
@@ -301,67 +316,72 @@ def edit_cost_value(ifc: tool.Ifc, cost: tool.Cost, cost_value: ifcopenshell.ent
def copy_cost_item_values( def copy_cost_item_values(
ifc: tool.Ifc, cost: tool.Cost, source: ifcopenshell.entity_instance, destination: ifcopenshell.entity_instance ifc: type[tool.Ifc],
cost: type[tool.Cost],
source: ifcopenshell.entity_instance,
destination: ifcopenshell.entity_instance,
) -> None: ) -> None:
ifc.run("cost.copy_cost_item_values", source=source, destination=destination) ifc.run("cost.copy_cost_item_values", source=source, destination=destination)
def select_cost_item_products(cost: tool.Cost, spatial: tool.Spatial, cost_item: ifcopenshell.entity_instance) -> None: def select_cost_item_products(
cost: type[tool.Cost], spatial: type[tool.Spatial], cost_item: ifcopenshell.entity_instance
) -> None:
is_deep = cost.show_nested_cost_item_elements() is_deep = cost.show_nested_cost_item_elements()
products = cost.get_cost_item_products(cost_item, is_deep) products = cost.get_cost_item_products(cost_item, is_deep)
spatial.select_products(products) spatial.select_products(products)
def select_cost_schedule_products( def select_cost_schedule_products(
cost: tool.Cost, spatial: tool.Spatial, cost_schedule: ifcopenshell.entity_instance cost: type[tool.Cost], spatial: type[tool.Spatial], cost_schedule: ifcopenshell.entity_instance
) -> None: ) -> None:
products = cost.get_cost_schedule_products(cost_schedule) products = cost.get_cost_schedule_products(cost_schedule)
spatial.select_products(products) spatial.select_products(products)
def import_cost_schedule_csv( def import_cost_schedule_csv(
cost: tool.Cost, file_path: str, is_schedule_of_rates: bool cost: type[tool.Cost], file_path: str, is_schedule_of_rates: bool
) -> ifcopenshell.entity_instance: ) -> ifcopenshell.entity_instance:
cost_schedule = cost.import_cost_schedule_csv(file_path, is_schedule_of_rates) cost_schedule = cost.import_cost_schedule_csv(file_path, is_schedule_of_rates)
return cost_schedule return cost_schedule
def add_csv_filepath(cost: tool.Cost, file_path: str, is_schedule_of_rates: bool, cost_schedule) -> None: def add_csv_filepath(cost: type[tool.Cost], file_path: str, is_schedule_of_rates: bool, cost_schedule) -> None:
cost.add_csv_filepath(file_path, is_schedule_of_rates, cost_schedule) cost.add_csv_filepath(file_path, is_schedule_of_rates, cost_schedule)
def remove_csv_filepath(cost: tool.Cost, cost_schedule) -> None: def remove_csv_filepath(cost: type[tool.Cost], cost_schedule) -> None:
cost.remove_csv_filepath(cost_schedule) cost.remove_csv_filepath(cost_schedule)
def refresh_cost_schedule_csv(ifc: tool.Ifc, cost: tool.Cost) -> None: def refresh_cost_schedule_csv(ifc: type[tool.Ifc], cost: type[tool.Cost]) -> None:
cost.delete_all_cost_items() cost.delete_all_cost_items()
cost.refresh_cost_schedule_csv() cost.refresh_cost_schedule_csv()
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
def add_cost_column(cost: tool.Cost, name: str) -> None: def add_cost_column(cost: type[tool.Cost], name: str) -> None:
cost.add_cost_column(name) cost.add_cost_column(name)
def remove_cost_column(cost: tool.Cost, name: str) -> None: def remove_cost_column(cost: type[tool.Cost], name: str) -> None:
cost.remove_cost_column(name) cost.remove_cost_column(name)
def expand_cost_item_rate(cost: tool.Cost, cost_item: ifcopenshell.entity_instance) -> None: def expand_cost_item_rate(cost: type[tool.Cost], cost_item: int) -> None:
cost.expand_cost_item_rate(cost_item) cost.expand_cost_item_rate(cost_item)
def contract_cost_item_rate(cost: tool.Cost, cost_item: ifcopenshell.entity_instance) -> None: def contract_cost_item_rate(cost: type[tool.Cost], cost_item: int) -> None:
cost.contract_cost_item_rate(cost_item) cost.contract_cost_item_rate(cost_item)
def calculate_cost_item_resource_value(ifc: tool.Ifc, cost_item: ifcopenshell.entity_instance) -> None: def calculate_cost_item_resource_value(ifc: type[tool.Ifc], cost_item: ifcopenshell.entity_instance) -> None:
ifc.run("cost.calculate_cost_item_resource_value", cost_item=cost_item) ifc.run("cost.calculate_cost_item_resource_value", cost_item=cost_item)
def export_cost_schedules( def export_cost_schedules(
cost: tool.Cost, cost: type[tool.Cost],
dirpath: str, dirpath: str,
format: Literal["CSV", "ODS", "XLSX"], format: Literal["CSV", "ODS", "XLSX"],
cost_schedule: Union[ifcopenshell.entity_instance, None] = None, cost_schedule: Union[ifcopenshell.entity_instance, None] = None,
@@ -371,8 +391,8 @@ def export_cost_schedules(
def clear_cost_item_assignments( def clear_cost_item_assignments(
ifc: tool.Ifc, ifc: type[tool.Ifc],
cost: tool.Cost, cost: type[tool.Cost],
cost_item: ifcopenshell.entity_instance, cost_item: ifcopenshell.entity_instance,
related_object_type: ifcopenshell.util.cost.FILTER_BY_TYPE, related_object_type: ifcopenshell.util.cost.FILTER_BY_TYPE,
) -> None: ) -> None:
@@ -383,7 +403,7 @@ def clear_cost_item_assignments(
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
def select_unassigned_products(ifc: tool.Ifc, cost: tool.Cost, spatial: tool.Spatial) -> None: def select_unassigned_products(ifc: type[tool.Ifc], cost: type[tool.Cost], spatial: type[tool.Spatial]) -> None:
spatial.deselect_objects() spatial.deselect_objects()
products = ifc.get().by_type("IfcElement") products = ifc.get().by_type("IfcElement")
cost_schedule = cost.get_active_cost_schedule() cost_schedule = cost.get_active_cost_schedule()
@@ -391,12 +411,12 @@ def select_unassigned_products(ifc: tool.Ifc, cost: tool.Cost, spatial: tool.Spa
spatial.select_products(selection) spatial.select_products(selection)
def load_product_cost_items(cost: tool.Cost, product: ifcopenshell.entity_instance) -> None: def load_product_cost_items(cost: type[tool.Cost], product: ifcopenshell.entity_instance) -> None:
cost.load_product_cost_items(product) cost.load_product_cost_items(product)
def highlight_product_cost_item( def highlight_product_cost_item(
spatial: tool.Spatial, cost: tool.Cost, cost_item: ifcopenshell.entity_instance spatial: type[tool.Spatial], cost: type[tool.Cost], cost_item: ifcopenshell.entity_instance
) -> Union[str, None]: ) -> Union[str, None]:
cost_schedule = cost.get_cost_schedule(cost_item) cost_schedule = cost.get_cost_schedule(cost_item)
is_cost_schedule_active = cost.is_cost_schedule_active(cost_schedule) is_cost_schedule_active = cost.is_cost_schedule_active(cost_schedule)
@@ -406,7 +426,7 @@ def highlight_product_cost_item(
return "Cost schedule is not active" return "Cost schedule is not active"
def change_parent_cost_item(ifc: tool.Ifc, cost: tool.Cost, new_parent) -> Union[str, None]: def change_parent_cost_item(ifc: type[tool.Ifc], cost: type[tool.Cost], new_parent) -> Union[str, None]:
cost_item = cost.get_active_cost_item() cost_item = cost.get_active_cost_item()
if cost_item and cost.is_root_cost_item(cost_item): if cost_item and cost.is_root_cost_item(cost_item):
return "Cannot change root cost item" return "Cannot change root cost item"
@@ -416,7 +436,7 @@ def change_parent_cost_item(ifc: tool.Ifc, cost: tool.Cost, new_parent) -> Union
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
def copy_cost_item(ifc: tool.Ifc, cost: tool.Cost) -> None: def copy_cost_item(ifc: type[tool.Ifc], cost: type[tool.Cost]) -> None:
cost_item = cost.get_highlighted_cost_item() cost_item = cost.get_highlighted_cost_item()
if cost_item: if cost_item:
cost_item = ifc.run("cost.copy_cost_item", cost_item=cost_item) cost_item = ifc.run("cost.copy_cost_item", cost_item=cost_item)
@@ -424,7 +444,7 @@ def copy_cost_item(ifc: tool.Ifc, cost: tool.Cost) -> None:
cost.load_cost_schedule_tree() cost.load_cost_schedule_tree()
def add_currency(ifc: tool.Ifc, cost: tool.Cost) -> ifcopenshell.entity_instance: def add_currency(ifc: type[tool.Ifc], cost: type[tool.Cost]) -> ifcopenshell.entity_instance:
unit = ifc.run("unit.add_monetary_unit") unit = ifc.run("unit.add_monetary_unit")
attributes = cost.get_currency_attributes() attributes = cost.get_currency_attributes()
ifc.run("unit.edit_monetary_unit", unit=unit, attributes=attributes) ifc.run("unit.edit_monetary_unit", unit=unit, attributes=attributes)
@@ -432,5 +452,7 @@ def add_currency(ifc: tool.Ifc, cost: tool.Cost) -> ifcopenshell.entity_instance
return unit return unit
def generate_cost_schedule_browser(cost: tool.Cost, cost_schedule: ifcopenshell.entity_instance) -> bpy.types.Panel: def generate_cost_schedule_browser(
cost: type[tool.Cost], cost_schedule: ifcopenshell.entity_instance
) -> bpy.types.Panel:
return cost.generate_cost_schedule_browser(cost_schedule) return cost.generate_cost_schedule_browser(cost_schedule)
+2 -2
View File
@@ -42,7 +42,7 @@ from mathutils import Vector
from pathlib import Path from pathlib import Path
from functools import lru_cache, cache from functools import lru_cache, cache
from bonsai.bim.ifc import IFC_CONNECTED_TYPE from bonsai.bim.ifc import IFC_CONNECTED_TYPE
from typing import Any, Optional, Union, Literal, Iterable, Callable, TypeVar, Generator, TYPE_CHECKING from typing import Any, Optional, Union, Literal, Iterable, Callable, TypeVar, Generator, TYPE_CHECKING, Sequence
from typing_extensions import assert_never from typing_extensions import assert_never
if TYPE_CHECKING: if TYPE_CHECKING:
@@ -657,7 +657,7 @@ class Blender(bonsai.core.tool.Blender):
cls, cls,
context: bpy.types.Context, context: bpy.types.Context,
active_object: Optional[bpy.types.Object] = None, active_object: Optional[bpy.types.Object] = None,
selected_objects: list[bpy.types.Object] = list(), selected_objects: Sequence[bpy.types.Object] = (),
clear_previous_selection=True, clear_previous_selection=True,
) -> None: ) -> None:
if clear_previous_selection: if clear_previous_selection:
+11 -6
View File
@@ -38,6 +38,11 @@ if TYPE_CHECKING:
class Cost(bonsai.core.tool.Cost): class Cost(bonsai.core.tool.Cost):
RELATED_OBJECT_TYPE = Literal["PRODUCT", "PROCESS", "RESOURCE"] RELATED_OBJECT_TYPE = Literal["PRODUCT", "PROCESS", "RESOURCE"]
contracted_cost_items: list[int]
"""List of contracted cost item ids."""
contracted_cost_item_rates: list[int]
"""List of contracted const item rates ids."""
@classmethod @classmethod
def get_cost_props(cls) -> BIMCostProperties: def get_cost_props(cls) -> BIMCostProperties:
@@ -662,18 +667,18 @@ class Cost(bonsai.core.tool.Cost):
return tool.Ifc.get().by_id(int(schedule_id)) return tool.Ifc.get().by_id(int(schedule_id))
@classmethod @classmethod
def expand_cost_item_rate(cls, cost_item: ifcopenshell.entity_instance) -> None: def expand_cost_item_rate(cls, cost_item_id: int) -> None:
props = cls.get_cost_props() props = cls.get_cost_props()
contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates) contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates)
contracted_cost_item_rates.remove(cost_item) contracted_cost_item_rates.remove(cost_item_id)
props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates) props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates)
cls.load_schedule_of_rates_tree(schedule_of_rates=tool.Ifc.get().by_id(int(props.schedule_of_rates))) cls.load_schedule_of_rates_tree(schedule_of_rates=tool.Ifc.get().by_id(int(props.schedule_of_rates)))
@classmethod @classmethod
def contract_cost_item_rate(cls, cost_item: ifcopenshell.entity_instance) -> None: def contract_cost_item_rate(cls, cost_item_id: int) -> None:
props = cls.get_cost_props() props = cls.get_cost_props()
contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates) contracted_cost_item_rates = json.loads(props.contracted_cost_item_rates)
contracted_cost_item_rates.append(cost_item) contracted_cost_item_rates.append(cost_item_id)
props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates) props.contracted_cost_item_rates = json.dumps(contracted_cost_item_rates)
cls.load_schedule_of_rates_tree(schedule_of_rates=tool.Ifc.get().by_id(int(props.schedule_of_rates))) cls.load_schedule_of_rates_tree(schedule_of_rates=tool.Ifc.get().by_id(int(props.schedule_of_rates)))
@@ -807,8 +812,8 @@ class Cost(bonsai.core.tool.Cost):
@classmethod @classmethod
def highlight_cost_item(cls, cost_item: ifcopenshell.entity_instance) -> None: def highlight_cost_item(cls, cost_item: ifcopenshell.entity_instance) -> None:
def expand_ancestors(cost_item): def expand_ancestors(cost_item: ifcopenshell.entity_instance) -> None:
cls.expand_cost_item(cost_item) cls.expand_cost_item(cost_item.id())
for rel in cost_item.Nests or []: for rel in cost_item.Nests or []:
parent_cost = rel.RelatingObject if rel.RelatingObject.is_a("IfcCostItem") else None parent_cost = rel.RelatingObject if rel.RelatingObject.is_a("IfcCostItem") else None
if parent_cost: if parent_cost:
+3 -1
View File
@@ -221,7 +221,9 @@ class TestReassignClass(NewFile):
bpy.ops.bim.add_occurrence(relating_type_id=relating_type_id) bpy.ops.bim.add_occurrence(relating_type_id=relating_type_id)
bpy.ops.bim.add_occurrence(relating_type_id=relating_type_id) bpy.ops.bim.add_occurrence(relating_type_id=relating_type_id)
slabs = [tool.Ifc.get_object(e) for e in ifc_file.by_type("IfcSlab")] slabs = [
obj for e in ifc_file.by_type("IfcSlab") if isinstance(obj := tool.Ifc.get_object(e), bpy.types.Object)
]
assert len(slabs) == 3 assert len(slabs) == 3
tool.Blender.set_objects_selection(context, slabs[0], (slabs[1],)) tool.Blender.set_objects_selection(context, slabs[0], (slabs[1],))
@@ -715,7 +715,7 @@ class declaration:
def index_in_schema(self): ... def index_in_schema(self): ...
def name(self) -> str: ... def name(self) -> str: ...
def name_uc(self): ... def name_uc(self): ...
def schema(self): ... def schema(self) -> schema_definition: ...
def type(self): ... def type(self): ...
class direction3: class direction3: