diff --git a/src/blenderbim/blenderbim/bim/module/sequence/__init__.py b/src/blenderbim/blenderbim/bim/module/sequence/__init__.py index 5eeff32eeb..2a43a798f4 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/__init__.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/__init__.py @@ -20,12 +20,10 @@ import bpy from . import ui, prop, operator classes = ( - operator.ExpandAllTasks, - operator.ContractAllTasks, operator.AddSummaryTask, operator.AddTask, - operator.AddTaskColumn, operator.AddTaskBars, + operator.AddTaskColumn, operator.AddTimePeriod, operator.AddWorkCalendar, operator.AddWorkPlan, @@ -42,11 +40,15 @@ classes = ( operator.BlenderBIM_DatePickerSetDate, operator.BlenderBIM_RedrawDatePicker, operator.CalculateTaskDuration, + operator.ClearPreviousAnimation, + operator.ContractAllTasks, operator.ContractTask, - operator.CopyTaskAttribute, operator.CopyTask, + operator.CopyTaskAttribute, + operator.CreateBaseline, operator.DisableEditingSequence, operator.DisableEditingTask, + operator.DisableEditingTaskAnimationColors, operator.DisableEditingTaskTime, operator.DisableEditingWorkCalendar, operator.DisableEditingWorkPlan, @@ -67,23 +69,27 @@ classes = ( operator.EnableEditingTaskCalendar, operator.EnableEditingTaskSequence, operator.EnableEditingTaskTime, - operator.EnableEditingWorkScheduleTasks, operator.EnableEditingWorkCalendar, operator.EnableEditingWorkCalendarTimes, operator.EnableEditingWorkPlan, operator.EnableEditingWorkPlanSchedules, operator.EnableEditingWorkSchedule, + operator.EnableEditingWorkScheduleTasks, operator.EnableEditingWorkTime, + operator.ExpandAllTasks, operator.ExpandTask, operator.ExportMSP, operator.ExportP6, operator.GenerateGanttChart, operator.GuessDateRange, - operator.ImportMSP, + operator.HighlightTask, operator.ImportCSV, + operator.ImportMSP, operator.ImportP6, operator.ImportP6XER, operator.ImportPP, + operator.LoadProductTasks, + operator.LoadTaskAnimationColors, operator.LoadTaskInputs, operator.LoadTaskOutputs, operator.LoadTaskProperties, @@ -98,10 +104,10 @@ classes = ( operator.RemoveWorkSchedule, operator.RemoveWorkTime, operator.ReorderTask, - operator.SelectTaskRelatedProducts, operator.SelectTaskRelatedInputs, - operator.SelectWorkScheduleProducts, + operator.SelectTaskRelatedProducts, operator.SelectUnassignedWorkScheduleProducts, + operator.SelectWorkScheduleProducts, operator.SetTaskSortColumn, operator.SetupDefaultTaskColumns, operator.UnassignLagTime, @@ -113,11 +119,6 @@ classes = ( operator.UnassignWorkSchedule, operator.VisualiseWorkScheduleDate, operator.VisualiseWorkScheduleDateRange, - operator.LoadTaskAnimationColors, - operator.DisableEditingTaskAnimationColors, - operator.LoadProductTasks, - operator.HighlightTask, - operator.CreateBaseline, prop.WorkPlan, prop.BIMWorkPlanProperties, prop.Task, diff --git a/src/blenderbim/blenderbim/bim/module/sequence/operator.py b/src/blenderbim/blenderbim/bim/module/sequence/operator.py index 99e5c11df8..49d12f462c 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/operator.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/operator.py @@ -1401,3 +1401,12 @@ class CreateBaseline(bpy.types.Operator, tool.Ifc.Operator): def invoke(self, context, event): return context.window_manager.invoke_props_dialog(self) + + +class ClearPreviousAnimation(bpy.types.Operator, tool.Ifc.Operator): + bl_idname = "bim.clear_previous_animation" + bl_label = "Clear Previous Animation" + bl_options = {"REGISTER", "UNDO"} + + def _execute(self, context): + core.clear_previous_animation(tool.Sequence) diff --git a/src/blenderbim/blenderbim/bim/module/sequence/ui.py b/src/blenderbim/blenderbim/bim/module/sequence/ui.py index 43cbb3bf70..fa04f9502c 100644 --- a/src/blenderbim/blenderbim/bim/module/sequence/ui.py +++ b/src/blenderbim/blenderbim/bim/module/sequence/ui.py @@ -444,6 +444,16 @@ class BIM_PT_animation_tools(Panel): self.draw_visualisation_ui() if self.props.should_show_snapshot_ui: 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") def draw_visualisation_ui(self): row = self.layout.row(align=True) @@ -467,12 +477,13 @@ class BIM_PT_animation_tools(Panel): row.prop(self.props, "speed_real_duration", text="") elif self.props.speed_types == "DURATION_SPEED": row.prop(self.props, "speed_animation_duration", text="") + row.label(text="->") row.prop(self.props, "speed_real_duration", text="") elif self.props.speed_types == "MULTIPLIER_SPEED": row.prop(self.props, "speed_multiplier", text="") row = self.layout.row(align=True) row.label(text="Display Settings") - row = self.layout.row(align=True) + row = self.layout.row() row.alignment = "RIGHT" if not self.animation_props.is_editing: op = row.operator( @@ -506,7 +517,6 @@ class BIM_PT_animation_tools(Panel): self.draw_visualisation_settings_ui() row = self.layout.row(align=True) - row.alignment = "RIGHT" 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 diff --git a/src/blenderbim/blenderbim/core/sequence.py b/src/blenderbim/blenderbim/core/sequence.py index 5d8bb01936..acab879966 100644 --- a/src/blenderbim/blenderbim/core/sequence.py +++ b/src/blenderbim/blenderbim/core/sequence.py @@ -530,6 +530,7 @@ def disable_editing_task_animation_colors(sequence): def visualise_work_schedule_date_range(sequence, work_schedule=None): + sequence.clear_objects_animation(include_blender_objects=False) settings = sequence.get_animation_settings() if settings: product_frames = sequence.get_animation_product_frames(work_schedule, settings) @@ -580,3 +581,6 @@ 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) diff --git a/src/blenderbim/blenderbim/tool/sequence.py b/src/blenderbim/blenderbim/tool/sequence.py index 6c62dd2c5f..5cb93acdc7 100644 --- a/src/blenderbim/blenderbim/tool/sequence.py +++ b/src/blenderbim/blenderbim/tool/sequence.py @@ -19,7 +19,6 @@ import bpy import re import os -import isodate import ifcopenshell import ifcopenshell.util.sequence import ifcopenshell.util.date @@ -36,7 +35,6 @@ from datetime import datetime import mathutils import pystache import webbrowser -from datetime import timedelta class Sequence(blenderbim.core.tool.Sequence): @@ -212,7 +210,9 @@ class Sequence(blenderbim.core.tool.Sequence): item.calendar = "" item.derived_calendar = calendar.Name or "Unnamed" if calendar else "" - if task.TaskTime and (task.TaskTime.ScheduleStart or task.TaskTime.ScheduleFinish or task.TaskTime.ScheduleDuration): + if task.TaskTime and ( + task.TaskTime.ScheduleStart or task.TaskTime.ScheduleFinish or task.TaskTime.ScheduleDuration + ): task_time = task.TaskTime item.start = ( canonicalise_time(ifcopenshell.util.date.ifc2datetime(task_time.ScheduleStart)) @@ -721,7 +721,7 @@ class Sequence(blenderbim.core.tool.Sequence): def setup_default_task_columns(cls): props = bpy.context.scene.BIMWorkScheduleProperties props.columns.clear() - default_columns = ["ScheduleStart","ScheduleFinish","ScheduleDuration"] + default_columns = ["ScheduleStart", "ScheduleFinish", "ScheduleDuration"] for item in default_columns: new = props.columns.add() new.name = f"IfcTaskTime.{item}" @@ -798,6 +798,7 @@ class Sequence(blenderbim.core.tool.Sequence): def update_visualisation_date(cls, start_date, finish_date): def canonicalise_time(time): return time.strftime("%d/%m/%y") + if not (start_date and finish_date): return props = bpy.context.scene.BIMWorkScheduleProperties @@ -1212,7 +1213,7 @@ class Sequence(blenderbim.core.tool.Sequence): start, finish, props.speed_animation_frames, - ifcopenshell.util.date.parse_duration(props.speed_real_duration) + ifcopenshell.util.date.parse_duration(props.speed_real_duration), ) elif props.speed_types == "DURATION_SPEED": animation_duration = ifcopenshell.util.date.parse_duration(props.speed_animation_duration) @@ -1299,15 +1300,24 @@ class Sequence(blenderbim.core.tool.Sequence): if obj.animation_data: obj.animation_data_clear() + @classmethod + def clear_object_color(cls, obj): + obj.color = (1.0, 1.0, 1.0, 1.0) + + @classmethod + def display_object(cls, obj): + if not obj.visible_get(): + obj.hide_viewport = False + obj.hide_render = False + @classmethod def clear_objects_animation(cls, include_blender_objects=True): for obj in bpy.data.objects: if not include_blender_objects and not obj.BIMObjectProperties.ifc_definition_id: continue cls.clear_object_animation(obj) - if not obj.visible_get(): - obj.hide_viewport = False - obj.hide_render = False + cls.clear_object_color(obj) + cls.display_object(obj) @classmethod def animate_objects(cls, settings, frames, clear_previous=True, animation_type=""): @@ -1502,13 +1512,13 @@ class Sequence(blenderbim.core.tool.Sequence): compare_start = schedule_start compare_finish = schedule_finish task_name = task.Name or "Unnamed" - task_name = task_name.replace('\n', "") + task_name = task_name.replace("\n", "") data = { "pID": task.id(), "pName": task_name, "pCaption": task_name, "pStart": schedule_start, - "pEnd": schedule_finish , + "pEnd": schedule_finish, "pPlanStart": compare_start, "pPlanEnd": compare_finish, "pMile": 1 if task.IsMilestone else 0, @@ -1602,4 +1612,5 @@ class Sequence(blenderbim.core.tool.Sequence): object_type = None if predefined_type == "USERDEFINED": object_type = bpy.context.scene.BIMWorkScheduleProperties.object_type - return predefined_type, object_type \ No newline at end of file + return predefined_type, object_type + diff --git a/src/blenderbim/test/bim/feature/sequence.feature b/src/blenderbim/test/bim/feature/sequence.feature index 81e40d63fd..dc5ddd29af 100644 --- a/src/blenderbim/test/bim/feature/sequence.feature +++ b/src/blenderbim/test/bim/feature/sequence.feature @@ -532,6 +532,39 @@ Scenario: Animate the consumption of a wall Then "scene.objects.get('IfcWall/Cube').hide_render" is "True" + +Scenario: Clear Previous Animation + Given an empty IFC project + And I press "bim.add_work_schedule" + And the variable "work_schedule" is "IfcStore.get_file().by_type('IfcWorkSchedule')[0].id()" + And I press "bim.enable_editing_work_schedule_tasks(work_schedule={work_schedule})" + And I press "bim.add_summary_task(work_schedule={work_schedule})" + And the variable "task" is "IfcStore.get_file().by_type('IfcTask')[0].id()" + And I press "bim.enable_editing_task_attributes(task={task})" + And I set "scene.BIMWorkScheduleProperties.task_attributes.get('PredefinedType').enum_value" to "CONSTRUCTION" + And I press "bim.edit_task" + And I press "bim.enable_editing_task_time(task={task})" + And I set "scene.BIMWorkScheduleProperties.task_time_attributes.get('ScheduleStart').string_value" to "2021-01-02" + And I set "scene.BIMWorkScheduleProperties.task_time_attributes.get('ScheduleFinish').string_value" to "2021-01-06" + And I press "bim.edit_task_time" + And I add a cube + And the object "Cube" is selected + And I set "scene.BIMRootProperties.ifc_class" to "IfcWall" + And I press "bim.assign_class" + And the object "IfcWall/Cube" is selected + And I press "bim.assign_product(task={task})" + And I set "scene.BIMWorkScheduleProperties.visualisation_start" to "01/01/21" + And I set "scene.BIMWorkScheduleProperties.visualisation_finish" to "01/02/21" + And I set "scene.BIMWorkScheduleProperties.speed_types" to "FRAME_SPEED" + And I set "scene.BIMWorkScheduleProperties.speed_animation_frames" to "7" + And I set "scene.BIMWorkScheduleProperties.speed_real_duration" to "1 w" + And I press "bim.visualise_work_schedule_date_range(work_schedule={work_schedule})" + And I press "bim.clear_previous_animation" + When I am on frame "3" + Then "scene.objects.get('IfcWall/Cube').hide_viewport" is "False" + And "scene.objects.get('IfcWall/Cube').hide_render" is "False" + And "scene.objects.get('IfcWall/Cube').color[:]" is "[1.0, 1.0, 1.0, 1]" + Scenario: Generate Gantt Chart Given an empty IFC project And I press "bim.add_work_schedule" @@ -808,4 +841,5 @@ Scenario: Duplicate Task and edit sequence Relationship And I press "bim.assign_successor(task={nested_task_two})" And I press "bim.duplicate_task(task={task})" When I press "bim.enable_editing_task_sequence(task={nested_task_one})" - Then nothing happens \ No newline at end of file + Then nothing happens +