This commit is contained in:
Andrej730
2025-06-30 18:59:26 +05:00
parent e743db27f4
commit 94d2d32d18
14 changed files with 105 additions and 56 deletions
+1 -1
View File
@@ -662,7 +662,7 @@ class IfcImporter:
settings: Optional[ifcopenshell.geom.main.settings] = None, settings: Optional[ifcopenshell.geom.main.settings] = None,
) -> set[ifcopenshell.entity_instance]: ) -> set[ifcopenshell.entity_instance]:
checkpoint = time.time() checkpoint = time.time()
results = set() results: set[ifcopenshell.entity_instance] = set()
if not products: if not products:
return results return results
+1 -1
View File
@@ -35,7 +35,7 @@ from bpy.props import (
from typing import Union, TYPE_CHECKING, Literal from typing import Union, TYPE_CHECKING, Literal
def get_active_dictionary(self, context): def get_active_dictionary(self: "BIMBSDDProperties", context: object) -> tool.Blender.BLENDER_ENUM_ITEMS:
if not BSDDData.is_loaded: if not BSDDData.is_loaded:
BSDDData.load() BSDDData.load()
return BSDDData.data["active_dictionary"] return BSDDData.data["active_dictionary"]
@@ -16,6 +16,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
# pyright: reportAttributeAccessIssue=false
import bpy import bpy
from . import ui, prop, operator from . import ui, prop, operator
+10 -9
View File
@@ -36,24 +36,25 @@ class ExecuteIfcFM(bpy.types.Operator, ExportHelper):
@property @property
def filename_ext(self) -> str: def filename_ext(self) -> str:
props = bpy.context.scene.BIMFMProperties props = tool.Blender.get_fm_props()
return f".{props.format}" return f".{props.format}"
def draw(self, context): def draw(self, context):
assert self.layout
layout = self.layout layout = self.layout
props = context.scene.BIMFMProperties props = tool.Blender.get_fm_props()
layout.prop(props, "format") layout.prop(props, "format")
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
props = context.scene.BIMFMProperties props = tool.Blender.get_fm_props()
if not props.should_load_from_memory and not props.ifc_files.single_file: if not props.should_load_from_memory and not props.ifc_files.single_file:
cls.poll_message_set("Select an IFC file or use 'load from memory' if it's loaded in Bonsai.") cls.poll_message_set("Select an IFC file or use 'load from memory' if it's loaded in Bonsai.")
return False return False
return True return True
def execute(self, context): def execute(self, context):
props = context.scene.BIMFMProperties props = tool.Blender.get_fm_props()
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
filepaths = [] filepaths = []
if ifc_file and props.should_load_from_memory: if ifc_file and props.should_load_from_memory:
@@ -95,7 +96,7 @@ class SelectFMSpreadsheetFiles(bpy.types.Operator, ImportHelper):
files: bpy.props.CollectionProperty(name="File Path", type=bpy.types.OperatorFileListElement) files: bpy.props.CollectionProperty(name="File Path", type=bpy.types.OperatorFileListElement)
def execute(self, context): def execute(self, context):
props = context.scene.BIMFMProperties props = tool.Blender.get_fm_props()
props.spreadsheet_files.clear() props.spreadsheet_files.clear()
dirname = os.path.dirname(self.filepath) dirname = os.path.dirname(self.filepath)
for f in self.files: for f in self.files:
@@ -112,24 +113,24 @@ class ExecuteIfcFMFederate(bpy.types.Operator, ExportHelper):
@property @property
def filename_ext(self) -> str: def filename_ext(self) -> str:
props = bpy.context.scene.BIMFMProperties props = tool.Blender.get_fm_props()
return f".{props.format}" return f".{props.format}"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
props = context.scene.BIMFMProperties props = tool.Blender.get_fm_props()
layout.prop(props, "format") layout.prop(props, "format")
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
props = context.scene.BIMFMProperties props = tool.Blender.get_fm_props()
if not props.spreadsheet_files: if not props.spreadsheet_files:
cls.poll_message_set("No spreadsheet files selected.") cls.poll_message_set("No spreadsheet files selected.")
return False return False
return True return True
def execute(self, context): def execute(self, context):
props = context.scene.BIMFMProperties props = tool.Blender.get_fm_props()
parser = ifcfm.Parser(preset=props.engine) parser = ifcfm.Parser(preset=props.engine)
parser.federate([f.name for f in props.spreadsheet_files]) parser.federate([f.name for f in props.spreadsheet_files])
writer = ifcfm.Writer(parser) writer = ifcfm.Writer(parser)
+10 -1
View File
@@ -17,6 +17,7 @@
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
import bpy import bpy
import bonsai.tool as tool
from bonsai.bim.module.fm.data import FMData from bonsai.bim.module.fm.data import FMData
from bonsai.bim.prop import MultipleFileSelect, StrProperty from bonsai.bim.prop import MultipleFileSelect, StrProperty
from bpy.types import PropertyGroup from bpy.types import PropertyGroup
@@ -30,9 +31,10 @@ from bpy.props import (
FloatVectorProperty, FloatVectorProperty,
CollectionProperty, CollectionProperty,
) )
from typing import TYPE_CHECKING, Literal
def get_engine(self, context): def get_engine(self: "BIMFMProperties", context: object) -> tool.Blender.BLENDER_ENUM_ITEMS:
if not FMData.is_loaded: if not FMData.is_loaded:
FMData.load() FMData.load()
return FMData.data["engine"] return FMData.data["engine"]
@@ -57,3 +59,10 @@ class BIMFMProperties(PropertyGroup):
default="ods", default="ods",
options=set(), options=set(),
) )
if TYPE_CHECKING:
ifc_files: MultipleFileSelect
spreadsheet_files: bpy.types.bpy_prop_collection_idprop[StrProperty]
should_load_from_memory: bool
engine: str
format: Literal["csv", "xlsx", "ods"]
+2 -2
View File
@@ -33,11 +33,11 @@ class BIM_PT_fm(Panel):
if not FMData.is_loaded: if not FMData.is_loaded:
FMData.load() FMData.load()
assert self.layout
layout = self.layout layout = self.layout
layout.use_property_split = True layout.use_property_split = True
scene = context.scene props = tool.Blender.get_fm_props()
props = scene.BIMFMProperties
if tool.Ifc.get(): if tool.Ifc.get():
row = layout.row() row = layout.row()
@@ -16,6 +16,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>. # along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
# pyright: reportAttributeAccessIssue=false
import bpy import bpy
from . import ui, prop, operator from . import ui, prop, operator
@@ -367,9 +367,10 @@ class WorkPlansData:
@classmethod @classmethod
def active_work_plan_schedules(cls): def active_work_plan_schedules(cls):
results = [] results = []
if not bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id: props = tool.Sequence.get_work_plan_props()
if not props.active_work_plan_id:
return [] return []
for rel in tool.Ifc.get().by_id(bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id).IsDecomposedBy: for rel in tool.Ifc.get().by_id(props.active_work_plan_id).IsDecomposedBy:
for work_schedule in rel.RelatedObjects: for work_schedule in rel.RelatedObjects:
results.append({"id": work_schedule.id(), "name": work_schedule.Name or "Unnamed"}) results.append({"id": work_schedule.id(), "name": work_schedule.Name or "Unnamed"})
return results return results
@@ -140,10 +140,11 @@ class EditWorkPlan(bpy.types.Operator, tool.Ifc.Operator):
bl_label = "Edit Work Plan" bl_label = "Edit Work Plan"
def _execute(self, context): def _execute(self, context):
props = tool.Sequence.get_work_plan_props()
core.edit_work_plan( core.edit_work_plan(
tool.Ifc, tool.Ifc,
tool.Sequence, tool.Sequence,
work_plan=tool.Ifc.get().by_id(context.scene.BIMWorkPlanProperties.active_work_plan_id), work_plan=tool.Ifc.get().by_id(props.active_work_plan_id),
) )
+12 -8
View File
@@ -88,7 +88,8 @@ class BIM_PT_work_plans(Panel):
def draw(self, context): def draw(self, context):
if not WorkPlansData.is_loaded: if not WorkPlansData.is_loaded:
WorkPlansData.load() WorkPlansData.load()
self.props = context.scene.BIMWorkPlanProperties assert self.layout
self.props = tool.Sequence.get_work_plan_props()
row = self.layout.row() row = self.layout.row()
if WorkPlansData.data["total_work_plans"]: if WorkPlansData.data["total_work_plans"]:
@@ -99,7 +100,7 @@ class BIM_PT_work_plans(Panel):
for work_plan in WorkPlansData.data["work_plans"]: for work_plan in WorkPlansData.data["work_plans"]:
self.draw_work_plan_ui(work_plan) self.draw_work_plan_ui(work_plan)
def draw_work_plan_ui(self, work_plan): def draw_work_plan_ui(self, work_plan: dict[str, Any]) -> None:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text=work_plan["name"], icon="TEXT") row.label(text=work_plan["name"], icon="TEXT")
if self.props.active_work_plan_id == work_plan["id"]: if self.props.active_work_plan_id == work_plan["id"]:
@@ -121,10 +122,10 @@ class BIM_PT_work_plans(Panel):
elif self.props.editing_type == "SCHEDULES": elif self.props.editing_type == "SCHEDULES":
self.draw_work_schedule_ui() self.draw_work_schedule_ui()
def draw_editable_ui(self): def draw_editable_ui(self) -> None:
draw_attributes(self.props.work_plan_attributes, self.layout) draw_attributes(self.props.work_plan_attributes, self.layout)
def draw_work_schedule_ui(self): def draw_work_schedule_ui(self) -> None:
if WorkPlansData.data["has_work_schedules"]: if WorkPlansData.data["has_work_schedules"]:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.prop(self.props, "work_schedules", text="") row.prop(self.props, "work_schedules", text="")
@@ -177,7 +178,8 @@ class BIM_PT_work_schedules(Panel):
for work_schedule_id, work_schedule in SequenceData.data["work_schedules"].items(): for work_schedule_id, work_schedule in SequenceData.data["work_schedules"].items():
self.draw_work_schedule_ui(work_schedule_id, work_schedule) self.draw_work_schedule_ui(work_schedule_id, work_schedule)
def draw_work_schedule_ui(self, work_schedule_id, work_schedule): def draw_work_schedule_ui(self, work_schedule_id: int, work_schedule: dict[str, Any]) -> None:
assert self.layout
if work_schedule["PredefinedType"] == "BASELINE": if work_schedule["PredefinedType"] == "BASELINE":
self.draw_readonly_work_schedule_ui(work_schedule_id) self.draw_readonly_work_schedule_ui(work_schedule_id)
else: else:
@@ -250,7 +252,7 @@ class BIM_PT_work_schedules(Panel):
self.draw_column_ui() self.draw_column_ui()
self.draw_editable_task_ui(work_schedule_id) self.draw_editable_task_ui(work_schedule_id)
def draw_task_operators(self): def draw_task_operators(self) -> None:
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.alignment = "RIGHT" row.alignment = "RIGHT"
ifc_definition_id = None ifc_definition_id = None
@@ -285,9 +287,10 @@ class BIM_PT_work_schedules(Panel):
row.operator("bim.duplicate_task", text="Copy", icon="DUPLICATE").task = ifc_definition_id row.operator("bim.duplicate_task", text="Copy", icon="DUPLICATE").task = ifc_definition_id
row.operator("bim.remove_task", text="Delete", icon="X").task = ifc_definition_id row.operator("bim.remove_task", text="Delete", icon="X").task = ifc_definition_id
def draw_column_ui(self): def draw_column_ui(self) -> None:
if not self.props.should_show_column_ui: if not self.props.should_show_column_ui:
return return
assert self.layout
row = self.layout.row() row = self.layout.row()
row.operator("bim.setup_default_task_columns", text="Setup Default Columns", icon="ANCHOR_BOTTOM") row.operator("bim.setup_default_task_columns", text="Setup Default Columns", icon="ANCHOR_BOTTOM")
row.alignment = "RIGHT" row.alignment = "RIGHT"
@@ -318,7 +321,8 @@ class BIM_PT_work_schedules(Panel):
def draw_editable_work_schedule_ui(self): def draw_editable_work_schedule_ui(self):
draw_attributes(self.props.work_schedule_attributes, self.layout) draw_attributes(self.props.work_schedule_attributes, self.layout)
def draw_editable_task_ui(self, work_schedule_id): def draw_editable_task_ui(self, work_schedule_id: int) -> None:
assert self.layout
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.label(text="Task Tools") row.label(text="Task Tools")
row = self.layout.row(align=True) row = self.layout.row(align=True)
+7 -5
View File
@@ -47,7 +47,7 @@ from collections.abc import Iterable
from natsort import natsorted from natsort import natsorted
if TYPE_CHECKING: if TYPE_CHECKING:
from bonsai.bim.prop import MultipleFileSelect from bonsai.bim.prop import MultipleFileSelect, Attribute
class SetTab(bpy.types.Operator): class SetTab(bpy.types.Operator):
@@ -1343,7 +1343,7 @@ class BIM_OT_attribute_search_values(bpy.types.Operator):
collection_values: bpy.props.CollectionProperty(type=StrProperty, options={"SKIP_SAVE"}) collection_values: bpy.props.CollectionProperty(type=StrProperty, options={"SKIP_SAVE"})
@staticmethod @staticmethod
def resolve_data_path(data_path: str) -> tuple[str, object]: def resolve_data_path(data_path: str) -> tuple[str, "Attribute"]:
"""Resolve the data path of an object's attribute to get the attribute name and the object.""" """Resolve the data path of an object's attribute to get the attribute name and the object."""
path_parts = data_path.split(".") path_parts = data_path.split(".")
obj_path = ".".join(path_parts[:-1]) obj_path = ".".join(path_parts[:-1])
@@ -1361,11 +1361,12 @@ class BIM_OT_attribute_search_values(bpy.types.Operator):
for value in string_values: for value in string_values:
self.collection_values.add().name = value self.collection_values.add().name = value
assert context.window_manager
return context.window_manager.invoke_props_dialog(self) return context.window_manager.invoke_props_dialog(self)
def get_unique_attribute_values(self): def get_unique_attribute_values(self) -> list[str]:
ifc_file = tool.Ifc.get() ifc_file = tool.Ifc.get()
unique_values = set() unique_values: set[str] = set()
ifc_class = self.attribute_ifc_class ifc_class = self.attribute_ifc_class
elements = ifc_file.by_type(ifc_class, include_subtypes=True) elements = ifc_file.by_type(ifc_class, include_subtypes=True)
@@ -1379,7 +1380,8 @@ class BIM_OT_attribute_search_values(bpy.types.Operator):
return list(unique_values) return list(unique_values)
def draw(self, context): def draw(self, context) -> None:
assert self.layout
row = self.layout.row() row = self.layout.row()
row.label(text=f"Select {self.attribute_name} value:") row.label(text=f"Select {self.attribute_name} value:")
row = self.layout.row() row = self.layout.row()
+17 -11
View File
@@ -61,6 +61,7 @@ if TYPE_CHECKING:
from bonsai.bim.module.constraint.prop import BIMConstraintProperties, BIMObjectConstraintProperties from bonsai.bim.module.constraint.prop import BIMConstraintProperties, BIMObjectConstraintProperties
from bonsai.bim.module.csv.prop import CsvProperties from bonsai.bim.module.csv.prop import CsvProperties
from bonsai.bim.module.diff.prop import DiffProperties from bonsai.bim.module.diff.prop import DiffProperties
from bonsai.bim.module.fm.prop import BIMFMProperties
from bonsai.bim.module.group.prop import BIMGroupProperties from bonsai.bim.module.group.prop import BIMGroupProperties
from bonsai.bim.module.light.prop import BIMSolarProperties, RadianceExporterProperties from bonsai.bim.module.light.prop import BIMSolarProperties, RadianceExporterProperties
@@ -1663,51 +1664,56 @@ class Blender(bonsai.core.tool.Blender):
@classmethod @classmethod
def get_object_constraint_props(cls, obj: bpy.types.Object) -> BIMObjectConstraintProperties: def get_object_constraint_props(cls, obj: bpy.types.Object) -> BIMObjectConstraintProperties:
return obj.BIMObjectConstraintProperties return obj.BIMObjectConstraintProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_constraint_props(cls) -> BIMConstraintProperties: def get_constraint_props(cls) -> BIMConstraintProperties:
assert (scene := bpy.context.scene) assert (scene := bpy.context.scene)
return scene.BIMConstraintProperties return scene.BIMConstraintProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_csv_props(cls) -> CsvProperties: def get_csv_props(cls) -> CsvProperties:
assert (scene := bpy.context.scene) assert (scene := bpy.context.scene)
return scene.CsvProperties return scene.CsvProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_diff_props(cls) -> DiffProperties: def get_diff_props(cls) -> DiffProperties:
assert (scene := bpy.context.scene) assert (scene := bpy.context.scene)
return scene.DiffProperties return scene.DiffProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_group_props(cls) -> BIMGroupProperties: def get_group_props(cls) -> BIMGroupProperties:
assert (scene := bpy.context.scene) assert (scene := bpy.context.scene)
return scene.BIMGroupProperties return scene.BIMGroupProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_bim_props(cls, scene: Optional[bpy.types.Scene] = None) -> BIMProperties: def get_bim_props(cls, scene: Optional[bpy.types.Scene] = None) -> BIMProperties:
if scene is None: if scene is None:
scene = bpy.context.scene assert (scene := bpy.context.scene)
return scene.BIMProperties return scene.BIMProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_object_bim_props(cls, obj: bpy.types.Object) -> BIMObjectProperties: def get_object_bim_props(cls, obj: bpy.types.Object) -> BIMObjectProperties:
return obj.BIMObjectProperties return obj.BIMObjectProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_object_attribute_props(cls, obj: bpy.types.Object) -> BIMAttributeProperties: def get_object_attribute_props(cls, obj: bpy.types.Object) -> BIMAttributeProperties:
return obj.BIMAttributeProperties return obj.BIMAttributeProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_solar_props(cls) -> BIMSolarProperties: def get_solar_props(cls) -> BIMSolarProperties:
assert (scene := bpy.context.scene) assert (scene := bpy.context.scene)
return scene.BIMSolarProperties return scene.BIMSolarProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_radiance_exporter_props(cls) -> RadianceExporterProperties: def get_radiance_exporter_props(cls) -> RadianceExporterProperties:
assert (scene := bpy.context.scene) assert (scene := bpy.context.scene)
return scene.BIMRadianceExporeterProperies return scene.BIMRadianceExporeterProperies # pyright: ignore[reportAttributeAccessIssue]
@classmethod
def get_fm_props(cls) -> BIMFMProperties:
assert (scene := bpy.context.scene)
return scene.BIMFMProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_ifc_definition_id(cls, obj: IFC_CONNECTED_TYPE) -> int: def get_ifc_definition_id(cls, obj: IFC_CONNECTED_TYPE) -> int:
+24 -12
View File
@@ -45,10 +45,11 @@ from mathutils import Color
if TYPE_CHECKING: if TYPE_CHECKING:
import bonsai.bim.prop import bonsai.bim.prop
from bonsai.bim.module.sequence.prop import ( from bonsai.bim.module.sequence.prop import (
BIMTaskTreeProperties,
BIMWorkScheduleProperties,
BIMAnimationProperties, BIMAnimationProperties,
BIMStatusProperties, BIMStatusProperties,
BIMTaskTreeProperties,
BIMWorkPlanProperties,
BIMWorkScheduleProperties,
) )
@@ -58,21 +59,29 @@ class Sequence(bonsai.core.tool.Sequence):
@classmethod @classmethod
def get_animation_props(cls) -> BIMAnimationProperties: def get_animation_props(cls) -> BIMAnimationProperties:
return bpy.context.scene.BIMAnimationProperties assert (scene := bpy.context.scene)
return scene.BIMAnimationProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_task_tree_props(cls) -> BIMTaskTreeProperties: def get_task_tree_props(cls) -> BIMTaskTreeProperties:
return bpy.context.scene.BIMTaskTreeProperties assert (scene := bpy.context.scene)
return scene.BIMTaskTreeProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_work_schedule_props(cls) -> BIMWorkScheduleProperties: def get_work_schedule_props(cls) -> BIMWorkScheduleProperties:
return bpy.context.scene.BIMWorkScheduleProperties assert (scene := bpy.context.scene)
return scene.BIMWorkScheduleProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_status_props(cls) -> BIMStatusProperties: def get_status_props(cls) -> BIMStatusProperties:
assert (scene := bpy.context.scene) assert (scene := bpy.context.scene)
return scene.BIMStatusProperties # pyright: ignore[reportAttributeAccessIssue] return scene.BIMStatusProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod
def get_work_plan_props(cls) -> BIMWorkPlanProperties:
assert (scene := bpy.context.scene)
return scene.BIMWorkPlanProperties # pyright: ignore[reportAttributeAccessIssue]
@classmethod @classmethod
def get_work_plan_attributes(cls) -> dict[str, Any]: def get_work_plan_attributes(cls) -> dict[str, Any]:
import bonsai.bim.module.sequence.helper as helper import bonsai.bim.module.sequence.helper as helper
@@ -91,7 +100,7 @@ class Sequence(bonsai.core.tool.Sequence):
attributes[prop.name] = helper.parse_duration(prop.string_value) attributes[prop.name] = helper.parse_duration(prop.string_value)
return True return True
props = bpy.context.scene.BIMWorkPlanProperties props = cls.get_work_plan_props()
return bonsai.bim.helper.export_attributes(props.work_plan_attributes, callback) return bonsai.bim.helper.export_attributes(props.work_plan_attributes, callback)
@classmethod @classmethod
@@ -101,25 +110,28 @@ class Sequence(bonsai.core.tool.Sequence):
prop.string_value = "" if prop.is_null else data[name] prop.string_value = "" if prop.is_null else data[name]
return True return True
props = bpy.context.scene.BIMWorkPlanProperties props = cls.get_work_plan_props()
props.work_plan_attributes.clear() props.work_plan_attributes.clear()
bonsai.bim.helper.import_attributes2(work_plan, props.work_plan_attributes, callback) bonsai.bim.helper.import_attributes2(work_plan, props.work_plan_attributes, callback)
@classmethod @classmethod
def enable_editing_work_plan(cls, work_plan: Union[ifcopenshell.entity_instance, None]) -> None: def enable_editing_work_plan(cls, work_plan: Union[ifcopenshell.entity_instance, None]) -> None:
if work_plan: if work_plan:
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = work_plan.id() props = cls.get_work_plan_props()
bpy.context.scene.BIMWorkPlanProperties.editing_type = "ATTRIBUTES" props.active_work_plan_id = work_plan.id()
props.editing_type = "ATTRIBUTES"
@classmethod @classmethod
def disable_editing_work_plan(cls) -> None: def disable_editing_work_plan(cls) -> None:
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = 0 props = cls.get_work_plan_props()
props.active_work_plan_id = 0
@classmethod @classmethod
def enable_editing_work_plan_schedules(cls, work_plan: Union[ifcopenshell.entity_instance, None]) -> None: def enable_editing_work_plan_schedules(cls, work_plan: Union[ifcopenshell.entity_instance, None]) -> None:
if work_plan: if work_plan:
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = work_plan.id() props = cls.get_work_plan_props()
bpy.context.scene.BIMWorkPlanProperties.editing_type = "SCHEDULES" props.active_work_plan_id = work_plan.id()
props.editing_type = "SCHEDULES"
@classmethod @classmethod
def get_work_schedule_attributes(cls) -> dict[str, Any]: def get_work_schedule_attributes(cls) -> dict[str, Any]:
@@ -318,12 +318,21 @@ class Iterator:
def get_native(self): ... def get_native(self): ...
def get_object(self, id): ... def get_object(self, id): ...
def had_error_processing_elements(self): ... def had_error_processing_elements(self): ...
def initialize(self): ... def initialize(self) -> bool:
"""Return true if the iterator is initialized with any elements, false otherwise."""
...
def next(self): ... def next(self): ...
def process_concurrently(self): ... def process_concurrently(self): ...
def process_finished_rep(self, rep): ... def process_finished_rep(self, rep): ...
def progress(self): ... def progress(self) -> int:
def set_cache(self, cache): ... """Return current progress (0-100).
Updated after processing each representation.
"""
...
def set_cache(self, cache: GeometrySerializer): ...
def unit_magnitude(self): ... def unit_magnitude(self): ...
def unit_name(self): ... def unit_name(self): ...