diff --git a/src/blenderbim/blenderbim/bim/module/search/data.py b/src/blenderbim/blenderbim/bim/module/search/data.py index 89bbca673c..b34d80148f 100644 --- a/src/blenderbim/blenderbim/bim/module/search/data.py +++ b/src/blenderbim/blenderbim/bim/module/search/data.py @@ -47,9 +47,8 @@ class SearchData: for group in groups: try: data = json.loads(group.Description) - if isinstance(data, dict) and data.get("type", None) == "BBIM_Search": - if data.get("query"): - results.append(group) + if isinstance(data, dict) and data.get("type", None) == "BBIM_Search" and data.get("query", None): + results.append(group) except: pass return [(str(g.id()), g.Name or "Unnamed", "") for g in sorted(results, key=lambda x: x.Name or "Unnamed")] diff --git a/src/blenderbim/blenderbim/bim/module/sequence/__init__.py b/src/blenderbim/blenderbim/bim/module/sequence/__init__.py index 65d1fb887e..8babec90a1 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/__init__.py @@ -49,7 +49,6 @@ classes = ( operator.CreateBaseline, operator.DisableEditingSequence, operator.DisableEditingTask, - operator.DisableEditingTaskAnimationColors, operator.DisableEditingTaskTime, operator.DisableEditingWorkCalendar, operator.DisableEditingWorkPlan, @@ -89,8 +88,9 @@ classes = ( operator.ImportP6, operator.ImportP6XER, operator.ImportPP, + operator.LoadAnimationColorScheme, + operator.LoadDefaultAnimationColors, operator.LoadProductTasks, - operator.LoadTaskAnimationColors, operator.LoadTaskInputs, operator.LoadTaskOutputs, operator.LoadTaskProperties, @@ -105,6 +105,7 @@ classes = ( operator.RemoveWorkSchedule, operator.RemoveWorkTime, operator.ReorderTask, + operator.SaveAnimationColorScheme, operator.SelectTaskRelatedInputs, operator.SelectTaskRelatedProducts, operator.SelectUnassignedWorkScheduleProducts, @@ -138,15 +139,15 @@ classes = ( ui.BIM_PT_work_plans, ui.BIM_PT_work_schedules, ui.BIM_PT_work_calendars, - ui.BIM_PT_task_icom, ui.BIM_PT_animation_tools, + ui.BIM_PT_task_icom, + ui.BIM_PT_animation_Color_Scheme, ui.BIM_UL_task_columns, ui.BIM_UL_task_inputs, ui.BIM_UL_task_resources, ui.BIM_UL_task_outputs, ui.BIM_UL_tasks, ui.BIM_PT_4D_Tools, - ui.BIM_PT_Task_Bar_Creator, ui.BIM_UL_animation_colors, ui.BIM_UL_product_input_tasks, ui.BIM_UL_product_output_tasks, diff --git a/src/blenderbim/blenderbim/bim/module/sequence/data.py b/src/blenderbim/blenderbim/bim/module/sequence/data.py index f08a5d79ed..e261801fcc 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/data.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/data.py @@ -20,6 +20,7 @@ import bpy import blenderbim.tool as tool import ifcopenshell import ifcopenshell.util.date as dateutil +import json def refresh(): @@ -27,6 +28,7 @@ def refresh(): WorkPlansData.is_loaded = False TaskICOMData.is_loaded = False WorkScheduleData.is_loaded = False + AnimationColorSchemeData.is_loaded = False class SequenceData: @@ -326,3 +328,31 @@ class TaskICOMData: resource_id = resource_tprops.resources[resource_props.active_resource_index].ifc_definition_id return not tool.Ifc.get().by_id(resource_id).is_a("IfcCrewResource") return False + + +class AnimationColorSchemeData: + data = {} + is_loaded = False + + @classmethod + def load(cls): + cls.is_loaded = True + cls.data = {} + cls.data["saved_color_schemes"] = cls.saved_color_schemes() + + @classmethod + def saved_color_schemes(cls): + groups = tool.Ifc.get().by_type("IfcGroup") + results = [] + for group in groups: + try: + data = json.loads(group.Description) + if ( + isinstance(data, dict) + and data.get("type", None) == "BBIM_AnimationColorScheme" + and data.get("colourscheme", None) + ): + results.append(group) + except: + pass + return [(str(g.id()), g.Name or "Unnamed", "") for g in sorted(results, key=lambda x: x.Name or "Unnamed")] diff --git a/src/blenderbim/blenderbim/bim/module/sequence/operator.py b/src/blenderbim/blenderbim/bim/module/sequence/operator.py index bb6f9d17ab..fa9889c947 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/operator.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/operator.py @@ -140,7 +140,7 @@ class AddWorkSchedule(bpy.types.Operator, tool.Ifc.Operator): self.props = context.scene.BIMWorkScheduleProperties layout.prop(self.props, "work_schedule_predefined_types", text="Type") if self.props.work_schedule_predefined_types == "USERDEFINED": - layout.prop(self.props,"object_type", text="Object type") + layout.prop(self.props, "object_type", text="Object type") def invoke(self, context, event): return context.window_manager.invoke_props_dialog(self) @@ -1275,25 +1275,51 @@ class AddTaskBars(bpy.types.Operator): return {"FINISHED"} -class LoadTaskAnimationColors(bpy.types.Operator): - bl_idname = "bim.enable_editing_task_animation_colors" +class LoadDefaultAnimationColors(bpy.types.Operator): + bl_idname = "bim.load_default_animation_color_scheme" bl_label = "Load Animation Colors" bl_options = {"REGISTER", "UNDO"} def execute(self, context): - core.enable_editing_task_animation_colors(tool.Sequence) + core.load_default_animation_color_scheme(tool.Sequence) return {"FINISHED"} -class DisableEditingTaskAnimationColors(bpy.types.Operator): - bl_idname = "bim.disable_editing_task_animation_colors" - bl_label = "Disable Editing Task Animation Colors" +class SaveAnimationColorScheme(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.save_animation_color_scheme" + bl_label = "Save Animation Color Scheme" bl_options = {"REGISTER", "UNDO"} + bl_description = "Saves the current animation color scheme" + name: bpy.props.StringProperty() - def execute(self, context): - core.disable_editing_task_animation_colors(tool.Sequence) + def _execute(self, context): + if not self.name: + return + core.save_animation_color_scheme(tool.Sequence, name=self.name) return {"FINISHED"} + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self) + + +class LoadAnimationColorScheme(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.load_animation_color_scheme" + bl_label = "Load Animation Color Scheme" + bl_options = {"REGISTER", "UNDO"} + bl_description = "Loads the animation color scheme" + + def _execute(self, context): + group = tool.Ifc.get().by_id(int(context.scene.BIMAnimationProperties.saved_color_schemes)) + core.load_animation_color_scheme(tool.Sequence, scheme=group) + + def draw(self, context): + props = context.scene.BIMAnimationProperties + row = self.layout.row() + row.prop(props, "saved_color_schemes", text="") + + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self) + class CopyTask(bpy.types.Operator, tool.Ifc.Operator): bl_idname = "bim.duplicate_task" diff --git a/src/blenderbim/blenderbim/bim/module/sequence/prop.py b/src/blenderbim/blenderbim/bim/module/sequence/prop.py index 28a77506b4..d23cc50a2c 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/prop.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/prop.py @@ -24,7 +24,7 @@ from ifcopenshell.util.doc import get_predefined_type_doc import blenderbim.tool as tool import blenderbim.core.sequence as core from blenderbim.bim.ifc import IfcStore -from blenderbim.bim.module.sequence.data import SequenceData +from blenderbim.bim.module.sequence.data import SequenceData, AnimationColorSchemeData import blenderbim.bim.module.pset.data from blenderbim.bim.prop import StrProperty, Attribute from dateutil import parser @@ -235,6 +235,7 @@ def get_schedule_predefined_types(self, context): break return results + def update_visualisation_start(self, context): update_visualisation_start_finish(self, context, "visualisation_start") @@ -292,20 +293,30 @@ def update_sort_reversed(self, context): work_schedule=tool.Ifc.get().by_id(context.scene.BIMWorkScheduleProperties.active_work_schedule_id), ) + def update_filter_by_active_schedule(self, context): if context.active_object: core.load_product_related_tasks( tool.Sequence, product=tool.Ifc.get().by_id(context.active_object.BIMObjectProperties.ifc_definition_id) ) + def switch_options(self, context): if self.should_show_visualisation_ui: self.should_show_snapshot_ui = False + def switch_options2(self, context): if self.should_show_snapshot_ui: self.should_show_visualisation_ui = False + +def get_saved_color_schemes(self, context): + if not AnimationColorSchemeData.is_loaded: + AnimationColorSchemeData.load() + return AnimationColorSchemeData.data["saved_color_schemes"] + + class Task(PropertyGroup): name: StringProperty(name="Name", update=updateTaskName) identification: StringProperty(name="Identification", update=updateTaskIdentification) @@ -440,7 +451,9 @@ class BIMWorkScheduleProperties(PropertyGroup): enable_reorder: BoolProperty(name="Enable Reorder", default=False) show_task_operators: BoolProperty(name="Show Task Options", default=True) should_show_schedule_baseline_ui: BoolProperty(name="Baselines", default=False) - filter_by_active_schedule: BoolProperty(name="Filter By Active Schedule", default=False, update = update_filter_by_active_schedule) + filter_by_active_schedule: BoolProperty( + name="Filter By Active Schedule", default=False, update=update_filter_by_active_schedule + ) class BIMTaskTreeProperties(PropertyGroup): @@ -510,16 +523,16 @@ class BIMTaskTypeColor(PropertyGroup): default=(1, 0, 0), min=0.0, max=1.0, - # update=update_task_animation_color, ) class BIMAnimationProperties(PropertyGroup): is_editing: BoolProperty(name="Is Loaded", default=False) + saved_color_schemes: EnumProperty(items=get_saved_color_schemes, name="Saved Colour Schemes") active_color_component_outputs_index: IntProperty(name="Active Color Component Index") active_color_component_inputs_index: IntProperty(name="Active Color Component Index") - task_colors_components_inputs: CollectionProperty(name="Groups", type=BIMTaskTypeColor) - task_colors_components_outputs: CollectionProperty(name="Groups", type=BIMTaskTypeColor) + task_input_colors: CollectionProperty(name="Groups", type=BIMTaskTypeColor) + task_output_colors: CollectionProperty(name="Groups", type=BIMTaskTypeColor) color_full: FloatVectorProperty( name="Full Bar", subtype="COLOR", diff --git a/src/blenderbim/blenderbim/bim/module/sequence/ui.py b/src/blenderbim/blenderbim/bim/module/sequence/ui.py index 64ed3399f7..8afd221482 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/ui.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/ui.py @@ -21,7 +21,13 @@ import blenderbim.bim.helper from bpy.types import Panel, UIList from blenderbim.bim.ifc import IfcStore from blenderbim.bim.helper import draw_attributes -from blenderbim.bim.module.sequence.data import WorkPlansData, WorkScheduleData, SequenceData, TaskICOMData +from blenderbim.bim.module.sequence.data import ( + WorkPlansData, + WorkScheduleData, + SequenceData, + TaskICOMData, + AnimationColorSchemeData, +) class BIM_PT_work_plans(Panel): @@ -58,7 +64,7 @@ class BIM_PT_work_plans(Panel): if self.props.active_work_plan_id == work_plan["id"]: if self.props.editing_type == "ATTRIBUTES": row.operator("bim.edit_work_plan", text="", icon="CHECKMARK") - row.operator("bim.disable_editing_work_plan", text="Cancel", icon="CANCEL") + row.operator("bim.disable_editing_work_plan", text="Cancel", icon="CANCEL") elif self.props.active_work_plan_id: row.operator("bim.remove_work_plan", text="", icon="X").work_plan = work_plan["id"] else: @@ -180,7 +186,10 @@ class BIM_PT_work_schedules(Panel): row2 = col.row(align=True) row.operator("bim.disable_editing_work_schedule", text="Cancel", icon="CANCEL") if not self.props.active_work_schedule_id: - row.label(text="{}[{}]".format(work_schedule["Name"], work_schedule["PredefinedType"]) or "Unnamed", icon="LINENUMBERS_ON") + row.label( + text="{}[{}]".format(work_schedule["Name"], work_schedule["PredefinedType"]) or "Unnamed", + icon="LINENUMBERS_ON", + ) row.operator( "bim.enable_editing_work_schedule_tasks", text="Tasks", icon="ACTION" ).work_schedule = work_schedule_id @@ -209,7 +218,7 @@ class BIM_PT_work_schedules(Panel): row.operator("bim.edit_task_time", text="", icon="CHECKMARK") elif self.props.editing_task_type == "ATTRIBUTES": row.operator("bim.edit_task", text="", icon="CHECKMARK") - row.operator("bim.disable_editing_task", text="Cancel", icon="CANCEL") + row.operator("bim.disable_editing_task", text="Cancel", icon="CANCEL") else: row.prop(self.props, "show_task_operators", text="Edit", icon="GREASEPENCIL") if self.props.show_task_operators: @@ -315,12 +324,12 @@ class BIM_PT_work_schedules(Panel): if self.props.active_sequence_id == sequence["id"]: if self.props.editing_sequence_type == "ATTRIBUTES": row.operator("bim.edit_sequence_attributes", text="", icon="CHECKMARK") - row.operator("bim.disable_editing_sequence", text="Cancel", icon="CANCEL") + row.operator("bim.disable_editing_sequence", text="Cancel", icon="CANCEL") self.draw_editable_sequence_attributes_ui() elif self.props.editing_sequence_type == "LAG_TIME": op = row.operator("bim.edit_sequence_lag_time", text="", icon="CHECKMARK") op.lag_time = sequence["TimeLag"] - row.operator("bim.disable_editing_sequence", text="Cancel", icon="CANCEL") + row.operator("bim.disable_editing_sequence", text="Cancel", icon="CANCEL") self.draw_editable_sequence_lag_time_ui() else: if sequence["TimeLag"]: @@ -436,9 +445,7 @@ class BIM_PT_animation_tools(Panel): self.animation_props = context.scene.BIMAnimationProperties row = self.layout.row(align=True) row.alignment = "RIGHT" - row.prop( - self.props, "should_show_visualisation_ui", text="Animation Settings", icon="SETTINGS" - ) + row.prop(self.props, "should_show_visualisation_ui", text="Animation Settings", icon="SETTINGS") row.prop(self.props, "should_show_snapshot_ui", text="Snapshot Settings", icon="SETTINGS") if self.props.should_show_visualisation_ui: self.draw_visualisation_ui() @@ -446,17 +453,19 @@ class BIM_PT_animation_tools(Panel): self.draw_snapshot_ui() self.draw_processing_options() - def draw_processing_options(self): row = self.layout.row(align=True) row.alignment = "LEFT" row.label(text="Processing Tools") row = self.layout.row() row.alignment = "RIGHT" - row.operator("bim.clear_previous_animation", text="Clear Previous Animation", icon="TRACKING_CLEAR_FORWARDS") row.operator("bim.add_animation_camera", text="Add Camera", icon="CAMERA_DATA") + row.operator("bim.clear_previous_animation", text="Reset Animation", icon="TRACKING_CLEAR_FORWARDS") def draw_visualisation_ui(self): + if not AnimationColorSchemeData.is_loaded: + AnimationColorSchemeData.load() + row = self.layout.row(align=True) row.label(text="Start Date/ Date Range:", icon="CAMERA_DATA") row = self.layout.row(align=True) @@ -486,16 +495,7 @@ class BIM_PT_animation_tools(Panel): row.label(text="Display Settings") row = self.layout.row() row.alignment = "RIGHT" - if not self.animation_props.is_editing: - op = row.operator( - "bim.enable_editing_task_animation_colors", text="Customize Object Colors", icon="SEQUENCE_COLOR_04" - ) - else: - op = row.operator( - "bim.disable_editing_task_animation_colors", text="Hide Object Colors", icon="SEQUENCE_COLOR_01" - ) - - row.prop(self.animation_props, "should_show_task_bar_options", text="Task Bar", icon="NLA_PUSHDOWN") + row.prop(self.animation_props, "should_show_task_bar_options", text="Task Bars", icon="NLA_PUSHDOWN") if self.animation_props.should_show_task_bar_options: row = self.layout.row() row.label(text="Task Bar Options", icon="NLA_PUSHDOWN") @@ -514,10 +514,12 @@ class BIM_PT_animation_tools(Panel): row = col.row(align=True) row.prop(self.animation_props, "color_full") - if self.animation_props.is_editing: - self.draw_visualisation_settings_ui() - row = self.layout.row(align=True) + row.alignment = "RIGHT" + if self.animation_props.saved_color_schemes: + row.prop(self.animation_props, "saved_color_schemes", text="Color Scheme", icon="SEQUENCE_COLOR_04") + else: + row.label(text="No Color Scheme Saved", icon="INFO") op = row.operator("bim.visualise_work_schedule_date_range", text="Create Animation", icon="OUTLINER_OB_CAMERA") op.work_schedule = self.props.active_work_schedule_id @@ -533,7 +535,33 @@ class BIM_PT_animation_tools(Panel): op = row.operator("bim.visualise_work_schedule_date", text="Create SnapShot", icon="CAMERA_STEREO") op.work_schedule = self.props.active_work_schedule_id - def draw_visualisation_settings_ui(self): + +class BIM_PT_animation_Color_Scheme(Panel): + bl_label = "Animation Color Scheme" + bl_idname = "BIM_PT_animation_Color_Scheme" + bl_options = {"DEFAULT_CLOSED"} + bl_space_type = "PROPERTIES" + bl_region_type = "WINDOW" + bl_context = "scene" + bl_parent_id = "BIM_PT_tab_4D5D" + + @classmethod + def poll(cls, context): + file = IfcStore.get_file() + return file and hasattr(file, "schema") and file.schema != "IFC2X3" + + def draw(self, context): + if not AnimationColorSchemeData.is_loaded: + AnimationColorSchemeData.load() + + self.animation_props = context.scene.BIMAnimationProperties + row = self.layout.row(align=True) + row.alignment = "RIGHT" + row.operator("bim.load_default_animation_color_scheme", text="Load default", icon="SEQUENCE_COLOR_04") + if AnimationColorSchemeData.data["saved_color_schemes"]: + row.operator("bim.load_animation_color_scheme", text="Load Scheme", icon="IMPORT") + row.operator("bim.save_animation_color_scheme", text="Save Scheme", icon="EXPORT") + grid = self.layout.grid_flow(columns=2, even_columns=True) col = grid.column() row1 = col.row(align=True) @@ -543,7 +571,7 @@ class BIM_PT_animation_tools(Panel): "BIM_UL_animation_colors", "", self.animation_props, - "task_colors_components_inputs", + "task_input_colors", self.animation_props, "active_color_component_inputs_index", ) @@ -555,11 +583,12 @@ class BIM_PT_animation_tools(Panel): "BIM_UL_animation_colors", "", self.animation_props, - "task_colors_components_outputs", + "task_output_colors", self.animation_props, "active_color_component_outputs_index", ) + class BIM_PT_task_icom(Panel): bl_label = "Task ICOM" bl_idname = "BIM_PT_task_icom" @@ -882,7 +911,7 @@ class BIM_PT_work_calendars(Panel): if self.props.active_work_calendar_id == work_calendar_id: if self.props.editing_type == "ATTRIBUTES": row.operator("bim.edit_work_calendar", text="", icon="CHECKMARK") - row.operator("bim.disable_editing_work_calendar", text="Cancel", icon="CANCEL") + row.operator("bim.disable_editing_work_calendar", text="Cancel", icon="CANCEL") elif self.props.active_work_calendar_id: row.operator("bim.remove_work_calendar", text="", icon="X").work_calendar = work_calendar_id else: @@ -920,7 +949,7 @@ class BIM_PT_work_calendars(Panel): row.label(text="{} - {}".format(work_time["Start"] or "*", work_time["Finish"] or "*")) if self.props.active_work_time_id == work_time["id"]: row.operator("bim.edit_work_time", text="", icon="CHECKMARK") - row.operator("bim.disable_editing_work_time", text="Cancel", icon="CANCEL") + row.operator("bim.disable_editing_work_time", text="Cancel", icon="CANCEL") elif self.props.active_work_time_id: op = row.operator("bim.remove_work_time", text="", icon="X") op.work_time = work_time["id"] @@ -1041,29 +1070,3 @@ class BIM_PT_4D_Tools(Panel): self.props, "active_product_output_task_index", ) - - -class BIM_PT_Task_Bar_Creator(Panel): - bl_label = "Task Bar Creator" - bl_idname = "BIM_PT_Task_Bar_Creator" - bl_space_type = "VIEW_3D" - bl_region_type = "UI" - bl_options = {"DEFAULT_CLOSED"} - bl_parent_id = "BIM_PT_4D_Tools" - - def draw(self, context): - self.animation_props = context.scene.BIMAnimationProperties - row = self.layout.row() - row.operator("bim.add_task_bars", text="Add Bar Visual", icon="NLA_PUSHDOWN") - - grid = self.layout.grid_flow(columns=2, even_columns=True) - # Column1 - col = grid.column() - row1 = col.row(align=True) - row1.label(text="Bar Colors", icon="NLA_PUSHDOWN") - - row2 = col.row(align=True) - row2.prop(self.animation_props, "color_progress") - - row3 = col.row(align=True) - row3.prop(self.animation_props, "color_full") diff --git a/src/blenderbim/blenderbim/core/sequence.py b/src/blenderbim/blenderbim/core/sequence.py index 7af332cbf4..72d9afb293 100644 --- a/src/blenderbim/blenderbim/core/sequence.py +++ b/src/blenderbim/blenderbim/core/sequence.py @@ -463,6 +463,7 @@ def add_task_column(sequence, column_type=None, name=None, data_type=None): sequence.load_task_tree(work_schedule) sequence.load_task_properties() + def remove_task_column(sequence, name=None): sequence.remove_task_column(name) @@ -474,6 +475,7 @@ def set_task_sort_column(sequence, column=None): sequence.load_task_tree(work_schedule) sequence.load_task_properties() + def calculate_task_duration(ifc, sequence, task=None): ifc.run("sequence.calculate_task_duration", task=task) work_schedule = sequence.get_active_work_schedule() @@ -482,6 +484,10 @@ def calculate_task_duration(ifc, sequence, task=None): sequence.load_task_properties() +def load_animation_color_scheme(sequence, scheme): + sequence.load_animation_color_scheme(scheme) + + def highlight_task(sequence, task=None): work_schedule = sequence.get_work_schedule(task) is_work_schedule_active = sequence.is_work_schedule_active(work_schedule) @@ -520,13 +526,8 @@ def add_task_bars(sequence): sequence.create_bars(tasks) -def enable_editing_task_animation_colors(sequence): - sequence.load_task_animation_colors() - sequence.enable_editing_task_animation_colors() - - -def disable_editing_task_animation_colors(sequence): - sequence.disable_editing_task_animation_colors() +def load_default_animation_color_scheme(sequence): + sequence.load_default_animation_color_scheme() def visualise_work_schedule_date_range(sequence, work_schedule=None): @@ -534,7 +535,8 @@ def visualise_work_schedule_date_range(sequence, work_schedule=None): settings = sequence.get_animation_settings() if settings: product_frames = sequence.get_animation_product_frames(work_schedule, settings) - sequence.load_task_animation_colors() + if not sequence.has_animation_colors(): + sequence.load_default_animation_color_scheme() sequence.animate_objects(settings, product_frames, "date_range") sequence.add_text_animation_handler(settings) add_task_bars(sequence) @@ -582,8 +584,14 @@ def reorder_task_nesting(ifc, sequence, task, new_index): def create_baseline(ifc, sequence, work_schedule, name): ifc.run("sequence.create_baseline", work_schedule=work_schedule, name=name) + def clear_previous_animation(sequence): sequence.clear_objects_animation(include_blender_objects=False) + def add_animation_camera(sequence): - sequence.add_animation_camera() \ No newline at end of file + sequence.add_animation_camera() + + +def save_animation_color_scheme(sequence, name): + sequence.save_animation_color_scheme(name) diff --git a/src/blenderbim/blenderbim/tool/sequence.py b/src/blenderbim/blenderbim/tool/sequence.py index 9de9274d0a..db4b2879f7 100644 --- a/src/blenderbim/blenderbim/tool/sequence.py +++ b/src/blenderbim/blenderbim/tool/sequence.py @@ -1044,63 +1044,54 @@ class Sequence(blenderbim.core.tool.Sequence): create_task_bar_data(tasks, vertical_increment, collection) @classmethod - def enable_editing_task_animation_colors(cls): - bpy.context.scene.BIMAnimationProperties.is_editing = True + def has_animation_colors(cls): + return bpy.context.scene.BIMAnimationProperties.task_output_colors @classmethod - def load_task_animation_colors(cls): + def load_default_animation_color_scheme(cls): + groups = { + "CREATION": { + "PredefinedType": ["CONSTRUCTION", "INSTALLATION"], + "Color": (0.0, 1.0, 0.0), + }, + "OPERATION": { + "PredefinedType": ["ATTENDANCE", "MAINTENANCE", "OPERATION", "RENOVATION"], + "Color": (0.0, 0.0, 1.0), + }, + "MOVEMENT_TO": { + "PredefinedType": ["LOGISTIC", "MOVE"], + "Color": (1.0, 1.0, 0.0), + }, + "DESTRUCTION": { + "PredefinedType": ["DEMOLITION", "DISMANTLE", "DISPOSAL", "REMOVAL"], + "Color": (1.0, 0.0, 0.0), + }, + "MOVEMENT_FROM": { + "PredefinedType": ["LOGISTIC", "MOVE"], + "Color": (1.0, 0.5, 0.0), + }, + "USERDEFINED": { + "PredefinedType": ["USERDEFINED", "NOTDEFINED"], + "Color": (0.2, 0.2, 0.2), + }, + } props = bpy.context.scene.BIMAnimationProperties - if not props.task_colors_components_inputs: - if tool.Ifc.schema(): - # for attribute in tool.Ifc.schema().declaration_by_name("IfcTask").all_attributes(): - # if attribute.name() != "PredefinedType": - # continue - # task_types = ifcopenshell.util.attribute.get_enum_items(attribute) - # return [(e, e, "") for e in enum_items] - groups = { - "CREATION": { - "PredefinedType": ["CONSTRUCTION", "INSTALLATION"], - "Color": (0.0, 1.0, 0.0), - }, - "OPERATION": { - "PredefinedType": ["ATTENDANCE", "MAINTENANCE", "OPERATION", "RENOVATION"], - "Color": (0.0, 0.0, 1.0), - }, - "MOVEMENT_TO": { - "PredefinedType": ["LOGISTIC", "MOVE"], - "Color": (1.0, 1.0, 0.0), - }, - "DESTRUCTION": { - "PredefinedType": ["DEMOLITION", "DISMANTLE", "DISPOSAL", "REMOVAL"], - "Color": (1.0, 0.0, 0.0), - }, - "MOVEMENT_FROM": { - "PredefinedType": ["LOGISTIC", "MOVE"], - "Color": (1.0, 0.5, 0.0), - }, - "USERDEFINED": { - "PredefinedType": ["USERDEFINED", "NOTDEFINED"], - "Color": (0.2, 0.2, 0.2), - }, - } - for group, data in groups.items(): - for predefined_type in data["PredefinedType"]: - if group in ["CREATION", "OPERATION", "MOVEMENT_TO"]: - predefined_type_item = props.task_colors_components_outputs.add() - elif group in ["MOVEMENT_FROM", "DESTRUCTION"]: - predefined_type_item = props.task_colors_components_inputs.add() - elif group == "USERDEFINED": - predefined_type_item = props.task_colors_components_inputs.add() - predefined_type_item2 = props.task_colors_components_outputs.add() - predefined_type_item2.name = predefined_type - predefined_type_item2.color = data["Color"] - # TO DO: consider cases where users confuses inputs and outputs - predefined_type_item.name = predefined_type - predefined_type_item.color = data["Color"] - - @classmethod - def disable_editing_task_animation_colors(cls): - bpy.context.scene.BIMAnimationProperties.is_editing = False + props.task_output_colors.clear() + props.task_input_colors.clear() + for group, data in groups.items(): + for predefined_type in data["PredefinedType"]: + if group in ["CREATION", "OPERATION", "MOVEMENT_TO"]: + predefined_type_item = props.task_output_colors.add() + elif group in ["MOVEMENT_FROM", "DESTRUCTION"]: + predefined_type_item = props.task_input_colors.add() + elif group == "USERDEFINED": + predefined_type_item = props.task_input_colors.add() + predefined_type_item2 = props.task_output_colors.add() + predefined_type_item2.name = predefined_type + predefined_type_item2.color = data["Color"] + # TO DO: consider cases where users confuses inputs and outputs + predefined_type_item.name = predefined_type + predefined_type_item.color = data["Color"] @classmethod def get_start_date(cls): @@ -1341,13 +1332,13 @@ class Sequence(blenderbim.core.tool.Sequence): @classmethod def animate_input(cls, obj, start_frame, product_frame, animation_type): props = bpy.context.scene.BIMAnimationProperties - color = props.task_colors_components_inputs[product_frame["type"]].color + color = props.task_input_colors[product_frame["type"]].color cls.animate_destruction(obj, start_frame, product_frame, color, animation_type) @classmethod def animate_output(cls, obj, start_frame, product_frame): props = bpy.context.scene.BIMAnimationProperties - color = props.task_colors_components_outputs[product_frame["type"]].color + color = props.task_output_colors[product_frame["type"]].color if product_frame["type"] in ["CONSTRUCTION", "INSTALLATION", "NOTDEFINED"]: cls.animate_creation(obj, start_frame, product_frame, color) elif product_frame["type"] in ["ATTENDANCE", "MAINTENANCE", "OPERATION", "RENOVATION"]: @@ -1628,3 +1619,43 @@ class Sequence(blenderbim.core.tool.Sequence): obj.select_set(True) bpy.context.scene.camera = camera bpy.ops.view3d.camera_to_view_selected() + + @classmethod + def save_animation_color_scheme(cls, name): + props = bpy.context.scene.BIMAnimationProperties + colour_scheme = { + "Inputs": {cs.name: cs.color[0:3] for cs in props.task_input_colors}, + "Outputs": {cs.name: cs.color[0:3] for cs in props.task_output_colors}, + } + + group = [g for g in tool.Ifc.get().by_type("IfcGroup") if g.Name == name] + if group: + group = group[0] + description = json.loads(group.Description) + description["colourscheme"] = colour_scheme + group.Description = json.dumps(description) + else: + description = json.dumps({"type": "BBIM_AnimationColorScheme", "colourscheme": colour_scheme}) + group = tool.Ifc.run("group.add_group", Name=name, Description=description) + return group[0] + + @classmethod + def load_animation_color_scheme(cls, scheme): + if not scheme: + return + data = json.loads(scheme.Description) + if data.get("type") == "BBIM_AnimationColorScheme": + inputs_color_scheme = data.get("colourscheme").get("Inputs") + outputs_color_scheme = data.get("colourscheme").get("Outputs") + props = bpy.context.scene.BIMAnimationProperties + props.task_input_colors.clear() + props.task_output_colors.clear() + for value, colour in inputs_color_scheme.items(): + new = props.task_input_colors.add() + new.name = str(value) + new.color = colour[0:3] + + for value, colour in outputs_color_scheme.items(): + new = props.task_output_colors.add() + new.name = str(value) + new.color = colour[0:3]