From 1ff6f691acb2108f77f9c8b53e7425336b56095d Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Thu, 30 Mar 2023 18:31:39 +0500 Subject: [PATCH] Clever STAIR_ARROW annotation Now adding STAIR_ARROW annotation is a bit more clever - if you have IfcStairFlight selected when adding this type of annotation it will automatically: 1) define stair as it's parent; 2) add the stair as it's product; 3) place itself along the stair (it's assumed that stair direction is X+) Example - https://i.imgur.com/Ze9DoK2.png --- .../blenderbim/bim/module/model/stair.py | 1 + src/blenderbim/blenderbim/core/drawing.py | 1 + src/blenderbim/blenderbim/core/tool.py | 26 ++++++++++++------- src/blenderbim/blenderbim/tool/blender.py | 18 +++++++++++++ src/blenderbim/blenderbim/tool/drawing.py | 21 +++++++++++++++ src/blenderbim/test/core/test_drawing.py | 1 + 6 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/model/stair.py b/src/blenderbim/blenderbim/bim/module/model/stair.py index 86a1d03c26..19df757fff 100644 --- a/src/blenderbim/blenderbim/bim/module/model/stair.py +++ b/src/blenderbim/blenderbim/bim/module/model/stair.py @@ -286,6 +286,7 @@ def update_ifc_stair_props(obj): }, ) tool.Ifc.edit(obj) + # TODO: update related STAIR_ARROW products class BIM_OT_add_clever_stair(bpy.types.Operator, tool.Ifc.Operator): diff --git a/src/blenderbim/blenderbim/core/drawing.py b/src/blenderbim/blenderbim/core/drawing.py index cf45f59e8b..d0a2852070 100644 --- a/src/blenderbim/blenderbim/core/drawing.py +++ b/src/blenderbim/blenderbim/core/drawing.py @@ -232,6 +232,7 @@ def add_annotation(ifc, collector, drawing_tool, drawing=None, object_type=None) ) ifc.run("group.assign_group", group=drawing_tool.get_drawing_group(drawing), products=[element]) collector.assign(obj) + drawing_tool.setup_annotation_object(obj, object_type) drawing_tool.enable_editing(obj) diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 3aaf2b0419..4f88afe1fe 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -71,16 +71,21 @@ class Aggregate: @interface -class Blender: pass -def create_ifc_object(cls, ifc_class, name, data): pass -def get_name(cls, ifc_class, name): pass -def get_obj_ifc_definition_id(cls, obj, obj_type): pass -def get_selected_objects(cls): pass -def set_active_object(cls, obj): pass -def apply_bmesh(cls, mesh, bm): pass -def get_bmesh_for_mesh(cls, mesh, clean=False): pass -def get_viewport_context(cls): pass -def update_viewport(cls): pass +class Blender: + def set_active_object(cls, obj): pass + def get_name(cls, ifc_class, name): pass + def get_selected_objects(cls): pass + def create_ifc_object(cls, ifc_class: str, name: str = None, data=None): pass + def get_obj_ifc_definition_id(cls, obj=None, obj_type=None): pass + def is_ifc_object(cls, obj): pass + def is_ifc_class_active(cls, ifc_class): pass + def get_viewport_context(cls): pass + def update_viewport(cls): pass + def get_default_selection_keypmap(cls): pass + def get_object_bounding_box(cls, obj): pass + def apply_bmesh(cls, mesh, bm): pass + def get_bmesh_for_mesh(cls, mesh, clean=False): pass + def bmesh_join(cls, bm_a, bm_b, callback=None): pass @interface @@ -223,6 +228,7 @@ class Drawing: def activate_view(cls, camera): pass def copy_representation(cls, source, dest): pass def create_annotation_object(cls, drawing, object_type): pass + def setup_annotation_object(cls, obj, object_type): pass def create_camera(cls, name, matrix): pass def create_svg_schedule(cls, schedule): pass def create_svg_sheet(cls, document, titleblock): pass diff --git a/src/blenderbim/blenderbim/tool/blender.py b/src/blenderbim/blenderbim/tool/blender.py index 2fee26dbd2..5c423f0d64 100644 --- a/src/blenderbim/blenderbim/tool/blender.py +++ b/src/blenderbim/blenderbim/tool/blender.py @@ -160,6 +160,24 @@ class Blender: ) return keymap + @classmethod + def get_object_bounding_box(cls, obj): + """Returns dict with local min and max x, y, z values for the object. + + Careful with using this method for objects in EDIT mode because + it requires all EDIT mode changes to be applied. + """ + bound_box = obj.bound_box + bbox_dict = { + "min_x": bound_box[0][0], + "max_x": bound_box[6][0], + "min_y": bound_box[0][1], + "max_y": bound_box[6][1], + "min_z": bound_box[0][2], + "max_z": bound_box[6][2], + } + return bbox_dict + ## BMESH UTILS ## @classmethod def apply_bmesh(cls, mesh, bm): diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index c30f270c68..2eb15cf504 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -38,6 +38,8 @@ import blenderbim.bim.module.drawing.helper as helper from blenderbim.bim.module.drawing.data import FONT_SIZES, DecoratorData from blenderbim.bim.module.drawing.prop import get_diagram_scales, BOX_ALIGNMENT_POSITIONS +from mathutils import Vector + class Drawing(blenderbim.core.tool.Drawing): @classmethod @@ -74,8 +76,27 @@ class Drawing(blenderbim.core.tool.Drawing): obj = annotation.Annotator.add_line_to_annotation(obj, co2, co1) elif object_type != "TEXT": obj = annotation.Annotator.add_line_to_annotation(obj) + return obj + @classmethod + def setup_annotation_object(cls, obj, object_type): + """Finish object's adjustments after both object and entity are created""" + if object_type == "STAIR_ARROW": + stair = bpy.context.active_object + stair_entity = tool.Ifc.get_entity(stair) + if stair_entity and stair_entity.is_a("IfcStairFlight"): + arrow = obj + arrow_element = tool.Ifc.get_entity(arrow) + arrow.parent = stair + + # place the arrow + bbox = tool.Blender.get_object_bounding_box(stair) + arrow.location = Vector((bbox["min_x"], (bbox["max_y"] - bbox["min_y"]) / 2, bbox["max_z"])) + arrow.data.splines[0].points[1].co = Vector((bbox["max_x"], 0, 0, 1)) + + tool.Ifc.run("drawing.assign_product", relating_product=stair_entity, related_object=arrow_element) + @classmethod def create_camera(cls, name, matrix): camera = bpy.data.objects.new(name, bpy.data.cameras.new(name)) diff --git a/src/blenderbim/test/core/test_drawing.py b/src/blenderbim/test/core/test_drawing.py index f66b13c596..f4d0d4777b 100644 --- a/src/blenderbim/test/core/test_drawing.py +++ b/src/blenderbim/test/core/test_drawing.py @@ -321,6 +321,7 @@ class TestAddAnnotation: drawing.get_drawing_group("drawing").should_be_called().will_return("group") ifc.run("group.assign_group", group="group", products=["element"]).should_be_called() collector.assign("obj").should_be_called() + drawing.setup_annotation_object("obj", "object_type").should_be_called() drawing.enable_editing("obj").should_be_called() subject.add_annotation(ifc, collector, drawing, drawing="drawing", object_type="object_type")