mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
typing
This commit is contained in:
@@ -78,7 +78,8 @@ class BoundaryDecorator:
|
||||
unselected_edges = []
|
||||
unselected_tris = []
|
||||
|
||||
for boundary in context.scene.BIMBoundaryProperties.boundaries:
|
||||
props = tool.Boundary.get_boundary_props()
|
||||
for boundary in props.boundaries:
|
||||
obj = boundary.obj
|
||||
if not obj or not obj.data: # A boundary may not have data if it has no connection geometry
|
||||
continue
|
||||
|
||||
@@ -354,7 +354,9 @@ class EnableEditingBoundary(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
bprops = context.active_object.BIMBoundaryProperties
|
||||
obj = context.active_object
|
||||
assert obj
|
||||
bprops = tool.Boundary.get_object_boundary_props(obj)
|
||||
bprops.is_editing = True
|
||||
boundary = tool.Ifc.get_entity(context.active_object)
|
||||
for ifc_attribute, blender_property in EDITABLE_ATTRIBUTES.items():
|
||||
@@ -373,7 +375,9 @@ class DisableEditingBoundary(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
bprops = context.active_object.BIMBoundaryProperties
|
||||
obj = context.active_object
|
||||
assert obj
|
||||
bprops = tool.Boundary.get_object_boundary_props(obj)
|
||||
bprops.is_editing = False
|
||||
for ifc_attribute, blender_property in EDITABLE_ATTRIBUTES.items():
|
||||
setattr(bprops, blender_property, None)
|
||||
@@ -386,8 +390,10 @@ class EditBoundaryAttributes(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
bprops = context.active_object.BIMBoundaryProperties
|
||||
boundary = tool.Ifc.get_entity(context.active_object)
|
||||
obj = context.active_object
|
||||
assert obj
|
||||
bprops = tool.Boundary.get_object_boundary_props(obj)
|
||||
boundary = tool.Ifc.get_entity(obj)
|
||||
attributes = dict()
|
||||
for ifc_attribute, blender_property in EDITABLE_ATTRIBUTES.items():
|
||||
obj = getattr(bprops, blender_property, None)
|
||||
@@ -519,6 +525,7 @@ class HideBoundaries(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = tool.Boundary.get_boundary_props()
|
||||
to_delete = set()
|
||||
spaces = set()
|
||||
for obj in context.selected_objects:
|
||||
@@ -538,7 +545,7 @@ class HideBoundaries(bpy.types.Operator, tool.Ifc.Operator):
|
||||
for boundary, boundary_obj in to_delete:
|
||||
tool.Ifc.unlink(element=boundary)
|
||||
bpy.data.objects.remove(boundary_obj)
|
||||
context.scene.BIMBoundaryProperties.boundaries.clear()
|
||||
props.boundaries.clear()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -549,7 +556,7 @@ class DecorateBoundaries(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMBoundaryProperties
|
||||
props = tool.Boundary.get_boundary_props()
|
||||
# filter not decorated boundaries and add decorations for them
|
||||
decorated_boundaries = set([i.obj for i in props.boundaries])
|
||||
active_boundaries = set()
|
||||
|
||||
@@ -30,23 +30,24 @@ from bpy.props import (
|
||||
CollectionProperty,
|
||||
)
|
||||
import bonsai.tool as tool
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
|
||||
def space_filter(self, object):
|
||||
def space_filter(self: "BIMObjectBoundaryProperties", object: bpy.types.Object) -> bool:
|
||||
entity = tool.Ifc.get_entity(object)
|
||||
if entity:
|
||||
return entity.is_a("IfcSpace") or entity.is_a("IfcExternalSpatialElement")
|
||||
return False
|
||||
|
||||
|
||||
def boundary_filter(self, object):
|
||||
def boundary_filter(self: "BIMObjectBoundaryProperties", object: bpy.types.Object) -> bool:
|
||||
entity = tool.Ifc.get_entity(object)
|
||||
if entity:
|
||||
return entity.is_a("IfcRelSpaceBoundary")
|
||||
return False
|
||||
|
||||
|
||||
def element_filter(self, object):
|
||||
def element_filter(self: "BIMObjectBoundaryProperties", object: bpy.types.Object) -> bool:
|
||||
entity = tool.Ifc.get_entity(object)
|
||||
if entity:
|
||||
return entity.is_a("IfcElement")
|
||||
@@ -60,6 +61,16 @@ class BIMObjectBoundaryProperties(PropertyGroup):
|
||||
parent_boundary: PointerProperty(name="ParentBoundary", type=bpy.types.Object, poll=boundary_filter)
|
||||
corresponding_boundary: PointerProperty(name="CorrespondingBoundary", type=bpy.types.Object, poll=boundary_filter)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
is_editing: bool
|
||||
relating_space: Union[bpy.types.Object, None]
|
||||
related_building_element: Union[bpy.types.Object, None]
|
||||
parent_boundary: Union[bpy.types.Object, None]
|
||||
corresponding_boundary: Union[bpy.types.Object, None]
|
||||
|
||||
|
||||
class BIMBoundaryProperties(PropertyGroup):
|
||||
boundaries: bpy.props.CollectionProperty(type=ObjProperty)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
boundaries: bpy.types.bpy_prop_collection_idprop[ObjProperty]
|
||||
|
||||
@@ -64,10 +64,12 @@ class BIM_PT_Boundary(Panel):
|
||||
return entity.is_a("IfcRelSpaceBoundary")
|
||||
|
||||
def draw(self, context):
|
||||
props = context.active_object.BIMObjectProperties
|
||||
obj = context.active_object
|
||||
assert obj
|
||||
props = obj.BIMObjectProperties
|
||||
ifc_file = tool.Ifc.get()
|
||||
boundary = ifc_file.by_id(props.ifc_definition_id)
|
||||
self.bprops = context.active_object.BIMBoundaryProperties
|
||||
self.bprops = tool.Boundary.get_object_boundary_props(obj)
|
||||
if self.bprops.is_editing:
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.edit_boundary_attributes", icon="CHECKMARK", text="Save Attributes")
|
||||
|
||||
@@ -325,10 +325,11 @@ class CostItemQuantitiesData:
|
||||
@classmethod
|
||||
def process_quantity_names(cls):
|
||||
active_task_index = bpy.context.scene.BIMWorkScheduleProperties.active_task_index
|
||||
total_tasks = len(bpy.context.scene.BIMTaskTreeProperties.tasks)
|
||||
tprops = tool.Sequence.get_task_tree_props()
|
||||
total_tasks = len(tprops.tasks)
|
||||
if not total_tasks or active_task_index >= total_tasks:
|
||||
return []
|
||||
ifc_definition_id = bpy.context.scene.BIMTaskTreeProperties.tasks[active_task_index].ifc_definition_id
|
||||
ifc_definition_id = tprops.tasks[active_task_index].ifc_definition_id
|
||||
element = tool.Ifc.get().by_id(ifc_definition_id)
|
||||
names = set()
|
||||
qtos = ifcopenshell.util.element.get_psets(element, qtos_only=True)
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import bpy
|
||||
import bonsai.bim.helper
|
||||
import bonsai.bim.module.cost.prop as CostProp
|
||||
import bonsai.tool as tool
|
||||
from bpy.types import Panel, UIList
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
from bonsai.bim.module.cost.data import CostSchedulesData
|
||||
@@ -461,7 +462,7 @@ class BIM_PT_cost_item_quantities(Panel):
|
||||
total_cost_item_processes = len(self.props.cost_item_processes)
|
||||
row2.label(text="Tasks ({})".format(total_cost_item_processes))
|
||||
|
||||
tprops = context.scene.BIMTaskTreeProperties
|
||||
tprops = tool.Sequence.get_task_tree_props()
|
||||
wprops = context.scene.BIMWorkScheduleProperties
|
||||
if tprops.tasks and wprops.active_task_index < len(tprops.tasks):
|
||||
if has_quantity_names:
|
||||
|
||||
@@ -422,7 +422,7 @@ class CreateDrawing(bpy.types.Operator):
|
||||
self.svg_writer.create_blank_svg(svg_path).draw_underlay(context.scene.render.filepath).save()
|
||||
return svg_path
|
||||
|
||||
def get_linework_contexts(self, ifc, target_view) -> LineworkContexts:
|
||||
def get_linework_contexts(self, ifc: ifcopenshell.file, target_view: str) -> LineworkContexts:
|
||||
plan_body_target_contexts = []
|
||||
plan_body_model_contexts = []
|
||||
model_body_target_contexts = []
|
||||
|
||||
@@ -42,6 +42,7 @@ import ifcopenshell.util.representation
|
||||
import ifcopenshell.util.shape
|
||||
import ifcopenshell.util.unit
|
||||
import bonsai.bim.handler
|
||||
import bonsai.bim.helper
|
||||
import bonsai.bim.schema
|
||||
import bonsai.tool as tool
|
||||
import bonsai.core.project as core
|
||||
|
||||
@@ -128,7 +128,7 @@ class BIM_PT_project(Panel):
|
||||
self.layout.use_property_decorate = False
|
||||
self.layout.use_property_split = True
|
||||
props = context.scene.BIMProperties
|
||||
pprops = context.scene.BIMProjectProperties
|
||||
pprops = self.props = tool.Project.get_project_props()
|
||||
self.file = IfcStore.get_file()
|
||||
if pprops.is_loading:
|
||||
self.draw_advanced_loading_ui(context)
|
||||
@@ -148,7 +148,7 @@ class BIM_PT_project(Panel):
|
||||
self.draw_unsaved_project_ui(context)
|
||||
|
||||
def draw_advanced_loading_ui(self, context):
|
||||
pprops = context.scene.BIMProjectProperties
|
||||
pprops = self.props
|
||||
prop_with_search(self.layout, pprops, "filter_mode")
|
||||
if pprops.filter_mode in ["DECOMPOSITION", "IFC_CLASS", "IFC_TYPE"]:
|
||||
row = self.layout.row(align=True)
|
||||
@@ -222,7 +222,7 @@ class BIM_PT_project(Panel):
|
||||
row.operator("bim.load_project_elements")
|
||||
|
||||
def draw_editing_buttons(self, context, row):
|
||||
pprops = context.scene.BIMProjectProperties
|
||||
pprops = self.props
|
||||
if IfcStore.get_file():
|
||||
if pprops.is_editing:
|
||||
row.operator("bim.edit_header", icon="CHECKMARK", text="")
|
||||
@@ -231,7 +231,7 @@ class BIM_PT_project(Panel):
|
||||
row.operator("bim.enable_editing_header", icon="GREASEPENCIL", text="")
|
||||
|
||||
def draw_editable_file_info(self, context):
|
||||
pprops = context.scene.BIMProjectProperties
|
||||
pprops = self.props
|
||||
|
||||
if IfcStore.get_file():
|
||||
row = self.layout.row(align=True)
|
||||
@@ -316,7 +316,7 @@ class BIM_PT_new_project_wizard(Panel):
|
||||
self.layout.use_property_split = True
|
||||
|
||||
props = context.scene.BIMProperties
|
||||
pprops = context.scene.BIMProjectProperties
|
||||
pprops = tool.Project.get_project_props()
|
||||
prop_with_search(self.layout, pprops, "export_schema")
|
||||
row = self.layout.row()
|
||||
row.prop(context.scene.unit_settings, "system")
|
||||
@@ -418,7 +418,7 @@ class BIM_PT_links(Panel):
|
||||
bl_parent_id = "BIM_PT_tab_project_setup"
|
||||
|
||||
def draw(self, context):
|
||||
self.props = context.scene.BIMProjectProperties
|
||||
self.props = tool.Project.get_project_props()
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.link_ifc")
|
||||
if self.props.links:
|
||||
|
||||
@@ -55,7 +55,11 @@ class Data:
|
||||
for name, data in sorted(psetqtos.items()):
|
||||
pset = ifc_file.by_id(data["id"])
|
||||
pset_uses = ifcopenshell.util.element.get_elements_by_pset(pset)
|
||||
has_template = bool(tool.Pset.get_pset_template(name))
|
||||
pset_template = tool.Pset.get_pset_template(name)
|
||||
if has_template := bool(pset_template):
|
||||
template_available_in_ui = pset_template
|
||||
else:
|
||||
template_available_in_ui = False
|
||||
results.append(
|
||||
{
|
||||
"id": data["id"],
|
||||
@@ -214,7 +218,7 @@ class TaskQtosData(Data):
|
||||
@classmethod
|
||||
def load(cls):
|
||||
wprops = bpy.context.scene.BIMWorkScheduleProperties
|
||||
tprops = bpy.context.scene.BIMTaskTreeProperties
|
||||
tprops = tool.Sequence.get_task_tree_props()
|
||||
ifc_definition_id = tprops.tasks[wprops.active_task_index].ifc_definition_id
|
||||
cls.data = {"qtos": cls.psetqtos(tool.Ifc.get().by_id(ifc_definition_id), qtos_only=True)}
|
||||
cls.is_loaded = True
|
||||
|
||||
@@ -491,14 +491,14 @@ class SavePsetAsTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOpera
|
||||
pset_id: bpy.props.IntProperty()
|
||||
|
||||
def invoke(self, context, event):
|
||||
props = context.scene.BIMPsetTemplateProperties
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
if tool.Blender.get_enum_safe(props, "pset_template_files") is None:
|
||||
self.report({"ERROR"}, "No template files found. You can create one in Property Set Templates UI.")
|
||||
return {"CANCELLED"}
|
||||
return context.window_manager.invoke_props_dialog(self, width=250)
|
||||
|
||||
def draw(self, context):
|
||||
props = context.scene.BIMPsetTemplateProperties
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
self.layout.prop(props, "pset_template_files", text="Template File")
|
||||
|
||||
def _execute(self, context):
|
||||
|
||||
@@ -40,7 +40,7 @@ from typing import Any, Optional, TYPE_CHECKING
|
||||
from typing_extensions import assert_never
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.pset.prop import IfcProperty
|
||||
from bonsai.bim.module.pset.prop import IfcProperty, PsetProperties
|
||||
|
||||
|
||||
def draw_property(prop: IfcProperty, layout: bpy.types.UILayout, copy_operator: Optional[str] = None) -> None:
|
||||
@@ -73,7 +73,7 @@ def draw_single_property(prop: IfcProperty, layout: bpy.types.UILayout, copy_ope
|
||||
|
||||
|
||||
def draw_enumerated_property(
|
||||
prop: bpy.types.PropertyGroup, layout: bpy.types.UILayout, copy_operator: Optional[str] = None
|
||||
prop: IfcProperty, layout: bpy.types.UILayout, copy_operator: Optional[str] = None
|
||||
) -> None:
|
||||
value_name = prop.metadata.get_value_name()
|
||||
if not value_name:
|
||||
@@ -99,7 +99,7 @@ def draw_psetqto_ui(
|
||||
context: bpy.types.Context,
|
||||
pset_id: int,
|
||||
pset: dict[str, Any],
|
||||
props: bpy.types.PropertyGroup,
|
||||
props: PsetProperties,
|
||||
layout: bpy.types.UILayout,
|
||||
obj_type: tool.Ifc.OBJECT_TYPE,
|
||||
allow_removing: bool = True,
|
||||
@@ -219,9 +219,7 @@ def draw_psetqto_ui(
|
||||
row.label(text="No Properties")
|
||||
|
||||
|
||||
def draw_psetqto_editable_ui(
|
||||
box: bpy.types.UILayout, props: bpy.types.PropertyGroup, prop: bpy.types.PropertyGroup
|
||||
) -> None:
|
||||
def draw_psetqto_editable_ui(box: bpy.types.UILayout, props: PsetProperties, prop: IfcProperty) -> None:
|
||||
row = box.row(align=True)
|
||||
draw_property(prop, row, copy_operator="bim.copy_property_to_selection")
|
||||
|
||||
@@ -493,7 +491,8 @@ class BIM_PT_task_qtos(Panel):
|
||||
props = context.scene.BIMWorkScheduleProperties
|
||||
if not props.active_work_schedule_id:
|
||||
return False
|
||||
total_tasks = len(context.scene.BIMTaskTreeProperties.tasks)
|
||||
tprops = tool.Sequence.get_task_tree_props()
|
||||
total_tasks = len(tprops.tasks)
|
||||
if total_tasks > 0 and props.active_task_index < total_tasks:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -126,13 +126,14 @@ class PsetTemplatesData:
|
||||
if not cls.data["pset_template_files"]:
|
||||
return []
|
||||
if not IfcStore.pset_template_file:
|
||||
IfcStore.pset_template_path = bpy.context.scene.BIMPsetTemplateProperties.pset_template_files
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
IfcStore.pset_template_path = props.pset_template_files
|
||||
IfcStore.pset_template_file = ifcopenshell.open(IfcStore.pset_template_path)
|
||||
return [(str(t.id()), t.Name, "") for t in IfcStore.pset_template_file.by_type("IfcPropertySetTemplate")]
|
||||
|
||||
@classmethod
|
||||
def pset_template(cls) -> dict[str, Any]:
|
||||
props = bpy.context.scene.BIMPsetTemplateProperties
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
template_id = props.pset_templates
|
||||
if not template_id:
|
||||
return {}
|
||||
@@ -145,7 +146,7 @@ class PsetTemplatesData:
|
||||
|
||||
@classmethod
|
||||
def prop_templates(cls) -> list[dict[str, Any]]:
|
||||
props = bpy.context.scene.BIMPsetTemplateProperties
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
template_id = props.pset_templates
|
||||
if not template_id:
|
||||
return []
|
||||
|
||||
@@ -49,7 +49,8 @@ class AddPsetTemplateFile(bpy.types.Operator):
|
||||
template.write(filepath)
|
||||
bonsai.bim.handler.refresh_ui_data()
|
||||
bonsai.bim.schema.reload(tool.Ifc.get().schema)
|
||||
context.scene.BIMPsetTemplateProperties.pset_template_files = filepath
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
props.pset_template_files = filepath
|
||||
tool.PsetTemplate.enable_editing_pset_template()
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -67,7 +68,8 @@ class AddPsetTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOperator
|
||||
self.template_file.write(IfcStore.pset_template_path)
|
||||
bonsai.bim.handler.refresh_ui_data()
|
||||
bonsai.bim.schema.reload(tool.Ifc.get().schema)
|
||||
context.scene.BIMPsetTemplateProperties.pset_templates = str(template.id())
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
props.pset_templates = str(template.id())
|
||||
|
||||
|
||||
class RemovePsetTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOperator):
|
||||
@@ -76,7 +78,7 @@ class RemovePsetTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOpera
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMPsetTemplateProperties
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
current_pset_template_id = int(props.pset_templates)
|
||||
if props.active_pset_template_id == current_pset_template_id:
|
||||
bpy.ops.bim.disable_editing_pset_template()
|
||||
@@ -107,7 +109,7 @@ class DisableEditingPsetTemplate(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMPsetTemplateProperties
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
props.active_pset_template_id = 0
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -130,7 +132,8 @@ class DeletePropEnum(bpy.types.Operator):
|
||||
index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
active_prop = context.scene.BIMPsetTemplateProperties.active_prop_template
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
active_prop = props.active_prop_template
|
||||
active_prop.enum_values.remove(self.index)
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -142,7 +145,8 @@ class AddPropEnum(bpy.types.Operator):
|
||||
index: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
active_prop = context.scene.BIMPsetTemplateProperties.active_prop_template
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
active_prop = props.active_prop_template
|
||||
active_prop.enum_values.add()
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -153,7 +157,7 @@ class DisableEditingPropTemplate(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMPsetTemplateProperties
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
props.active_prop_template_id = 0
|
||||
return {"FINISHED"}
|
||||
|
||||
@@ -164,7 +168,7 @@ class EditPsetTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOperato
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMPsetTemplateProperties
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
ifcopenshell.api.run(
|
||||
"pset_template.edit_pset_template",
|
||||
IfcStore.pset_template_file,
|
||||
@@ -209,7 +213,7 @@ class RemovePsetTemplateFile(bpy.types.Operator):
|
||||
bonsai.bim.schema.reload(tool.Ifc.get().schema)
|
||||
|
||||
# Ensure enum is valid after deletion.
|
||||
self.props = context.scene.BIMPsetTemplateProperties
|
||||
self.props = tool.PsetTemplate.get_pset_template_props()
|
||||
if not tool.Blender.ensure_enum_is_valid(self.props, "pset_template_files"):
|
||||
self.update_template_files_prop(context)
|
||||
return {"FINISHED"}
|
||||
@@ -226,7 +230,7 @@ class AddPropTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOperator
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMPsetTemplateProperties
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
pset_template_id = props.active_pset_template_id or int(props.pset_templates)
|
||||
prop_template = ifcopenshell.api.run(
|
||||
"pset_template.add_prop_template",
|
||||
@@ -264,7 +268,7 @@ class EditPropTemplate(bpy.types.Operator, tool.PsetTemplate.PsetTemplateOperato
|
||||
|
||||
def _execute(self, context):
|
||||
assert IfcStore.pset_template_file
|
||||
props = context.scene.BIMPsetTemplateProperties
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
active_prop_template = props.active_prop_template
|
||||
if props.active_prop_template.template_type == "P_ENUMERATEDVALUE":
|
||||
data_type = props.active_prop_template.get_value_name()
|
||||
|
||||
@@ -36,7 +36,7 @@ class BIM_PT_pset_template(Panel):
|
||||
if not PsetTemplatesData.is_loaded:
|
||||
PsetTemplatesData.load()
|
||||
|
||||
self.props = context.scene.BIMPsetTemplateProperties
|
||||
self.props = tool.PsetTemplate.get_pset_template_props()
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
if PsetTemplatesData.data["pset_template_files"]:
|
||||
|
||||
@@ -40,6 +40,7 @@ from bpy.props import (
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
||||
def getTaskColumns(self, context):
|
||||
@@ -343,6 +344,26 @@ class Task(PropertyGroup):
|
||||
is_predecessor: BoolProperty(name="Is Predecessor")
|
||||
is_successor: BoolProperty(name="Is Successor")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
name: str
|
||||
identification: str
|
||||
ifc_definition_id: int
|
||||
has_children: bool
|
||||
is_selected: bool
|
||||
is_expanded: bool
|
||||
has_bar_visual: bool
|
||||
level_index: int
|
||||
duration: str
|
||||
start: str
|
||||
finish: str
|
||||
calendar: str
|
||||
derived_start: str
|
||||
derived_finish: str
|
||||
derived_duration: str
|
||||
derived_calendar: str
|
||||
is_predecessor: bool
|
||||
is_successor: bool
|
||||
|
||||
|
||||
class WorkPlan(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
@@ -479,6 +500,9 @@ class BIMTaskTreeProperties(PropertyGroup):
|
||||
# In Blender if you add many collection items it makes other property access in the same group really slow.
|
||||
tasks: CollectionProperty(name="Tasks", type=Task)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
tasks: bpy.types.bpy_prop_collection_idprop[Task]
|
||||
|
||||
|
||||
class WorkCalendar(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
|
||||
@@ -156,7 +156,7 @@ class BIM_PT_work_schedules(Panel):
|
||||
if not WorkScheduleData.is_loaded:
|
||||
WorkScheduleData.load()
|
||||
self.props = context.scene.BIMWorkScheduleProperties
|
||||
self.tprops = context.scene.BIMTaskTreeProperties
|
||||
self.tprops = tool.Sequence.get_task_tree_props()
|
||||
|
||||
if not self.props.active_work_schedule_id:
|
||||
row = self.layout.row(align=True)
|
||||
@@ -649,7 +649,8 @@ class BIM_PT_task_icom(Panel):
|
||||
props = context.scene.BIMWorkScheduleProperties
|
||||
if not props.active_work_schedule_id:
|
||||
return False
|
||||
total_tasks = len(context.scene.BIMTaskTreeProperties.tasks)
|
||||
tprops = tool.Sequence.get_task_tree_props()
|
||||
total_tasks = len(tprops.tasks)
|
||||
if total_tasks > 0 and props.active_task_index < total_tasks:
|
||||
return True
|
||||
return False
|
||||
@@ -659,7 +660,7 @@ class BIM_PT_task_icom(Panel):
|
||||
TaskICOMData.load()
|
||||
|
||||
self.props = context.scene.BIMWorkScheduleProperties
|
||||
self.tprops = context.scene.BIMTaskTreeProperties
|
||||
self.tprops = tool.Sequence.get_task_tree_props()
|
||||
task = self.tprops.tasks[self.props.active_task_index]
|
||||
|
||||
grid = self.layout.grid_flow(columns=3, even_columns=True)
|
||||
|
||||
@@ -169,6 +169,9 @@ class StrProperty(PropertyGroup):
|
||||
class ObjProperty(PropertyGroup):
|
||||
obj: bpy.props.PointerProperty(type=bpy.types.Object)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
obj: Union[bpy.types.Object, None]
|
||||
|
||||
|
||||
def update_single_file(self: "MultipleFileSelect", context: bpy.types.Context) -> None:
|
||||
self.file_list.clear()
|
||||
@@ -180,6 +183,10 @@ class MultipleFileSelect(PropertyGroup):
|
||||
single_file: bpy.props.StringProperty(name="Single File Path", description="", update=update_single_file)
|
||||
file_list: bpy.props.CollectionProperty(type=StrProperty)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
single_file: str
|
||||
file_list: bpy.types.bpy_prop_collection_idprop[StrProperty]
|
||||
|
||||
def set_file_list(self, dirname: str, files: list[str]) -> None:
|
||||
self.file_list.clear()
|
||||
|
||||
|
||||
@@ -194,9 +194,8 @@ class Blender(bonsai.core.tool.Blender):
|
||||
elif obj_type == "MaterialSetItem":
|
||||
return bpy.data.objects.get(obj).BIMObjectMaterialProperties.active_material_set_item_id
|
||||
elif obj_type == "Task":
|
||||
return context.scene.BIMTaskTreeProperties.tasks[
|
||||
context.scene.BIMWorkScheduleProperties.active_task_index
|
||||
].ifc_definition_id
|
||||
tprops = tool.Sequence.get_task_tree_props()
|
||||
return tprops.tasks[context.scene.BIMWorkScheduleProperties.active_task_index].ifc_definition_id
|
||||
elif obj_type == "Cost":
|
||||
return context.scene.BIMCostProperties.cost_items[
|
||||
context.scene.BIMCostProperties.active_cost_item_index
|
||||
|
||||
@@ -16,15 +16,27 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import bpy
|
||||
import mathutils
|
||||
import bonsai.core.tool
|
||||
import bonsai.tool as tool
|
||||
from mathutils import Matrix, Vector
|
||||
from typing import Any, Sequence
|
||||
from typing import Any, Sequence, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.boundary.prop import BIMBoundaryProperties, BIMObjectBoundaryProperties
|
||||
|
||||
|
||||
class Boundary(bonsai.core.tool.Boundary):
|
||||
@classmethod
|
||||
def get_boundary_props(cls) -> BIMBoundaryProperties:
|
||||
return bpy.context.scene.BIMBoundaryProperties
|
||||
|
||||
@classmethod
|
||||
def get_object_boundary_props(cls, obj: bpy.types.Object) -> BIMObjectBoundaryProperties:
|
||||
return obj.BIMBoundaryProperties
|
||||
|
||||
@classmethod
|
||||
def get_assign_connection_geometry_settings(cls, obj: bpy.types.Object) -> dict[str, Any]:
|
||||
from bonsai.bim.module.geometry.helper import Helper
|
||||
@@ -76,7 +88,8 @@ class Boundary(bonsai.core.tool.Boundary):
|
||||
|
||||
@classmethod
|
||||
def decorate_boundary(cls, obj: bpy.types.Object) -> None:
|
||||
new = bpy.context.scene.BIMBoundaryProperties.boundaries.add()
|
||||
props = cls.get_boundary_props()
|
||||
new = props.boundaries.add()
|
||||
new.obj = obj
|
||||
obj.show_in_front = True
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ class Pset(bonsai.core.tool.Pset):
|
||||
return special_type
|
||||
|
||||
@classmethod
|
||||
def import_pset_from_existing(cls, pset: ifcopenshell.entity_instance, props: bpy.types.PropertyGroup) -> None:
|
||||
def import_pset_from_existing(cls, pset: ifcopenshell.entity_instance, props: PsetProperties) -> None:
|
||||
pset_props = []
|
||||
if pset.is_a("IfcElementQuantity"):
|
||||
pset_props = pset.Quantities
|
||||
|
||||
@@ -42,12 +42,17 @@ from typing import Optional, Any, Union, Literal, TYPE_CHECKING, Iterable
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import bonsai.bim.prop
|
||||
from bonsai.bim.module.sequence.prop import BIMTaskTreeProperties
|
||||
|
||||
|
||||
class Sequence(bonsai.core.tool.Sequence):
|
||||
|
||||
RELATED_OBJECT_TYPE = Literal["RESOURCE", "PRODUCT", "CONTROL"]
|
||||
|
||||
@classmethod
|
||||
def get_task_tree_props(cls) -> BIMTaskTreeProperties:
|
||||
return bpy.context.scene.BIMTaskTreeProperties
|
||||
|
||||
@classmethod
|
||||
def get_work_plan_attributes(cls) -> dict[str, Any]:
|
||||
import bonsai.bim.module.sequence.helper as helper
|
||||
@@ -146,7 +151,8 @@ class Sequence(bonsai.core.tool.Sequence):
|
||||
|
||||
@classmethod
|
||||
def load_task_tree(cls, work_schedule: ifcopenshell.entity_instance) -> None:
|
||||
bpy.context.scene.BIMTaskTreeProperties.tasks.clear()
|
||||
props = cls.get_task_tree_props()
|
||||
props.tasks.clear()
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
cls.contracted_tasks = json.loads(props.contracted_tasks)
|
||||
|
||||
@@ -185,7 +191,8 @@ class Sequence(bonsai.core.tool.Sequence):
|
||||
@classmethod
|
||||
def create_new_task_li(cls, related_object_id: int, level_index: int) -> None:
|
||||
task = tool.Ifc.get().by_id(related_object_id)
|
||||
new = bpy.context.scene.BIMTaskTreeProperties.tasks.add()
|
||||
props = cls.get_task_tree_props()
|
||||
new = props.tasks.add()
|
||||
new.ifc_definition_id = related_object_id
|
||||
new.is_expanded = related_object_id not in cls.contracted_tasks
|
||||
new.level_index = level_index
|
||||
@@ -199,7 +206,7 @@ class Sequence(bonsai.core.tool.Sequence):
|
||||
@classmethod
|
||||
def load_task_properties(cls, task: Optional[ifcopenshell.entity_instance] = None) -> None:
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
task_props = bpy.context.scene.BIMTaskTreeProperties
|
||||
task_props = cls.get_task_tree_props()
|
||||
tasks_with_visual_bar = cls.get_task_bar_list()
|
||||
props.is_task_update_enabled = False
|
||||
|
||||
@@ -281,8 +288,9 @@ class Sequence(bonsai.core.tool.Sequence):
|
||||
@classmethod
|
||||
def contract_all_tasks(cls) -> None:
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
tprops = cls.get_task_tree_props()
|
||||
contracted_tasks = json.loads(props.contracted_tasks)
|
||||
for task_item in bpy.context.scene.BIMTaskTreeProperties.tasks:
|
||||
for task_item in tprops.tasks:
|
||||
if task_item.is_expanded:
|
||||
contracted_tasks.append(task_item.ifc_definition_id)
|
||||
props.contracted_tasks = json.dumps(contracted_tasks)
|
||||
@@ -302,7 +310,7 @@ class Sequence(bonsai.core.tool.Sequence):
|
||||
def disable_selecting_deleted_task(cls) -> None:
|
||||
props = bpy.context.scene.BIMWorkScheduleProperties
|
||||
if props.active_task_id not in [
|
||||
task.ifc_definition_id for task in bpy.context.scene.BIMTaskTreeProperties.tasks
|
||||
task.ifc_definition_id for task in cls.get_task_tree_props().tasks
|
||||
]: # Task was deleted
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_task_id = 0
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_task_time_id = 0
|
||||
@@ -310,9 +318,7 @@ class Sequence(bonsai.core.tool.Sequence):
|
||||
@classmethod
|
||||
def get_checked_tasks(cls) -> list[ifcopenshell.entity_instance]:
|
||||
return [
|
||||
tool.Ifc.get().by_id(task.ifc_definition_id)
|
||||
for task in bpy.context.scene.BIMTaskTreeProperties.tasks
|
||||
if task.is_selected
|
||||
tool.Ifc.get().by_id(task.ifc_definition_id) for task in cls.get_task_tree_props().tasks if task.is_selected
|
||||
] or []
|
||||
|
||||
@classmethod
|
||||
@@ -486,7 +492,7 @@ class Sequence(bonsai.core.tool.Sequence):
|
||||
|
||||
@classmethod
|
||||
def get_highlighted_task(cls) -> Union[ifcopenshell.entity_instance, None]:
|
||||
tasks = bpy.context.scene.BIMTaskTreeProperties.tasks
|
||||
tasks = cls.get_task_tree_props().tasks
|
||||
if len(tasks) and len(tasks) > bpy.context.scene.BIMWorkScheduleProperties.active_task_index:
|
||||
return tool.Ifc.get().by_id(
|
||||
tasks[bpy.context.scene.BIMWorkScheduleProperties.active_task_index].ifc_definition_id
|
||||
@@ -789,7 +795,7 @@ class Sequence(bonsai.core.tool.Sequence):
|
||||
cls.load_task_tree(work_schedule)
|
||||
cls.load_task_properties()
|
||||
|
||||
task_props = bpy.context.scene.BIMTaskTreeProperties
|
||||
task_props = cls.get_task_tree_props()
|
||||
expanded_tasks = [item.ifc_definition_id for item in task_props.tasks]
|
||||
bpy.context.scene.BIMWorkScheduleProperties.active_task_index = expanded_tasks.index(task.id()) or 0
|
||||
|
||||
|
||||
@@ -1133,23 +1133,27 @@ class Spatial(bonsai.core.tool.Spatial):
|
||||
@classmethod
|
||||
def toggle_spaces_visibility_wired_and_textured(cls, spaces: list[ifcopenshell.entity_instance]) -> None:
|
||||
first_obj = tool.Ifc.get_object(spaces[0])
|
||||
if bpy.data.objects[first_obj.name].display_type == "TEXTURED":
|
||||
assert isinstance(first_obj, bpy.types.Object)
|
||||
obj: bpy.types.Object
|
||||
if first_obj.display_type == "TEXTURED":
|
||||
for space in spaces:
|
||||
obj = tool.Ifc.get_object(space)
|
||||
bpy.data.objects[obj.name].show_wire = True
|
||||
bpy.data.objects[obj.name].display_type = "WIRE"
|
||||
obj.show_wire = True
|
||||
obj.display_type = "WIRE"
|
||||
return
|
||||
|
||||
elif bpy.data.objects[first_obj.name].display_type == "WIRE":
|
||||
elif first_obj.display_type == "WIRE":
|
||||
for space in spaces:
|
||||
obj = tool.Ifc.get_object(space)
|
||||
bpy.data.objects[obj.name].show_wire = False
|
||||
bpy.data.objects[obj.name].display_type = "TEXTURED"
|
||||
obj.show_wire = False
|
||||
obj.display_type = "TEXTURED"
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def toggle_hide_spaces(cls, spaces: list[ifcopenshell.entity_instance]) -> None:
|
||||
first_obj = tool.Ifc.get_object(spaces[0])
|
||||
assert isinstance(first_obj, bpy.types.Object)
|
||||
obj: bpy.types.Object
|
||||
if first_obj.hide_get() == False:
|
||||
for space in spaces:
|
||||
obj = tool.Ifc.get_object(space)
|
||||
|
||||
@@ -352,7 +352,8 @@ def i_select_the_item_name_item_in_the_list_name_list(item_name, list_name):
|
||||
|
||||
@when("I load a new pset template file")
|
||||
def i_load_a_new_pset_template_file():
|
||||
IfcStore.pset_template_path = bpy.context.scene.BIMPsetTemplateProperties.pset_template_files
|
||||
props = tool.PsetTemplate.get_pset_template_props()
|
||||
IfcStore.pset_template_path = props.pset_template_files
|
||||
IfcStore.pset_template_file = ifcopenshell.open(IfcStore.pset_template_path)
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import ifcopenshell.api.owner
|
||||
import ifcopenshell.api.geometry
|
||||
import ifcopenshell.guid
|
||||
import ifcopenshell.util.placement
|
||||
from typing import Any
|
||||
|
||||
|
||||
def assign_port(
|
||||
@@ -68,6 +69,9 @@ def assign_port(
|
||||
|
||||
|
||||
class Usecase:
|
||||
file: ifcopenshell.file
|
||||
settings: dict[str, Any]
|
||||
|
||||
def execute(self):
|
||||
if self.file.schema == "IFC2X3":
|
||||
return self.execute_ifc2x3()
|
||||
|
||||
Reference in New Issue
Block a user