This commit is contained in:
Andrej730
2024-05-23 12:02:37 +05:00
parent fffd7360cb
commit f576aadee1
23 changed files with 343 additions and 213 deletions
@@ -22,21 +22,24 @@ import bmesh
from bmesh.types import BMVert, BMFace
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.element
import ifcopenshell.util.representation
from ifcopenshell.util.shape_builder import V
import blenderbim
import blenderbim.tool as tool
import blenderbim.core.geometry
import blenderbim.core.geometry as core
import blenderbim.core.root
from blenderbim.bim.module.model.window import create_bm_window, create_bm_box
from mathutils import Vector, Matrix
from pprint import pprint
import json
import collections
def update_door_modifier_representation(context, obj):
def update_door_modifier_representation(context: bpy.types.Context, obj: bpy.types.Object) -> None:
props = obj.BIMDoorProperties
element = tool.Ifc.get_entity(obj)
ifc_file = tool.Ifc.get()
@@ -94,7 +94,6 @@ class DumbProfileGenerator:
obj=obj,
ifc_class=ifc_class,
should_add_representation=False,
context=self.body_context,
)
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=self.relating_type)
@@ -20,8 +20,12 @@
import bpy
import bmesh
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.representation
import ifcopenshell.util.unit
from ifcopenshell.util.shape_builder import V
import blenderbim
import blenderbim.core.root
import blenderbim.tool as tool
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.model.door import bm_sort_out_geom
@@ -20,7 +20,11 @@ import bpy
import bmesh
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.representation
import ifcopenshell.util.unit
import blenderbim
import blenderbim.core.root
import blenderbim.tool as tool
from blenderbim.bim.helper import convert_property_group_from_si
from blenderbim.bim.module.model.door import bm_sort_out_geom
@@ -176,7 +176,6 @@ class DumbSlabGenerator:
obj=obj,
ifc_class=ifc_class,
should_add_representation=False,
context=self.body_context,
)
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=self.relating_type)
@@ -20,7 +20,11 @@ import bpy
import json
import bmesh
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.representation
import ifcopenshell.util.unit
import blenderbim
import blenderbim.core.root
import blenderbim.tool as tool
from mathutils import Vector
from bmesh.types import BMVert
@@ -217,7 +221,6 @@ class BIM_OT_add_clever_stair(bpy.types.Operator, tool.Ifc.Operator):
collection = context.view_layer.active_layer_collection.collection
collection.objects.link(obj)
body_context = ifcopenshell.util.representation.get_context(ifc_file, "Model", "Body", "MODEL_VIEW")
element = blenderbim.core.root.assign_class(
tool.Ifc,
tool.Collector,
@@ -225,7 +228,6 @@ class BIM_OT_add_clever_stair(bpy.types.Operator, tool.Ifc.Operator):
obj=obj,
ifc_class="IfcStairFlight",
should_add_representation=False,
context=body_context,
)
if tool.Ifc.get_schema() != "IFC2X3":
element.PredefinedType = "STRAIGHT"
@@ -607,7 +607,6 @@ class DumbWallGenerator:
obj=obj,
ifc_class=ifc_class,
should_add_representation=False,
context=self.body_context,
)
ifcopenshell.api.run("type.assign_type", self.file, related_objects=[element], relating_type=self.relating_type)
if self.axis_context:
@@ -26,6 +26,11 @@ import blenderbim.tool as tool
import blenderbim.core.root
import blenderbim.core.geometry
from ifcopenshell.api.geometry.add_window_representation import DEFAULT_PANEL_SCHEMAS
import ifcopenshell.api
import ifcopenshell.util.element
import ifcopenshell.util.representation
import ifcopenshell.util.shape_builder
import ifcopenshell.util.unit
from ifcopenshell.util.shape_builder import V
from bmesh.types import BMVert
from mathutils import Vector
@@ -22,6 +22,7 @@ import ifcopenshell.util.element
import ifcopenshell.util.schema
import ifcopenshell.util.representation
import ifcopenshell.util.type
import ifcopenshell.util.unit
import ifcopenshell.api
import blenderbim.tool as tool
import blenderbim.core.geometry
@@ -454,7 +455,6 @@ class AddType(bpy.types.Operator, tool.Ifc.Operator):
predefined_type=predefined_type,
ifc_class="IfcStairFlightType",
should_add_representation=False,
context=body,
)
tool.Blender.select_and_activate_single_object(context, obj)
bpy.ops.bim.add_stair()
@@ -21,6 +21,7 @@ import ifcopenshell.api
import ifcopenshell.util.representation
import blenderbim.tool as tool
import blenderbim.core.geometry
import blenderbim.core.root
from blenderbim.bim.ifc import IfcStore
from blenderbim.bim.module.model.opening import FilledOpeningGenerator
+9 -1
View File
@@ -16,8 +16,16 @@
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import TYPE_CHECKING, Optional
def create_project(ifc, project, schema=None, template=None):
if TYPE_CHECKING:
import bpy
import ifcopenshell
import blenderbim.tool as tool
def create_project(ifc: tool.Ifc, project: tool.Project, schema: str, template: Optional[str] = None) -> None:
if ifc.get():
return
+161 -93
View File
@@ -16,103 +16,115 @@
# You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Union
def add_work_plan(ifc):
if TYPE_CHECKING:
import bpy
import ifcopenshell
import blenderbim.tool as tool
def add_work_plan(ifc: tool.Ifc) -> ifcopenshell.entity_instance:
return ifc.run("sequence.add_work_plan")
def remove_work_plan(ifc, work_plan=None):
def remove_work_plan(ifc: tool.Ifc, work_plan: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.remove_work_plan", work_plan=work_plan)
def enable_editing_work_plan(sequence, work_plan=None):
def enable_editing_work_plan(sequence: tool.Sequence, work_plan: ifcopenshell.entity_instance) -> None:
sequence.load_work_plan_attributes(work_plan)
sequence.enable_editing_work_plan(work_plan)
def disable_editing_work_plan(sequence):
def disable_editing_work_plan(sequence: tool.Sequence) -> None:
sequence.disable_editing_work_plan()
def edit_work_plan(ifc, sequence, work_plan=None):
def edit_work_plan(ifc: tool.Ifc, sequence: tool.Sequence, work_plan: ifcopenshell.entity_instance) -> None:
attributes = sequence.get_work_plan_attributes()
ifc.run("sequence.edit_work_plan", work_plan=work_plan, attributes=attributes)
sequence.disable_editing_work_plan()
def edit_work_schedule(ifc, sequence, work_schedule=None):
def edit_work_schedule(ifc: tool.Ifc, sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
attributes = sequence.get_work_schedule_attributes()
ifc.run("sequence.edit_work_schedule", work_schedule=work_schedule, attributes=attributes)
sequence.disable_editing_work_schedule()
def enable_editing_work_plan_schedules(sequence, work_plan=None):
def enable_editing_work_plan_schedules(
sequence: tool.Sequence, work_plan: Optional[ifcopenshell.entity_instance] = None
) -> None:
sequence.enable_editing_work_plan_schedules(work_plan)
def add_work_schedule(ifc, sequence, name=None):
def add_work_schedule(ifc: tool.Ifc, sequence: tool.Sequence, name: str) -> ifcopenshell.entity_instance:
predefined_type, object_type = sequence.get_user_predefined_type()
return ifc.run("sequence.add_work_schedule", name=name, predefined_type=predefined_type, object_type=object_type)
def remove_work_schedule(ifc, work_schedule=None):
def remove_work_schedule(ifc: tool.Ifc, work_schedule: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.remove_work_schedule", work_schedule=work_schedule)
def assign_work_schedule(ifc, work_plan=None, work_schedule=None):
def assign_work_schedule(
ifc: tool.Ifc, work_plan: ifcopenshell.entity_instance, work_schedule: ifcopenshell.entity_instance
) -> Union[ifcopenshell.entity_instance, None]:
if work_schedule:
return ifc.run("aggregate.assign_object", relating_object=work_plan, products=[work_schedule])
def unassign_work_schedule(ifc, work_schedule=None):
def unassign_work_schedule(ifc: tool.Ifc, work_schedule: ifcopenshell.entity_instance) -> None:
ifc.run("aggregate.unassign_object", products=[work_schedule])
def enable_editing_work_schedule(sequence, work_schedule=None):
def enable_editing_work_schedule(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
sequence.load_work_schedule_attributes(work_schedule)
sequence.enable_editing_work_schedule(work_schedule)
def enable_editing_work_schedule_tasks(sequence, work_schedule=None):
def enable_editing_work_schedule_tasks(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
sequence.enable_editing_work_schedule_tasks(work_schedule)
sequence.load_task_tree(work_schedule)
sequence.load_task_properties()
def load_task_tree(sequence, work_schedule):
def load_task_tree(sequence: tool.Sequence, work_schedule) -> None:
sequence.load_task_tree(work_schedule)
sequence.load_task_properties()
def expand_task(sequence, task=None):
def expand_task(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
sequence.expand_task(task)
work_schedule = sequence.get_active_work_schedule()
sequence.load_task_tree(work_schedule)
sequence.load_task_properties()
def expand_all_tasks(sequence):
def expand_all_tasks(sequence: tool.Sequence) -> None:
sequence.expand_all_tasks()
work_schedule = sequence.get_active_work_schedule()
sequence.load_task_tree(work_schedule)
sequence.load_task_properties()
def contract_task(sequence, task=None):
def contract_task(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
sequence.contract_task(task)
work_schedule = sequence.get_active_work_schedule()
sequence.load_task_tree(work_schedule)
sequence.load_task_properties()
def contract_all_tasks(sequence):
def contract_all_tasks(sequence: tool.Sequence) -> None:
sequence.contract_all_tasks()
work_schedule = sequence.get_active_work_schedule()
sequence.load_task_tree(work_schedule)
sequence.load_task_properties()
def remove_task(ifc, sequence, task=None):
def remove_task(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.remove_task", task=task)
work_schedule = sequence.get_active_work_schedule()
sequence.load_task_tree(work_schedule)
@@ -120,44 +132,46 @@ def remove_task(ifc, sequence, task=None):
sequence.disable_selecting_deleted_task()
def load_task_properties(sequence):
def load_task_properties(sequence: tool.Sequence) -> None:
sequence.load_task_properties()
def disable_editing_work_schedule(sequence):
def disable_editing_work_schedule(sequence: tool.Sequence) -> None:
sequence.disable_editing_work_schedule()
def add_summary_task(ifc, sequence, work_schedule=None):
def add_summary_task(ifc: tool.Ifc, sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.add_task", work_schedule=work_schedule)
sequence.load_task_tree(work_schedule)
sequence.load_task_properties()
def add_task(ifc, sequence, parent_task=None):
def add_task(
ifc: tool.Ifc, sequence: tool.Sequence, parent_task: Optional[ifcopenshell.entity_instance] = None
) -> None:
ifc.run("sequence.add_task", parent_task=parent_task)
work_schedule = sequence.get_active_work_schedule()
sequence.load_task_tree(work_schedule)
sequence.load_task_properties()
def enable_editing_task(sequence, task=None):
def enable_editing_task(sequence, task=None) -> None:
sequence.enable_editing_task(task)
def enable_editing_task_attributes(sequence, task=None):
def enable_editing_task_attributes(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
sequence.load_task_attributes(task)
sequence.enable_editing_task_attributes(task)
def edit_task(ifc, sequence, task=None):
def edit_task(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
attributes = sequence.get_task_attributes()
ifc.run("sequence.edit_task", task=task, attributes=attributes)
sequence.load_task_properties(task=task)
sequence.disable_editing_task()
def copy_task_attribute(ifc, sequence, attribute_name=None):
def copy_task_attribute(ifc: tool.Ifc, sequence: tool.Sequence, attribute_name: str) -> None:
for task in sequence.get_checked_tasks():
ifc.run(
"sequence.edit_task",
@@ -167,18 +181,18 @@ def copy_task_attribute(ifc, sequence, attribute_name=None):
sequence.load_task_properties(task)
def duplicate_task(ifc, sequence, task=None):
def duplicate_task(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.duplicate_task", task=task)
work_schedule = sequence.get_active_work_schedule()
sequence.load_task_tree(work_schedule)
sequence.load_task_properties()
def disable_editing_task(sequence):
def disable_editing_task(sequence: tool.Sequence) -> None:
sequence.disable_editing_task()
def enable_editing_task_time(ifc, sequence, task=None):
def enable_editing_task_time(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
task_time = sequence.get_task_time(task)
if task_time is None:
task_time = ifc.run("sequence.add_task_time", task=task)
@@ -186,7 +200,7 @@ def enable_editing_task_time(ifc, sequence, task=None):
sequence.enable_editing_task_time(task)
def edit_task_time(ifc, sequence, resource, task_time=None):
def edit_task_time(ifc: tool.Ifc, sequence: tool.Sequence, resource, task_time: ifcopenshell.entity_instance) -> None:
attributes = sequence.get_task_time_attributes()
# TODO: nasty loop goes on when calendar props are messed up
ifc.run("sequence.edit_task_time", task_time=task_time, attributes=attributes)
@@ -196,59 +210,83 @@ def edit_task_time(ifc, sequence, resource, task_time=None):
resource.load_resource_properties()
def assign_predecessor(ifc, sequence, task=None):
def assign_predecessor(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
predecessor_task = sequence.get_highlighted_task()
ifc.run("sequence.assign_sequence", relating_process=task, related_process=predecessor_task)
sequence.load_task_properties()
def unassign_predecessor(ifc, sequence, task=None):
def unassign_predecessor(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
predecessor_task = sequence.get_highlighted_task()
ifc.run("sequence.unassign_sequence", relating_process=task, related_process=predecessor_task)
sequence.load_task_properties()
def assign_successor(ifc, sequence, task=None):
def assign_successor(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
successor_task = sequence.get_highlighted_task()
ifc.run("sequence.assign_sequence", relating_process=successor_task, related_process=task)
sequence.load_task_properties()
def unassign_successor(ifc, sequence, task=None):
def unassign_successor(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
successor_task = sequence.get_highlighted_task()
ifc.run("sequence.unassign_sequence", relating_process=successor_task, related_process=task)
sequence.load_task_properties()
def assign_products(ifc, sequence, spatial, task=None, products=None):
def assign_products(
ifc: tool.Ifc,
sequence: tool.Sequence,
spatial: tool.Spatial,
task: ifcopenshell.entity_instance,
products: Optional[list[ifcopenshell.entity_instance]] = None,
) -> None:
for product in products or spatial.get_selected_products() or []:
ifc.run("sequence.assign_product", relating_product=product, related_object=task)
outputs = sequence.get_task_outputs(task)
sequence.load_task_outputs(outputs)
def unassign_products(ifc, sequence, spatial, task=None, products=None):
def unassign_products(
ifc: tool.Ifc,
sequence: tool.Sequence,
spatial: tool.Spatial,
task: ifcopenshell.entity_instance,
products: Optional[list[ifcopenshell.entity_instance]] = None,
) -> None:
for product in products or spatial.get_selected_products() or []:
ifc.run("sequence.unassign_product", relating_product=product, related_object=task)
outputs = sequence.get_task_outputs(task)
sequence.load_task_outputs(outputs)
def assign_input_products(ifc, sequence, spatial, task=None, products=None):
def assign_input_products(
ifc: tool.Ifc,
sequence: tool.Sequence,
spatial: tool.Spatial,
task: ifcopenshell.entity_instance,
products: Optional[list[ifcopenshell.entity_instance]] = None,
) -> None:
for product in products or spatial.get_selected_products() or []:
ifc.run("sequence.assign_process", relating_process=task, related_object=product)
inputs = sequence.get_task_inputs(task)
sequence.load_task_inputs(inputs)
def unassign_input_products(ifc, sequence, spatial, task=None, products=None):
def unassign_input_products(
ifc: tool.Ifc,
sequence: tool.Sequence,
spatial: tool.Spatial,
task: ifcopenshell.entity_instance,
products: Optional[list[ifcopenshell.entity_instance]] = None,
) -> None:
for product in products or spatial.get_selected_products() or []:
ifc.run("sequence.unassign_process", relating_process=task, related_object=product)
inputs = sequence.get_task_inputs(task)
sequence.load_task_inputs(inputs)
def assign_resource(ifc, sequence, resource_tool, task=None):
def assign_resource(ifc: tool.Ifc, sequence: tool.Sequence, resource_tool, task: ifcopenshell.entity_instance) -> None:
resource = resource_tool.get_highlighted_resource()
sub_resource = ifc.run(
"resource.add_resource",
@@ -261,59 +299,67 @@ def assign_resource(ifc, sequence, resource_tool, task=None):
resource_tool.load_resources()
def unassign_resource(ifc, sequence, resource_tool, task=None, resource=None):
def unassign_resource(
ifc: tool.Ifc,
sequence: tool.Sequence,
resource_tool,
task: ifcopenshell.entity_instance,
resource: ifcopenshell.entity_instance,
) -> None:
ifc.run("sequence.unassign_process", relating_process=task, related_object=resource)
ifc.run("resource.remove_resource", resource=resource)
sequence.load_task_resources(task)
resource_tool.load_resources()
def remove_work_calendar(ifc, work_calendar=None):
def remove_work_calendar(ifc: tool.Ifc, work_calendar: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.remove_work_calendar", work_calendar=work_calendar)
def add_work_calendar(ifc):
def add_work_calendar(ifc: tool.Ifc) -> ifcopenshell.entity_instance:
return ifc.run("sequence.add_work_calendar")
def edit_work_calendar(ifc, sequence, work_calendar=None):
def edit_work_calendar(ifc: tool.Ifc, sequence: tool.Sequence, work_calendar: ifcopenshell.entity_instance) -> None:
attributes = sequence.get_work_calendar_attributes()
ifc.run("sequence.edit_work_calendar", work_calendar=work_calendar, attributes=attributes)
sequence.disable_editing_work_calendar()
sequence.load_task_properties()
def enable_editing_work_calendar(sequence, work_calendar=None):
def enable_editing_work_calendar(sequence: tool.Sequence, work_calendar: ifcopenshell.entity_instance) -> None:
sequence.load_work_calendar_attributes(work_calendar)
sequence.enable_editing_work_calendar(work_calendar)
def disable_editing_work_calendar(sequence):
def disable_editing_work_calendar(sequence: tool.Sequence) -> None:
sequence.disable_editing_work_calendar()
def enable_editing_work_calendar_times(sequence, work_calendar=None):
def enable_editing_work_calendar_times(sequence: tool.Sequence, work_calendar: ifcopenshell.entity_instance) -> None:
sequence.enable_editing_work_calendar_times(work_calendar)
def add_work_time(ifc, work_calendar=None, time_type=None):
def add_work_time(
ifc: tool.Ifc, work_calendar: ifcopenshell.entity_instance, time_type: ifcopenshell.entity_instance
) -> ifcopenshell.entity_instance:
return ifc.run("sequence.add_work_time", work_calendar=work_calendar, time_type=time_type)
def enable_editing_work_time(sequence, work_time=None):
def enable_editing_work_time(sequence: tool.Sequence, work_time: ifcopenshell.entity_instance) -> None:
sequence.load_work_time_attributes(work_time)
sequence.enable_editing_work_time(work_time)
def disable_editing_work_time(sequence):
def disable_editing_work_time(sequence: tool.Sequence) -> None:
sequence.disable_editing_work_time()
def remove_work_time(ifc, work_time=None):
def remove_work_time(ifc: tool.Ifc, work_time=None) -> None:
ifc.run("sequence.remove_work_time", work_time=work_time)
def edit_work_time(ifc, sequence):
def edit_work_time(ifc: tool.Ifc, sequence: tool.Sequence) -> None:
work_time = sequence.get_active_work_time()
ifc.run("sequence.edit_work_time", work_time=work_time, attributes=sequence.get_work_time_attributes())
recurrence_pattern = work_time.RecurrencePattern
@@ -326,100 +372,118 @@ def edit_work_time(ifc, sequence):
sequence.disable_editing_work_time()
def assign_recurrence_pattern(ifc, work_time=None, recurrence_type=None):
def assign_recurrence_pattern(
ifc: tool.Ifc, work_time: ifcopenshell.entity_instance, recurrence_type: ifcopenshell.entity_instance
) -> ifcopenshell.entity_instance:
return ifc.run("sequence.assign_recurrence_pattern", parent=work_time, recurrence_type=recurrence_type)
def unassign_recurrence_pattern(ifc, recurrence_pattern=None):
def unassign_recurrence_pattern(ifc: tool.Ifc, recurrence_pattern: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.unassign_recurrence_pattern", recurrence_pattern=recurrence_pattern)
def add_time_period(ifc, sequence, recurrence_pattern=None):
def add_time_period(ifc: tool.Ifc, sequence: tool.Sequence, recurrence_pattern: ifcopenshell.entity_instance) -> None:
start_time, end_time = sequence.get_recurrence_pattern_times()
ifc.run("sequence.add_time_period", recurrence_pattern=recurrence_pattern, start_time=start_time, end_time=end_time)
sequence.reset_time_period()
def remove_time_period(ifc, time_period=None):
def remove_time_period(ifc: tool.Ifc, time_period: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.remove_time_period", time_period=time_period)
def enable_editing_task_calendar(sequence, task=None):
def enable_editing_task_calendar(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
sequence.enable_editing_task_calendar(task)
def edit_task_calendar(ifc, sequence, task=None, work_calendar=None):
def edit_task_calendar(
ifc: tool.Ifc,
sequence: tool.Sequence,
task: ifcopenshell.entity_instance,
work_calendar: ifcopenshell.entity_instance,
) -> None:
ifc.run("control.assign_control", relating_control=work_calendar, related_object=task)
ifc.run("sequence.cascade_schedule", task=task)
sequence.load_task_properties()
def remove_task_calendar(ifc, sequence, task=None, work_calendar=None):
def remove_task_calendar(
ifc: tool.Ifc,
sequence: tool.Sequence,
task: ifcopenshell.entity_instance,
work_calendar: ifcopenshell.entity_instance,
) -> None:
ifc.run("control.unassign_control", relating_control=work_calendar, related_object=task)
ifc.run("sequence.cascade_schedule", task=task)
sequence.load_task_properties()
def enable_editing_task_sequence(sequence):
def enable_editing_task_sequence(sequence: tool.Sequence) -> None:
sequence.enable_editing_task_sequence()
sequence.load_task_properties()
def disable_editing_task_time(sequence):
def disable_editing_task_time(sequence: tool.Sequence) -> None:
sequence.disable_editing_task_time()
def enable_editing_sequence_attributes(sequence, rel_sequence=None):
def enable_editing_sequence_attributes(sequence: tool.Sequence, rel_sequence: ifcopenshell.entity_instance) -> None:
sequence.enable_editing_rel_sequence_attributes(rel_sequence)
sequence.load_rel_sequence_attributes(rel_sequence)
def enable_editing_sequence_lag_time(sequence, rel_sequence=None, lag_time=None):
def enable_editing_sequence_lag_time(
sequence: tool.Sequence, rel_sequence: ifcopenshell.entity_instance, lag_time: ifcopenshell.entity_instance
) -> None:
sequence.load_lag_time_attributes(lag_time)
sequence.enable_editing_sequence_lag_time(rel_sequence)
def unassign_lag_time(ifc, sequence, rel_sequence=None):
def unassign_lag_time(ifc: tool.Ifc, sequence: tool.Sequence, rel_sequence: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.unassign_lag_time", rel_sequence=rel_sequence)
sequence.load_task_properties()
def assign_lag_time(ifc, rel_sequence=None):
def assign_lag_time(ifc: tool.Ifc, rel_sequence: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.assign_lag_time", rel_sequence=rel_sequence, lag_value="P1D")
def edit_sequence_attributes(ifc, sequence, rel_sequence=None):
def edit_sequence_attributes(
ifc: tool.Ifc, sequence: tool.Sequence, rel_sequence: ifcopenshell.entity_instance
) -> None:
attributes = sequence.get_rel_sequence_attributes()
ifc.run("sequence.edit_sequence", rel_sequence=rel_sequence, attributes=attributes)
sequence.disable_editing_rel_sequence()
sequence.load_task_properties()
def edit_sequence_lag_time(ifc, sequence, lag_time=None):
def edit_sequence_lag_time(ifc: tool.Ifc, sequence: tool.Sequence, lag_time: ifcopenshell.entity_instance) -> None:
attributes = sequence.get_lag_time_attributes()
ifc.run("sequence.edit_lag_time", lag_time=lag_time, attributes=attributes)
sequence.disable_editing_rel_sequence()
sequence.load_task_properties()
def disable_editing_rel_sequence(sequence):
def disable_editing_rel_sequence(sequence: tool.Sequence) -> None:
sequence.disable_editing_rel_sequence()
def select_task_outputs(sequence, spatial, task=None):
def select_task_outputs(sequence: tool.Sequence, spatial: tool.Spatial, task: ifcopenshell.entity_instance) -> None:
spatial.select_products(products=sequence.get_task_outputs(task))
def select_task_inputs(sequence, spatial, task=None):
def select_task_inputs(sequence: tool.Sequence, spatial: tool.Spatial, task: ifcopenshell.entity_instance) -> None:
spatial.select_products(products=sequence.get_task_inputs(task))
def select_work_schedule_products(sequence, spatial, work_schedule=None):
def select_work_schedule_products(
sequence: tool.Sequence, spatial: tool.Spatial, work_schedule: ifcopenshell.entity_instance
) -> None:
products = sequence.get_work_schedule_products(work_schedule)
spatial.select_products(products)
def select_unassigned_work_schedule_products(ifc, sequence, spatial):
def select_unassigned_work_schedule_products(ifc: tool.Ifc, sequence: tool.Sequence, spatial: tool.Spatial) -> None:
spatial.deselect_objects()
products = ifc.get().by_type("IfcElement")
work_schedule = sequence.get_active_work_schedule()
@@ -428,11 +492,11 @@ def select_unassigned_work_schedule_products(ifc, sequence, spatial):
spatial.select_products(selection)
def recalculate_schedule(ifc, work_schedule=None):
def recalculate_schedule(ifc: tool.Ifc, work_schedule: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.recalculate_schedule", work_schedule=work_schedule)
def add_task_column(sequence, column_type=None, name=None, data_type=None):
def add_task_column(sequence: tool.Sequence, column_type: str, name: str, data_type: str) -> None:
sequence.add_task_column(column_type, name, data_type)
work_schedule = sequence.get_active_work_schedule()
if work_schedule:
@@ -440,11 +504,11 @@ def add_task_column(sequence, column_type=None, name=None, data_type=None):
sequence.load_task_properties()
def remove_task_column(sequence, name=None):
def remove_task_column(sequence: tool.Sequence, name: str) -> None:
sequence.remove_task_column(name)
def set_task_sort_column(sequence, column=None):
def set_task_sort_column(sequence: tool.Sequence, column: str) -> None:
sequence.set_task_sort_column(column)
work_schedule = sequence.get_active_work_schedule()
if work_schedule:
@@ -452,7 +516,7 @@ def set_task_sort_column(sequence, column=None):
sequence.load_task_properties()
def calculate_task_duration(ifc, sequence, task=None):
def calculate_task_duration(ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> None:
ifc.run("sequence.calculate_task_duration", task=task)
work_schedule = sequence.get_active_work_schedule()
if work_schedule:
@@ -460,11 +524,11 @@ def calculate_task_duration(ifc, sequence, task=None):
sequence.load_task_properties()
def load_animation_color_scheme(sequence, scheme):
def load_animation_color_scheme(sequence: tool.Sequence, scheme: Union[ifcopenshell.entity_instance, None]) -> None:
sequence.load_animation_color_scheme(scheme)
def go_to_task(sequence, task=None):
def go_to_task(sequence: tool.Sequence, task: ifcopenshell.entity_instance) -> Union[None, str]:
work_schedule = sequence.get_work_schedule(task)
is_work_schedule_active = sequence.is_work_schedule_active(work_schedule)
if is_work_schedule_active:
@@ -473,7 +537,7 @@ def go_to_task(sequence, task=None):
return "Work schedule is not active"
def highlight_product_related_task(sequence, spatial, product_type=None):
def highlight_product_related_task(sequence: tool.Sequence, spatial: tool.Spatial, product_type=None) -> None:
products = spatial.get_selected_products()
if products:
if product_type == "Output":
@@ -487,26 +551,26 @@ def highlight_product_related_task(sequence, spatial, product_type=None):
sequence.go_to_task(task)
def guess_date_range(sequence, work_schedule=None):
def guess_date_range(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
start, finish = sequence.guess_date_range(work_schedule)
sequence.update_visualisation_date(start, finish)
def setup_default_task_columns(sequence):
def setup_default_task_columns(sequence: tool.Sequence) -> None:
sequence.setup_default_task_columns()
def add_task_bars(sequence):
def add_task_bars(sequence: tool.Sequence) -> None:
tasks = sequence.get_animation_bar_tasks()
if tasks:
sequence.create_bars(tasks)
def load_default_animation_color_scheme(sequence):
def load_default_animation_color_scheme(sequence: tool.Sequence) -> None:
sequence.load_default_animation_color_scheme()
def visualise_work_schedule_date_range(sequence, work_schedule=None):
def visualise_work_schedule_date_range(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
sequence.clear_objects_animation(include_blender_objects=False)
settings = sequence.get_animation_settings()
if settings:
@@ -520,7 +584,7 @@ def visualise_work_schedule_date_range(sequence, work_schedule=None):
sequence.set_object_shading()
def visualise_work_schedule_date(sequence, work_schedule=None):
def visualise_work_schedule_date(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
sequence.clear_objects_animation(include_blender_objects=False)
start_date = sequence.get_start_date()
product_states = sequence.process_construction_state(work_schedule, start_date)
@@ -528,12 +592,12 @@ def visualise_work_schedule_date(sequence, work_schedule=None):
sequence.set_object_shading()
def generate_gantt_chart(sequence, work_schedule):
def generate_gantt_chart(sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance) -> None:
json = sequence.create_tasks_json(work_schedule)
sequence.generate_gantt_browser_chart(json, work_schedule)
def load_product_related_tasks(sequence, product=None):
def load_product_related_tasks(sequence: tool.Sequence, product: ifcopenshell.entity_instance) -> Union[None, str]:
filter_by_schedule = sequence.is_filter_by_active_schedule()
if filter_by_schedule:
work_schedule = sequence.get_active_work_schedule()
@@ -546,7 +610,9 @@ def load_product_related_tasks(sequence, product=None):
sequence.load_product_related_tasks(task_inputs, task_ouputs)
def reorder_task_nesting(ifc, sequence, task, new_index):
def reorder_task_nesting(
ifc: tool.Ifc, sequence: tool.Sequence, task: ifcopenshell.entity_instance, new_index: int
) -> Union[None, str]:
is_sorting_enabled = sequence.is_sorting_enabled()
is_sort_reversed = sequence.is_sort_reversed()
if is_sorting_enabled or is_sort_reversed:
@@ -558,17 +624,19 @@ def reorder_task_nesting(ifc, sequence, task, new_index):
sequence.load_task_properties()
def create_baseline(ifc, sequence, work_schedule, name):
def create_baseline(
ifc: tool.Ifc, sequence: tool.Sequence, work_schedule: ifcopenshell.entity_instance, name: Optional[str] = None
) -> None:
ifc.run("sequence.create_baseline", work_schedule=work_schedule, name=name)
def clear_previous_animation(sequence):
def clear_previous_animation(sequence: tool.Sequence) -> None:
sequence.clear_objects_animation(include_blender_objects=False)
def add_animation_camera(sequence):
def add_animation_camera(sequence: tool.Sequence) -> None:
sequence.add_animation_camera()
def save_animation_color_scheme(sequence, name):
def save_animation_color_scheme(sequence: tool.Sequence, name: str) -> None:
sequence.save_animation_color_scheme(name)
+10 -5
View File
@@ -2,6 +2,7 @@ import os
import bpy
import blenderbim.core.tool
import blenderbim.tool as tool
import ifcopenshell.util.element
import ifcopenshell.util.date
import ifcopenshell.util.cost
import ifcopenshell.util.unit
@@ -188,7 +189,7 @@ class Cost(blenderbim.core.tool.Cost):
new.name = related_object.Name or "Unnamed"
@classmethod
def load_cost_item_quantity_assignments(cls, cost_item, related_object_type):
def load_cost_item_quantity_assignments(cls, cost_item: ifcopenshell.entity_instance, related_object_type):
def create_list_items(collection, cost_item, is_deep):
products = cls.get_cost_item_assignments(cost_item, filter_by_type=related_object_type, is_deep=False)
for product in products:
@@ -217,12 +218,16 @@ class Cost(blenderbim.core.tool.Cost):
create_list_items(props.cost_item_resources, cost_item, is_deep)
@classmethod
def calculate_parametric_quantity(cls, cost_item=None, product=None):
def calculate_parametric_quantity(
cls, cost_item: ifcopenshell.entity_instance, product: ifcopenshell.entity_instance
) -> tuple[float, Union[str, None]]:
quantities, unit = cls.get_assigned_quantities(cost_item, product)
return sum(quantity[3] for quantity in quantities), unit
@classmethod
def get_assigned_quantities(cls, cost_item, product):
def get_assigned_quantities(
cls, cost_item: ifcopenshell.entity_instance, product: ifcopenshell.entity_instance
) -> tuple[list[ifcopenshell.entity_instance], Union[str, None]]:
selected_quantitites = []
unit = ""
for quantities in ifcopenshell.util.element.get_psets(product, qtos_only=True).values():
@@ -465,13 +470,13 @@ class Cost(blenderbim.core.tool.Cost):
print("Import finished in {:.2f} seconds".format(time.time() - start))
@classmethod
def add_cost_column(cls, name):
def add_cost_column(cls, name: str) -> None:
props = bpy.context.scene.BIMCostProperties
new = props.columns.add()
new.name = name
@classmethod
def remove_cost_column(cls, name):
def remove_cost_column(cls, name: str) -> None:
props = bpy.context.scene.BIMCostProperties
props.columns.remove(props.columns.find(name))
+3 -2
View File
@@ -27,6 +27,7 @@ import ifcopenshell.util.element
import ifcopenshell.util.unit
import ifcopenshell.util.placement
import ifcopenshell.util.representation
import blenderbim.core.geometry
import blenderbim.core.tool
import blenderbim.tool as tool
import blenderbim.core.geometry as geometry
@@ -39,7 +40,7 @@ from blenderbim.bim.module.geometry.helper import Helper
from blenderbim.bim.module.model.data import AuthoringData, RailingData, RoofData, WindowData, DoorData
from blenderbim.bim.module.model.opening import FilledOpeningGenerator
from ifcopenshell.util.shape_builder import V, ShapeBuilder
from typing import Optional, Union, TypeVar, Any
from typing import Optional, Union, TypeVar, Any, Iterable
T = TypeVar("T")
@@ -904,7 +905,7 @@ class Model(blenderbim.core.tool.Model):
return Matrix(placement)
@classmethod
def reload_body_representation(cls, obj_or_objects):
def reload_body_representation(cls, obj_or_objects: Union[bpy.types.Object, Iterable[bpy.types.Object]]) -> None:
"""Update body representation including all decomposed objects"""
if isinstance(obj_or_objects, collections.abc.Iterable):
objects = set(obj_or_objects)
+14 -8
View File
@@ -19,18 +19,24 @@
import os
import bpy
import ifcopenshell
import ifcopenshell.util.representation
import ifcopenshell.util.unit
import blenderbim.core.aggregate
import blenderbim.core.context
import blenderbim.core.tool
import blenderbim.core.root
import blenderbim.core.unit
import blenderbim.core.owner
import blenderbim.bim.schema
import blenderbim.tool as tool
from blenderbim.bim.ifc import IfcStore
from pathlib import Path
from typing import Optional
class Project(blenderbim.core.tool.Project):
@classmethod
def append_all_types_from_template(cls, template):
def append_all_types_from_template(cls, template: str) -> None:
# TODO refactor
filepath = os.path.join(bpy.context.scene.BIMProperties.data_dir, "templates", "projects", template)
bpy.ops.bim.select_library_file(filepath=filepath)
@@ -96,13 +102,13 @@ class Project(blenderbim.core.tool.Project):
@classmethod
def run_root_assign_class(
cls,
obj=None,
ifc_class=None,
predefined_type=None,
should_add_representation=True,
context=None,
ifc_representation_class=None,
):
obj: bpy.types.Object,
ifc_class: str,
predefined_type: Optional[str] = None,
should_add_representation: bool = True,
context: Optional[ifcopenshell.entity_instance] = None,
ifc_representation_class: Optional[str] = None,
) -> ifcopenshell.entity_instance:
return blenderbim.core.root.assign_class(
tool.Ifc,
tool.Collector,
+102 -89
View File
@@ -36,11 +36,12 @@ import blenderbim.bim.helper
import blenderbim.bim.module.sequence.helper as helper
from dateutil import parser
from datetime import datetime
from typing import Optional, Any, Union
class Sequence(blenderbim.core.tool.Sequence):
@classmethod
def get_work_plan_attributes(cls):
def get_work_plan_attributes(cls) -> dict[str, Any]:
def callback(attributes, prop):
if "Date" in prop.name or "Time" in prop.name:
if prop.is_null:
@@ -59,7 +60,7 @@ class Sequence(blenderbim.core.tool.Sequence):
return blenderbim.bim.helper.export_attributes(props.work_plan_attributes, callback)
@classmethod
def load_work_plan_attributes(cls, work_plan):
def load_work_plan_attributes(cls, work_plan: ifcopenshell.entity_instance) -> None:
def callback(name, prop, data):
if name in ["CreationDate", "StartTime", "FinishTime"]:
prop.string_value = "" if prop.is_null else data[name]
@@ -70,23 +71,23 @@ class Sequence(blenderbim.core.tool.Sequence):
blenderbim.bim.helper.import_attributes2(work_plan, props.work_plan_attributes, callback)
@classmethod
def enable_editing_work_plan(cls, work_plan):
def enable_editing_work_plan(cls, work_plan: Union[ifcopenshell.entity_instance, None]) -> None:
if work_plan:
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = work_plan.id()
bpy.context.scene.BIMWorkPlanProperties.editing_type = "ATTRIBUTES"
@classmethod
def disable_editing_work_plan(cls):
def disable_editing_work_plan(cls) -> None:
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = 0
@classmethod
def enable_editing_work_plan_schedules(cls, work_plan):
def enable_editing_work_plan_schedules(cls, work_plan: Union[ifcopenshell.entity_instance, None]) -> None:
if work_plan:
bpy.context.scene.BIMWorkPlanProperties.active_work_plan_id = work_plan.id()
bpy.context.scene.BIMWorkPlanProperties.editing_type = "SCHEDULES"
@classmethod
def get_work_schedule_attributes(cls):
def get_work_schedule_attributes(cls) -> dict[str, Any]:
def callback(attributes, prop):
if "Date" in prop.name or "Time" in prop.name:
if prop.is_null:
@@ -105,7 +106,7 @@ class Sequence(blenderbim.core.tool.Sequence):
return blenderbim.bim.helper.export_attributes(props.work_schedule_attributes, callback)
@classmethod
def load_work_schedule_attributes(cls, work_schedule):
def load_work_schedule_attributes(cls, work_schedule: ifcopenshell.entity_instance) -> None:
def callback(name, prop, data):
if name in ["CreationDate", "StartTime", "FinishTime"]:
prop.string_value = "" if prop.is_null else data[name]
@@ -116,23 +117,23 @@ class Sequence(blenderbim.core.tool.Sequence):
blenderbim.bim.helper.import_attributes2(work_schedule, props.work_schedule_attributes, callback)
@classmethod
def enable_editing_work_schedule(cls, work_schedule):
def enable_editing_work_schedule(cls, work_schedule: ifcopenshell.entity_instance) -> None:
bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id = work_schedule.id()
bpy.context.scene.BIMWorkScheduleProperties.editing_type = "WORK_SCHEDULE"
@classmethod
def disable_editing_work_schedule(cls):
def disable_editing_work_schedule(cls) -> None:
bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id = 0
@classmethod
def enable_editing_work_schedule_tasks(cls, work_schedule):
def enable_editing_work_schedule_tasks(cls, work_schedule: Union[ifcopenshell.entity_instance, None]) -> None:
if work_schedule:
props = bpy.context.scene.BIMWorkScheduleProperties
props.active_work_schedule_id = work_schedule.id()
props.editing_type = "TASKS"
@classmethod
def load_task_tree(cls, work_schedule):
def load_task_tree(cls, work_schedule: ifcopenshell.entity_instance) -> None:
bpy.context.scene.BIMTaskTreeProperties.tasks.clear()
props = bpy.context.scene.BIMWorkScheduleProperties
cls.contracted_tasks = json.loads(props.contracted_tasks)
@@ -142,7 +143,7 @@ class Sequence(blenderbim.core.tool.Sequence):
cls.create_new_task_li(related_object_id, 0)
@classmethod
def get_sorted_tasks_ids(cls, tasks):
def get_sorted_tasks_ids(cls, tasks: list[ifcopenshell.entity_instance]) -> list[int]:
def get_sort_key(task):
# Sorting only applies to actual tasks, not the WBS
# for rel in task.IsNestedBy:
@@ -170,7 +171,7 @@ class Sequence(blenderbim.core.tool.Sequence):
return related_object_ids
@classmethod
def create_new_task_li(cls, related_object_id, level_index):
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()
new.ifc_definition_id = related_object_id
@@ -182,8 +183,9 @@ class Sequence(blenderbim.core.tool.Sequence):
for related_object_id in cls.get_sorted_tasks_ids(ifcopenshell.util.sequence.get_nested_tasks(task)):
cls.create_new_task_li(related_object_id, level_index + 1)
# TODO: task argument is never used?
@classmethod
def load_task_properties(cls, task=None):
def load_task_properties(cls, task: Optional[ifcopenshell.entity_instance] = None) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
task_props = bpy.context.scene.BIMTaskTreeProperties
tasks_with_visual_bar = cls.get_task_bar_list()
@@ -248,24 +250,24 @@ class Sequence(blenderbim.core.tool.Sequence):
props.is_task_update_enabled = True
@classmethod
def get_active_work_schedule(cls):
def get_active_work_schedule(cls) -> Union[ifcopenshell.entity_instance, None]:
if not bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id:
return None
return tool.Ifc.get().by_id(bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id)
@classmethod
def expand_task(cls, task):
def expand_task(cls, task: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
contracted_tasks = json.loads(props.contracted_tasks)
contracted_tasks.remove(task.id())
props.contracted_tasks = json.dumps(contracted_tasks)
@classmethod
def expand_all_tasks(cls):
def expand_all_tasks(cls) -> None:
bpy.context.scene.BIMWorkScheduleProperties.contracted_tasks = json.dumps([])
@classmethod
def contract_all_tasks(cls):
def contract_all_tasks(cls) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
contracted_tasks = json.loads(props.contracted_tasks)
for task_item in bpy.context.scene.BIMTaskTreeProperties.tasks:
@@ -274,18 +276,18 @@ class Sequence(blenderbim.core.tool.Sequence):
props.contracted_tasks = json.dumps(contracted_tasks)
@classmethod
def contract_task(cls, task):
def contract_task(cls, task: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
contracted_tasks = json.loads(props.contracted_tasks)
contracted_tasks.append(task.id())
props.contracted_tasks = json.dumps(contracted_tasks)
@classmethod
def disable_work_schedule(cls):
def disable_work_schedule(cls) -> None:
bpy.context.scene.BIMWorkScheduleProperties.active_work_schedule_id = 0
@classmethod
def disable_selecting_deleted_task(cls):
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
@@ -294,7 +296,7 @@ class Sequence(blenderbim.core.tool.Sequence):
bpy.context.scene.BIMWorkScheduleProperties.active_task_time_id = 0
@classmethod
def get_checked_tasks(cls):
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
@@ -302,39 +304,39 @@ class Sequence(blenderbim.core.tool.Sequence):
] or []
@classmethod
def get_task_attribute_value(cls, attribute_name):
def get_task_attribute_value(cls, attribute_name: str) -> Any:
return bpy.context.scene.BIMWorkScheduleProperties.task_attributes.get(attribute_name).get_value()
@classmethod
def get_active_task(cls):
def get_active_task(cls) -> ifcopenshell.entity_instance:
return tool.Ifc.get().by_id(bpy.context.scene.BIMWorkScheduleProperties.active_task_id)
@classmethod
def get_active_work_time(cls):
def get_active_work_time(cls) -> ifcopenshell.entity_instance:
return tool.Ifc.get().by_id(bpy.context.scene.BIMWorkCalendarProperties.active_work_time_id)
@classmethod
def get_task_time(cls, task):
return task.TaskTime if task.TaskTime else None
def get_task_time(cls, task: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
return task.TaskTime or None
@classmethod
def load_task_attributes(cls, task):
def load_task_attributes(cls, task: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.task_attributes.clear()
blenderbim.bim.helper.import_attributes2(task, props.task_attributes)
@classmethod
def enable_editing_task_attributes(cls, task):
def enable_editing_task_attributes(cls, task: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.active_task_id = task.id()
props.editing_task_type = "ATTRIBUTES"
@classmethod
def get_task_attributes(cls):
def get_task_attributes(cls) -> dict[str, Any]:
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMWorkScheduleProperties.task_attributes)
@classmethod
def load_task_time_attributes(cls, task_time):
def load_task_time_attributes(cls, task_time: ifcopenshell.entity_instance) -> None:
def callback(name, prop, data):
if prop and prop.data_type == "string":
duration_props = bpy.context.scene.BIMWorkScheduleProperties.durations_attributes.add()
@@ -358,20 +360,20 @@ class Sequence(blenderbim.core.tool.Sequence):
blenderbim.bim.helper.import_attributes2(task_time, props.task_time_attributes, callback)
@classmethod
def enable_editing_task_time(cls, task):
def enable_editing_task_time(cls, task: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.active_task_id = task.id()
props.active_task_time_id = task.TaskTime.id()
props.editing_task_type = "TASKTIME"
@classmethod
def disable_editing_task(cls):
def disable_editing_task(cls) -> None:
bpy.context.scene.BIMWorkScheduleProperties.active_task_id = 0
bpy.context.scene.BIMWorkScheduleProperties.active_task_time_id = 0
bpy.context.scene.BIMWorkScheduleProperties.editing_task_type = ""
@classmethod
def get_task_time_attributes(cls):
def get_task_time_attributes(cls) -> dict[str, Any]:
def callback(attributes, prop):
if "Start" in prop.name or "Finish" in prop.name or prop.name == "StatusTime":
if prop.is_null:
@@ -400,7 +402,7 @@ class Sequence(blenderbim.core.tool.Sequence):
return blenderbim.bim.helper.export_attributes(props.task_time_attributes, callback)
@classmethod
def load_task_resources(cls, task):
def load_task_resources(cls, task: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
rprops = bpy.context.scene.BIMResourceProperties
props.task_resources.clear()
@@ -413,36 +415,38 @@ class Sequence(blenderbim.core.tool.Sequence):
rprops.is_resource_update_enabled = True
@classmethod
def get_task_inputs(cls, task):
def get_task_inputs(cls, task: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
is_deep = bpy.context.scene.BIMWorkScheduleProperties.show_nested_inputs
return ifcopenshell.util.sequence.get_task_inputs(task, is_deep)
@classmethod
def get_task_outputs(cls, task):
def get_task_outputs(cls, task: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
is_deep = bpy.context.scene.BIMWorkScheduleProperties.show_nested_outputs
return ifcopenshell.util.sequence.get_task_outputs(task, is_deep)
@classmethod
def are_entities_same_class(cls, entities):
def are_entities_same_class(cls, entities: list[ifcopenshell.entity_instance]) -> bool:
if not entities:
return False
if len(entities) == 1:
return True
first = entities[0]
first_class = entities[0].is_a()
for entity in entities:
if entity.is_a() != first.is_a():
if entity.is_a() != first_class:
return False
return True
@classmethod
def get_task_resources(cls, task):
def get_task_resources(
cls, task: Union[ifcopenshell.entity_instance, None]
) -> Union[list[ifcopenshell.entity_instance], None]:
if not task:
return
is_deep = bpy.context.scene.BIMWorkScheduleProperties.show_nested_resources
return ifcopenshell.util.sequence.get_task_resources(task, is_deep)
@classmethod
def load_task_inputs(cls, inputs):
def load_task_inputs(cls, inputs: list[ifcopenshell.entity_instance]) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.task_inputs.clear()
for input in inputs:
@@ -451,7 +455,7 @@ class Sequence(blenderbim.core.tool.Sequence):
new.name = input.Name or "Unnamed"
@classmethod
def load_task_outputs(cls, outputs):
def load_task_outputs(cls, outputs: list[ifcopenshell.entity_instance]) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.task_outputs.clear()
if outputs:
@@ -461,7 +465,7 @@ class Sequence(blenderbim.core.tool.Sequence):
new.name = output.Name or "Unnamed"
@classmethod
def get_highlighted_task(cls):
def get_highlighted_task(cls) -> Union[ifcopenshell.entity_instance, None]:
tasks = bpy.context.scene.BIMTaskTreeProperties.tasks
if len(tasks) and len(tasks) > bpy.context.scene.BIMWorkScheduleProperties.active_task_index:
return tool.Ifc.get().by_id(
@@ -469,11 +473,11 @@ class Sequence(blenderbim.core.tool.Sequence):
)
@classmethod
def get_direct_nested_tasks(cls, task):
def get_direct_nested_tasks(cls, task: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
return ifcopenshell.util.sequence.get_nested_tasks(task)
@classmethod
def get_direct_task_outputs(cls, task):
def get_direct_task_outputs(cls, task: ifcopenshell.entity_instance) -> list[ifcopenshell.entity_instance]:
return ifcopenshell.util.sequence.get_direct_task_outputs(task)
@classmethod
@@ -482,34 +486,34 @@ class Sequence(blenderbim.core.tool.Sequence):
return ifcopenshell.util.sequence.get_task_outputs(task, is_deep)
@classmethod
def enable_editing_work_calendar_times(cls, work_calendar):
def enable_editing_work_calendar_times(cls, work_calendar: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkCalendarProperties
props.active_work_calendar_id = work_calendar.id()
props.editing_type = "WORKTIMES"
@classmethod
def load_work_calendar_attributes(cls, work_calendar):
def load_work_calendar_attributes(cls, work_calendar: ifcopenshell.entity_instance) -> dict[str, Any]:
props = bpy.context.scene.BIMWorkCalendarProperties
props.work_calendar_attributes.clear()
return blenderbim.bim.helper.import_attributes2(work_calendar, props.work_calendar_attributes)
@classmethod
def enable_editing_work_calendar(cls, work_calendar):
def enable_editing_work_calendar(cls, work_calendar: ifcopenshell.entity_instance) -> None:
bpy.context.scene.BIMWorkCalendarProperties.active_work_calendar_id = work_calendar.id()
bpy.context.scene.BIMWorkCalendarProperties.editing_type = "ATTRIBUTES"
@classmethod
def disable_editing_work_calendar(cls):
def disable_editing_work_calendar(cls) -> None:
bpy.context.scene.BIMWorkCalendarProperties.active_work_calendar_id = 0
@classmethod
def get_work_calendar_attributes(cls):
def get_work_calendar_attributes(cls) -> dict[str, Any]:
return blenderbim.bim.helper.export_attributes(
bpy.context.scene.BIMWorkCalendarProperties.work_calendar_attributes
)
@classmethod
def load_work_time_attributes(cls, work_time):
def load_work_time_attributes(cls, work_time: ifcopenshell.entity_instance) -> None:
def callback(name, prop, data):
if name in ["Start", "Finish"]:
prop.string_value = "" if prop.is_null else data[name]
@@ -521,7 +525,7 @@ class Sequence(blenderbim.core.tool.Sequence):
blenderbim.bim.helper.import_attributes2(work_time, props.work_time_attributes, callback)
@classmethod
def enable_editing_work_time(cls, work_time):
def enable_editing_work_time(cls, work_time: ifcopenshell.entity_instance) -> None:
def initialise_recurrence_components(props):
if len(props.day_components) == 0:
for i in range(0, 31):
@@ -568,7 +572,7 @@ class Sequence(blenderbim.core.tool.Sequence):
props.editing_type = "WORKTIMES"
@classmethod
def get_work_time_attributes(cls):
def get_work_time_attributes(cls) -> dict[str, Any]:
def callback(attributes, prop):
if "Start" in prop.name or "Finish" in prop.name:
if prop.is_null:
@@ -608,11 +612,11 @@ class Sequence(blenderbim.core.tool.Sequence):
return attributes
@classmethod
def disable_editing_work_time(cls):
def disable_editing_work_time(cls) -> None:
bpy.context.scene.BIMWorkCalendarProperties.active_work_time_id = 0
@classmethod
def get_recurrence_pattern_times(cls):
def get_recurrence_pattern_times(cls) -> Union[tuple[datetime, datetime], None]:
props = bpy.context.scene.BIMWorkCalendarProperties
try:
start_time = parser.parse(props.start_time)
@@ -622,40 +626,40 @@ class Sequence(blenderbim.core.tool.Sequence):
return # improve UI / refactor to add user hints
@classmethod
def reset_time_period(cls):
def reset_time_period(cls) -> None:
bpy.context.scene.BIMWorkCalendarProperties.start_time = ""
bpy.context.scene.BIMWorkCalendarProperties.end_time = ""
@classmethod
def enable_editing_task_calendar(cls, task):
def enable_editing_task_calendar(cls, task: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.active_task_id = task.id()
props.editing_task_type = "CALENDAR"
@classmethod
def enable_editing_task_sequence(cls):
def enable_editing_task_sequence(cls) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.editing_task_type = "SEQUENCE"
@classmethod
def disable_editing_task_time(cls):
def disable_editing_task_time(cls) -> None:
bpy.context.scene.BIMWorkScheduleProperties.active_task_id = 0
bpy.context.scene.BIMWorkScheduleProperties.active_task_time_id = 0
@classmethod
def load_rel_sequence_attributes(cls, rel_sequence):
def load_rel_sequence_attributes(cls, rel_sequence: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.sequence_attributes.clear()
blenderbim.bim.helper.import_attributes2(rel_sequence, props.sequence_attributes)
@classmethod
def enable_editing_rel_sequence_attributes(cls, rel_sequence):
def enable_editing_rel_sequence_attributes(cls, rel_sequence: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.active_sequence_id = rel_sequence.id()
props.editing_sequence_type = "ATTRIBUTES"
@classmethod
def load_lag_time_attributes(cls, lag_time):
def load_lag_time_attributes(cls, lag_time: ifcopenshell.entity_instance) -> None:
def callback(name, prop, data):
if name == "LagValue":
prop = bpy.context.scene.BIMWorkScheduleProperties.lag_time_attributes.add()
@@ -673,21 +677,21 @@ class Sequence(blenderbim.core.tool.Sequence):
blenderbim.bim.helper.import_attributes2(lag_time, props.lag_time_attributes, callback)
@classmethod
def enable_editing_sequence_lag_time(cls, rel_sequence):
def enable_editing_sequence_lag_time(cls, rel_sequence: ifcopenshell.entity_instance) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.active_sequence_id = rel_sequence.id()
props.editing_sequence_type = "LAG_TIME"
@classmethod
def get_rel_sequence_attributes(cls):
def get_rel_sequence_attributes(cls) -> dict[str, Any]:
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMWorkScheduleProperties.sequence_attributes)
@classmethod
def disable_editing_rel_sequence(cls):
def disable_editing_rel_sequence(cls) -> None:
bpy.context.scene.BIMWorkScheduleProperties.active_sequence_id = 0
@classmethod
def get_lag_time_attributes(cls):
def get_lag_time_attributes(cls) -> dict[str, Any]:
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMWorkScheduleProperties.lag_time_attributes)
@classmethod
@@ -698,14 +702,14 @@ class Sequence(blenderbim.core.tool.Sequence):
obj.select_set(True) if obj else None
@classmethod
def add_task_column(cls, column_type, name, data_type):
def add_task_column(cls, column_type: str, name: str, data_type: str):
props = bpy.context.scene.BIMWorkScheduleProperties
new = props.columns.add()
new.name = f"{column_type}.{name}"
new.data_type = data_type
@classmethod
def setup_default_task_columns(cls):
def setup_default_task_columns(cls) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.columns.clear()
default_columns = ["ScheduleStart", "ScheduleFinish", "ScheduleDuration"]
@@ -715,14 +719,14 @@ class Sequence(blenderbim.core.tool.Sequence):
new.data_type = "string"
@classmethod
def remove_task_column(cls, name):
def remove_task_column(cls, name: str) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.columns.remove(props.columns.find(name))
if props.sort_column == name:
props.sort_column = ""
@classmethod
def set_task_sort_column(cls, column):
def set_task_sort_column(cls, column: str) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.sort_column = column
@@ -743,7 +747,7 @@ class Sequence(blenderbim.core.tool.Sequence):
return related_tasks
@classmethod
def get_work_schedule(cls, task):
def get_work_schedule(cls, task: ifcopenshell.entity_instance) -> Union[ifcopenshell.entity_instance, None]:
for rel in task.HasAssignments or []:
if rel.is_a("IfcRelAssignsToControl") and rel.RelatingControl.is_a("IfcWorkSchedule"):
return rel.RelatingControl
@@ -779,8 +783,9 @@ class Sequence(blenderbim.core.tool.Sequence):
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
# TODO: proper typing
@classmethod
def guess_date_range(cls, work_schedule):
def guess_date_range(cls, work_schedule: ifcopenshell.entity_instance) -> tuple[Any, Any]:
return ifcopenshell.util.sequence.guess_date_range(work_schedule)
@classmethod
@@ -792,7 +797,7 @@ class Sequence(blenderbim.core.tool.Sequence):
props.visualisation_finish = ifcopenshell.util.date.canonicalise_time(finish_date)
@classmethod
def get_animation_bar_tasks(cls):
def get_animation_bar_tasks(cls) -> list[ifcopenshell.entity_instance]:
return [tool.Ifc.get().by_id(task_id) for task_id in cls.get_task_bar_list()]
@classmethod
@@ -1076,19 +1081,19 @@ class Sequence(blenderbim.core.tool.Sequence):
predefined_type_item.color = data["Color"]
@classmethod
def get_start_date(cls):
def get_start_date(cls) -> Union[datetime, None]:
start = parser.parse(bpy.context.scene.BIMWorkScheduleProperties.visualisation_start, dayfirst=True, fuzzy=True)
return start if start else None
return start or None
@classmethod
def get_finish_date(cls):
def get_finish_date(cls) -> Union[datetime, None]:
finish = parser.parse(
bpy.context.scene.BIMWorkScheduleProperties.visualisation_finish, dayfirst=True, fuzzy=True
)
return finish if finish else None
return finish or None
@classmethod
def process_construction_state(cls, work_schedule, date):
def process_construction_state(cls, work_schedule: ifcopenshell.entity_instance, date: datetime) -> dict[str, Any]:
cls.to_build = set()
cls.in_construction = set()
cls.completed = set()
@@ -1109,7 +1114,7 @@ class Sequence(blenderbim.core.tool.Sequence):
}
@classmethod
def process_task_status(cls, task, date):
def process_task_status(cls, task: ifcopenshell.entity_instance, date: datetime) -> None:
for rel in task.IsNestedBy or []:
[cls.process_task_status(related_object, date) for related_object in rel.RelatedObjects]
start = ifcopenshell.util.sequence.derive_date(task, "ScheduleStart", is_earliest=True)
@@ -1234,7 +1239,7 @@ class Sequence(blenderbim.core.tool.Sequence):
}
@classmethod
def get_animation_product_frames(cls, work_schedule, settings):
def get_animation_product_frames(cls, work_schedule: ifcopenshell.entity_instance, settings: dict[str, Any]):
def preprocess_task(task):
for subtask in ifcopenshell.util.sequence.get_nested_tasks(task):
preprocess_task(subtask)
@@ -1445,7 +1450,7 @@ class Sequence(blenderbim.core.tool.Sequence):
append_handler(animate_text_handler)
@classmethod
def create_tasks_json(cls, work_schedule=None):
def create_tasks_json(cls, work_schedule: ifcopenshell.entity_instance) -> list[dict[str, Any]]:
sequence_type_map = {
None: "FS",
"START_START": "SS",
@@ -1535,7 +1540,9 @@ class Sequence(blenderbim.core.tool.Sequence):
cls.create_new_task_json(nested_task, json, type_map, baseline_schedule)
@classmethod
def generate_gantt_browser_chart(cls, task_json, work_schedule):
def generate_gantt_browser_chart(
cls, task_json: list[dict[str, Any]], work_schedule: ifcopenshell.entity_instance
) -> None:
with open(os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.html"), "w") as f:
with open(os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.mustache"), "r") as t:
task_b64 = base64.b64encode(bytes(json.dumps(task_json), "utf-8")).decode("utf-8")
@@ -1545,15 +1552,19 @@ class Sequence(blenderbim.core.tool.Sequence):
webbrowser.open("file://" + os.path.join(bpy.context.scene.BIMProperties.data_dir, "gantt", "index.html"))
@classmethod
def is_filter_by_active_schedule(cls):
def is_filter_by_active_schedule(cls) -> bool:
return bpy.context.scene.BIMWorkScheduleProperties.filter_by_active_schedule
@classmethod
def get_tasks_for_product(cls, product, work_schedule=None):
def get_tasks_for_product(
cls, product: ifcopenshell.entity_instance, work_schedule: Optional[ifcopenshell.entity_instance] = None
) -> tuple[list[ifcopenshell.entity_instance], list[ifcopenshell.entity_instance]]:
return ifcopenshell.util.sequence.get_tasks_for_product(product, work_schedule)
@classmethod
def load_product_related_tasks(cls, task_inputs, task_ouputs):
def load_product_related_tasks(
cls, task_inputs: list[ifcopenshell.entity_instance], task_ouputs: list[ifcopenshell.entity_instance]
) -> None:
props = bpy.context.scene.BIMWorkScheduleProperties
props.product_input_tasks.clear()
props.product_output_tasks.clear()
@@ -1567,7 +1578,9 @@ class Sequence(blenderbim.core.tool.Sequence):
new.ifc_definition_id = task.id()
@classmethod
def get_work_schedule_products(cls, work_schedule):
def get_work_schedule_products(
cls, work_schedule: ifcopenshell.entity_instance
) -> list[ifcopenshell.entity_instance]:
products = []
for task in ifcopenshell.util.sequence.get_root_tasks(work_schedule):
products.extend(ifcopenshell.util.sequence.get_task_inputs(task, is_deep=True))
@@ -1615,7 +1628,7 @@ class Sequence(blenderbim.core.tool.Sequence):
bpy.ops.view3d.camera_to_view_selected()
@classmethod
def save_animation_color_scheme(cls, name):
def save_animation_color_scheme(cls, name: str) -> ifcopenshell.entity_instance:
props = bpy.context.scene.BIMAnimationProperties
colour_scheme = {
"Inputs": {cs.name: cs.color[0:3] for cs in props.task_input_colors},
@@ -1634,7 +1647,7 @@ class Sequence(blenderbim.core.tool.Sequence):
return group[0]
@classmethod
def load_animation_color_scheme(cls, scheme):
def load_animation_color_scheme(cls, scheme: Optional[ifcopenshell.entity_instance]) -> None:
if not scheme:
return
data = json.loads(scheme.Description)
+1 -1
View File
@@ -148,7 +148,7 @@ class Spatial(blenderbim.core.tool.Spatial):
target_obj.matrix_world = relative_to_obj.matrix_world @ matrix
@classmethod
def select_products(cls, products, unhide=False):
def select_products(cls, products: list[ifcopenshell.entity_instance], unhide: bool = False) -> None:
bpy.ops.object.select_all(action="DESELECT")
for product in products:
obj = tool.Ifc.get_object(product)
+3
View File
@@ -19,6 +19,9 @@
import bpy
import ifcopenshell.util.element
import ifcopenshell.util.system
import blenderbim.bim.helper
import blenderbim.core.geometry
import blenderbim.core.root
import blenderbim.core.tool
import blenderbim.tool as tool
from blenderbim.bim import import_ifc
+2
View File
@@ -18,8 +18,10 @@
import bpy
import ifcopenshell
import ifcopenshell.api
import test.bim.bootstrap
import blenderbim.core.tool
import blenderbim.core.root
import blenderbim.tool as tool
from blenderbim.tool.qto import Qto as subject
from blenderbim.bim.module.pset.qto_calculator import QtoCalculator
@@ -21,7 +21,10 @@ import math
import bmesh
import ifcopenshell.util.unit
from mathutils import Vector, Matrix
from typing import Union, Optional, Literal, Any
from typing import Union, Optional, Literal, Any, TYPE_CHECKING
if TYPE_CHECKING:
from blenderbim.bim.module.geometry.helper import Helper
Z_AXIS = Vector((0, 0, 1))
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
from typing import Any
def map_representation(
@@ -29,7 +30,10 @@ def map_representation(
class Usecase:
def execute(self):
file: ifcopenshell.file
settings: dict[str, Any]
def execute(self) -> ifcopenshell.entity_instance:
mapping_source = self.get_mapping_source()
zero = self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))
@@ -49,7 +53,7 @@ class Usecase:
}
)
def get_mapping_source(self):
def get_mapping_source(self) -> ifcopenshell.entity_instance:
for inverse in self.file.get_inverse(self.settings["representation"]):
if inverse.is_a("IfcRepresentationMap"):
return inverse
@@ -17,6 +17,7 @@
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
import ifcopenshell
import ifcopenshell.api
import ifcopenshell.util.element
@@ -351,7 +351,7 @@ def get_direct_task_outputs(task: ifcopenshell.entity_instance) -> list[ifcopens
]
def get_task_outputs(task: ifcopenshell.entity_instance, is_deep=False):
def get_task_outputs(task: ifcopenshell.entity_instance, is_deep: bool = False) -> list[ifcopenshell.entity_instance]:
if not is_deep:
return get_direct_task_outputs(task)
else:
@@ -362,7 +362,7 @@ def get_task_outputs(task: ifcopenshell.entity_instance, is_deep=False):
]
def get_task_inputs(task: ifcopenshell.entity_instance, is_deep=False):
def get_task_inputs(task: ifcopenshell.entity_instance, is_deep: bool = False) -> list[ifcopenshell.entity_instance]:
if not is_deep:
return [
object
@@ -385,7 +385,7 @@ def get_task_inputs(task: ifcopenshell.entity_instance, is_deep=False):
]
def get_task_resources(task: ifcopenshell.entity_instance, is_deep=False):
def get_task_resources(task: ifcopenshell.entity_instance, is_deep: bool = False) -> list[ifcopenshell.entity_instance]:
if not is_deep:
return [
object