mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 19:07:57 +00:00
New feature to see the current frame's real life date as text during a generated animation
This commit is contained in:
@@ -1312,7 +1312,9 @@ class IfcImporter:
|
||||
if "TargetView" in pset:
|
||||
camera.BIMCameraProperties.target_view = pset["TargetView"]
|
||||
if "Scale" in pset:
|
||||
valid_scales = [i[0] for i in get_diagram_scales(None, bpy.context) if pset["Scale"] == i[0].split("|")[-1]]
|
||||
valid_scales = [
|
||||
i[0] for i in get_diagram_scales(None, bpy.context) if pset["Scale"] == i[0].split("|")[-1]
|
||||
]
|
||||
if valid_scales:
|
||||
camera.BIMCameraProperties.diagram_scale = valid_scales[0]
|
||||
else:
|
||||
|
||||
@@ -116,7 +116,13 @@ class CreateAllShapes(bpy.types.Operator):
|
||||
start = time.time()
|
||||
try:
|
||||
shape = ifcopenshell.geom.create_shape(settings, element)
|
||||
print("Success", time.time()-start, len(shape.geometry.verts), len(shape.geometry.edges), len(shape.geometry.faces))
|
||||
print(
|
||||
"Success",
|
||||
time.time() - start,
|
||||
len(shape.geometry.verts),
|
||||
len(shape.geometry.edges),
|
||||
len(shape.geometry.faces),
|
||||
)
|
||||
except:
|
||||
failures.append(element)
|
||||
print("***** FAILURE *****")
|
||||
|
||||
@@ -102,7 +102,7 @@ class BIMProjectProperties(PropertyGroup):
|
||||
("BLACKLIST", "Blacklist", "Filter objects using a custom blacklist query"),
|
||||
],
|
||||
name="Filter Mode",
|
||||
update=update_filter_mode
|
||||
update=update_filter_mode,
|
||||
)
|
||||
filter_categories: CollectionProperty(name="Filter Categories", type=FilterCategory)
|
||||
active_filter_category_index: IntProperty(name="Active Filter Category Index")
|
||||
@@ -119,6 +119,5 @@ class BIMProjectProperties(PropertyGroup):
|
||||
links: CollectionProperty(name="Links", type=Link)
|
||||
active_link_index: IntProperty(name="Active Link Index")
|
||||
|
||||
|
||||
def get_library_element_index(self, lib_element):
|
||||
return next((i for i in range(len(self.library_elements)) if self.library_elements[i] == lib_element))
|
||||
|
||||
@@ -271,9 +271,9 @@ class BIM_UL_links(UIList):
|
||||
row.label(text=item.name)
|
||||
if item.is_loaded:
|
||||
op = row.operator("bim.unload_link", text="", icon="UNLINKED")
|
||||
op.filepath=item.name
|
||||
op.filepath = item.name
|
||||
else:
|
||||
op = row.operator("bim.load_link", text="", icon="LINKED")
|
||||
op.filepath=item.name
|
||||
op.filepath = item.name
|
||||
op = row.operator("bim.unlink_ifc", text="", icon="X")
|
||||
op.filepath=item.name
|
||||
op.filepath = item.name
|
||||
|
||||
@@ -109,6 +109,7 @@ classes = (
|
||||
prop.RecurrenceComponent,
|
||||
prop.BIMWorkCalendarProperties,
|
||||
prop.DatePickerProperties,
|
||||
prop.BIMDateTextProperties,
|
||||
ui.BIM_PT_work_plans,
|
||||
ui.BIM_PT_work_schedules,
|
||||
ui.BIM_PT_work_calendars,
|
||||
@@ -132,6 +133,7 @@ def register():
|
||||
bpy.types.Scene.BIMTaskTreeProperties = bpy.props.PointerProperty(type=prop.BIMTaskTreeProperties)
|
||||
bpy.types.Scene.BIMWorkCalendarProperties = bpy.props.PointerProperty(type=prop.BIMWorkCalendarProperties)
|
||||
bpy.types.Scene.DatePickerProperties = bpy.props.PointerProperty(type=prop.DatePickerProperties)
|
||||
bpy.types.TextCurve.BIMDateTextProperties = bpy.props.PointerProperty(type=prop.BIMDateTextProperties)
|
||||
bpy.types.TOPBAR_MT_file_import.append(menu_func_import)
|
||||
|
||||
|
||||
@@ -141,4 +143,5 @@ def unregister():
|
||||
del bpy.types.Scene.BIMTaskTreeProperties
|
||||
del bpy.types.Scene.BIMWorkCalendarProperties
|
||||
del bpy.types.Scene.DatePickerProperties
|
||||
del bpy.types.TextCurve.BIMDateTextProperties
|
||||
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
|
||||
|
||||
@@ -1742,11 +1742,12 @@ class VisualiseWorkScheduleDateRange(bpy.types.Operator):
|
||||
self.animate_input(obj, product_frame)
|
||||
elif product_frame["relationship"] == "output":
|
||||
self.animate_output(obj, product_frame)
|
||||
self.add_text_animation_handler()
|
||||
|
||||
area = next(area for area in context.screen.areas if area.type == "VIEW_3D")
|
||||
area.spaces[0].shading.color_type = "OBJECT"
|
||||
context.scene.frame_start = self.start_frame
|
||||
context.scene.frame_end = self.start_frame + self.total_frames
|
||||
context.scene.frame_end = int(self.start_frame + self.total_frames)
|
||||
# with open("/home/dion/animation.json", "w") as json_file:
|
||||
# guid_frames = {}
|
||||
# for k, v in self.product_frames.items():
|
||||
@@ -1754,6 +1755,35 @@ class VisualiseWorkScheduleDateRange(bpy.types.Operator):
|
||||
# json.dump(guid_frames, json_file)
|
||||
return {"FINISHED"}
|
||||
|
||||
def add_text_animation_handler(self):
|
||||
data = bpy.data.curves.get("Timeline")
|
||||
if not data:
|
||||
data = bpy.data.curves.new(type="FONT", name="Timeline")
|
||||
obj = bpy.data.objects.get("Timeline")
|
||||
if not obj:
|
||||
obj = bpy.data.objects.new(name="Timeline", object_data=data)
|
||||
bpy.context.scene.collection.objects.link(obj)
|
||||
obj.data.BIMDateTextProperties.start_frame = self.start_frame
|
||||
obj.data.BIMDateTextProperties.total_frames = int(self.total_frames)
|
||||
obj.data.BIMDateTextProperties.start = self.props.visualisation_start
|
||||
obj.data.BIMDateTextProperties.finish = self.props.visualisation_finish
|
||||
bpy.app.handlers.frame_change_post.append(self.animate_text)
|
||||
|
||||
def remove_text_animation_handler(self):
|
||||
bpy.app.handlers.frame_change_post.remove(self.animate_text)
|
||||
|
||||
def animate_text(self, scene, context):
|
||||
data = bpy.data.curves.get("Timeline")
|
||||
if not data or not bpy.data.objects.get("Timeline"):
|
||||
self.remove_text_animation_handler()
|
||||
scene.frame_current
|
||||
props = data.BIMDateTextProperties
|
||||
start = parser.parse(props.start, dayfirst=True, fuzzy=True)
|
||||
finish = parser.parse(props.finish, dayfirst=True, fuzzy=True)
|
||||
duration = finish - start
|
||||
frame_date = (((scene.frame_current - props.start_frame) / props.total_frames) * duration) + start
|
||||
data.body = frame_date.date().isoformat()
|
||||
|
||||
def animate_input(self, obj, product_frame):
|
||||
if product_frame["type"] in ["LOGISTIC", "MOVE", "DISPOSAL"]:
|
||||
self.animate_movement_from(obj, product_frame)
|
||||
|
||||
@@ -204,15 +204,15 @@ def updateTaskDuration(self, context):
|
||||
bpy.ops.bim.load_task_properties()
|
||||
|
||||
|
||||
def updateVisualisationStart(self, context):
|
||||
updateVisualisationStartFinish(self, context, "visualisation_start")
|
||||
def update_visualisation_start(self, context):
|
||||
update_visualisation_start_finish(self, context, "visualisation_start")
|
||||
|
||||
|
||||
def updateVisualisationFinish(self, context):
|
||||
updateVisualisationStartFinish(self, context, "visualisation_finish")
|
||||
def update_visualisation_finish(self, context):
|
||||
update_visualisation_start_finish(self, context, "visualisation_finish")
|
||||
|
||||
|
||||
def updateVisualisationStartFinish(self, context, startfinish):
|
||||
def update_visualisation_start_finish(self, context, startfinish):
|
||||
def canonicalise_time(time):
|
||||
if not time:
|
||||
return "-"
|
||||
@@ -316,8 +316,8 @@ class BIMWorkScheduleProperties(PropertyGroup):
|
||||
active_sequence_id: IntProperty(name="Active Sequence Id")
|
||||
sequence_attributes: CollectionProperty(name="Sequence Attributes", type=Attribute)
|
||||
time_lag_attributes: CollectionProperty(name="Time Lag Attributes", type=Attribute)
|
||||
visualisation_start: StringProperty(name="Visualisation Start", update=updateVisualisationStart)
|
||||
visualisation_finish: StringProperty(name="Visualisation Finish", update=updateVisualisationFinish)
|
||||
visualisation_start: StringProperty(name="Visualisation Start", update=update_visualisation_start)
|
||||
visualisation_finish: StringProperty(name="Visualisation Finish", update=update_visualisation_finish)
|
||||
speed_multiplier: FloatProperty(name="Speed Multiplier", default=10000)
|
||||
speed_animation_duration: StringProperty(name="Speed Animation Duration", default="PT1S")
|
||||
speed_animation_frames: IntProperty(name="Speed Animation Frames", default=24)
|
||||
@@ -388,3 +388,10 @@ class BIMWorkCalendarProperties(PropertyGroup):
|
||||
class DatePickerProperties(PropertyGroup):
|
||||
display_date: StringProperty()
|
||||
selected_date: StringProperty()
|
||||
|
||||
|
||||
class BIMDateTextProperties(PropertyGroup):
|
||||
start_frame: IntProperty(name="Start Frame")
|
||||
total_frames: IntProperty(name="Total Frames")
|
||||
start: StringProperty(name="Start")
|
||||
finish: StringProperty(name="Finish")
|
||||
|
||||
@@ -104,7 +104,7 @@ class ImportIFC(bpy.types.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
bpy.ops.bim.load_project('INVOKE_DEFAULT')
|
||||
bpy.ops.bim.load_project("INVOKE_DEFAULT")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -78,6 +78,10 @@ def additionally_the_object_name_is_selected(name):
|
||||
obj.select_set(True)
|
||||
|
||||
|
||||
def i_am_on_frame_number(number):
|
||||
bpy.context.scene.frame_set(int(number))
|
||||
|
||||
|
||||
def i_set_prop_to_value(prop, value):
|
||||
try:
|
||||
eval(f"bpy.context.{prop}")
|
||||
@@ -159,6 +163,10 @@ def the_object_name_is_not_in_the_collection_collection(name, collection):
|
||||
assert collection not in [c.name for c in the_object_name_exists(name).users_collection]
|
||||
|
||||
|
||||
def the_object_name_has_a_body_of_value(name, value):
|
||||
assert the_object_name_exists(name).data.body == value
|
||||
|
||||
|
||||
def the_collection_name1_is_in_the_collection_name2(name1, name2):
|
||||
assert bpy.data.collections.get(name2).children.get(name1)
|
||||
|
||||
@@ -256,7 +264,9 @@ def the_object_name_has_number_vertices(name, number):
|
||||
|
||||
def the_object_name_is_at_location(name, location):
|
||||
obj_location = the_object_name_exists(name).location
|
||||
assert (obj_location - Vector([float(co) for co in location.split(",")])).length < 0.1, f"Object is at {obj_location}"
|
||||
assert (
|
||||
obj_location - Vector([float(co) for co in location.split(",")])
|
||||
).length < 0.1, f"Object is at {obj_location}"
|
||||
|
||||
|
||||
definitions = {
|
||||
@@ -265,6 +275,7 @@ definitions = {
|
||||
'I add a cube of size "([0-9]+)" at "(.*)"': i_add_a_cube_of_size_size_at_location,
|
||||
'the object "(.*)" is selected': the_object_name_is_selected,
|
||||
'additionally the object "(.*)" is selected': additionally_the_object_name_is_selected,
|
||||
'I am on frame "([0-9]+)"': i_am_on_frame_number,
|
||||
'I set "(.*)" to "(.*)"': i_set_prop_to_value,
|
||||
'"(.*)" is "(.*)"': prop_is_value,
|
||||
'I enable "(.*)"': i_enable_prop,
|
||||
@@ -275,6 +286,7 @@ definitions = {
|
||||
'the object "(.*)" is not an IFC element': the_object_name_is_not_an_ifc_element,
|
||||
'the object "(.*)" is in the collection "(.*)"': the_object_name_is_in_the_collection_collection,
|
||||
'the object "(.*)" is not in the collection "(.*)"': the_object_name_is_not_in_the_collection_collection,
|
||||
'the object "(.*)" has a body of "(.*)"': the_object_name_has_a_body_of_value,
|
||||
'the collection "(.*)" is in the collection "(.*)"': the_collection_name1_is_in_the_collection_name2,
|
||||
'the collection "(.*)" is not in the collection "(.*)"': the_collection_name1_is_not_in_the_collection_name2,
|
||||
"an IFC file exists": an_ifc_file_exists,
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
@@ -0,0 +1,39 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
import test.bim.bootstrap
|
||||
|
||||
|
||||
class TestVisualiseWorkScheduleDateRange(test.bim.bootstrap.NewFile):
|
||||
@test.bim.bootstrap.scenario
|
||||
def test_seeing_the_current_frame_date_as_text(self):
|
||||
return """
|
||||
Given an empty IFC project
|
||||
And I press "bim.add_work_schedule"
|
||||
And I press "bim.enable_editing_tasks(work_schedule=72)"
|
||||
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 "P1W"
|
||||
And I press "bim.visualise_work_schedule_date_range(work_schedule=72)"
|
||||
When I am on frame "1"
|
||||
Then the object "Timeline" has a body of "2021-01-01"
|
||||
When I am on frame "2"
|
||||
Then the object "Timeline" has a body of "2021-01-02"
|
||||
"""
|
||||
@@ -0,0 +1,17 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
@@ -1,4 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
|
||||
This file is part of BlenderBIM Add-on.
|
||||
|
||||
BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
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/>.
|
||||
-->
|
||||
<ids xmlns="http://standards.buildingsmart.org/IDS" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://standards.buildingsmart.org/IDS ids_04.xsd">
|
||||
<specification name="Sample IDS" necessity="required">
|
||||
<applicability>
|
||||
|
||||
Reference in New Issue
Block a user