From 7deedf6ec904cffd55932a818534d37185f11f4b Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Sun, 3 May 2020 15:41:05 +1000 Subject: [PATCH] New UI to add annotation objects --- .../blenderbim/bim/__init__.py | 1 + .../blenderbim/bim/annotation.py | 59 +++++++++++++++++++ .../blenderbim/bim/operator.py | 21 +++++++ src/ifcblenderexport/blenderbim/bim/ui.py | 32 ++++++++++ 4 files changed, 113 insertions(+) create mode 100644 src/ifcblenderexport/blenderbim/bim/annotation.py diff --git a/src/ifcblenderexport/blenderbim/bim/__init__.py b/src/ifcblenderexport/blenderbim/bim/__init__.py index 86e4405ec5..bbd4d4f397 100644 --- a/src/ifcblenderexport/blenderbim/bim/__init__.py +++ b/src/ifcblenderexport/blenderbim/bim/__init__.py @@ -120,6 +120,7 @@ if bpy is not None: operator.AddIfcFile, operator.RemoveIfcFile, operator.SelectDocIfcFile, + operator.AddAnnotation, prop.StrProperty, prop.Classification, prop.ClassificationReference, diff --git a/src/ifcblenderexport/blenderbim/bim/annotation.py b/src/ifcblenderexport/blenderbim/bim/annotation.py new file mode 100644 index 0000000000..fa4ebbcf0b --- /dev/null +++ b/src/ifcblenderexport/blenderbim/bim/annotation.py @@ -0,0 +1,59 @@ +import bpy +from mathutils import Vector + +class Annotator: + + @staticmethod + def add_text(): + curve = bpy.data.curves.new(type='FONT', name='Text') + curve.body = 'TEXT' + obj = bpy.data.objects.new('Text', curve) + obj.matrix_world = bpy.context.scene.camera.matrix_world + co1, co2 = Annotator.get_placeholder_coords() + obj.location = co1 + obj.hide_render = True + bpy.context.scene.collection.objects.link(obj) + return obj + + @staticmethod + def add_line_to_annotation(obj): + co1, co2 = Annotator.get_placeholder_coords() + if isinstance(obj.data, bpy.types.Mesh): + obj.data.vertices.add(2) + obj.data.vertices[-2].co = co1 + obj.data.vertices[-1].co = co2 + obj.data.edges.add(2) + obj.data.edges[-1].vertices = (obj.data.vertices[-2].index, obj.data.vertices[-1].index) + if isinstance(obj.data, bpy.types.Curve): + polyline = obj.data.splines.new('POLY') + polyline.points.add(1) + polyline.points[-2].co = list(co1) + [1] + polyline.points[-1].co = list(co2) + [1] + return obj + + @staticmethod + def get_annotation_obj(name, data_type): + collection = bpy.context.scene.camera.users_collection[0] + for obj in collection.objects: + if name in obj.name: + return obj + if data_type == 'mesh': + data = bpy.data.meshes.new(name) + elif data_type == 'curve': + data = bpy.data.curves.new(name, type='CURVE') + data.dimensions = '3D' + data.resolution_u = 2 + obj = bpy.data.objects.new(name, data) + collection.objects.link(obj) + return obj + + @staticmethod + def get_placeholder_coords(): + camera = bpy.context.scene.camera + z_offset = camera.matrix_world.to_quaternion() @ Vector((0, 0, -1)) + if bpy.context.scene.render.resolution_x > bpy.context.scene.render.resolution_y: + y = camera.data.ortho_scale * (bpy.context.scene.render.resolution_y / bpy.context.scene.render.resolution_x) / 4 + else: + y = camera.data.ortho_scale / 4 + y_offset = camera.matrix_world.to_quaternion() @ Vector((0, y, 0)) + return (camera.location + z_offset, camera.location + z_offset + y_offset) diff --git a/src/ifcblenderexport/blenderbim/bim/operator.py b/src/ifcblenderexport/blenderbim/bim/operator.py index ee928ace28..5b92c679bb 100644 --- a/src/ifcblenderexport/blenderbim/bim/operator.py +++ b/src/ifcblenderexport/blenderbim/bim/operator.py @@ -13,6 +13,7 @@ from . import sheeter from . import schema from . import bcf from . import ifc +from . import annotation from bpy_extras.io_utils import ImportHelper from itertools import cycle from mathutils import Vector, Matrix, Euler @@ -2387,3 +2388,23 @@ class SelectDocIfcFile(bpy.types.Operator): def invoke(self, context, event): context.window_manager.fileselect_add(self) return {'RUNNING_MODAL'} + + +class AddAnnotation(bpy.types.Operator): + bl_idname = 'bim.add_annotation' + bl_label = 'Add Annotation' + obj_name = bpy.props.StringProperty() + data_type = bpy.props.StringProperty() + + def execute(self, context): + if not bpy.context.scene.camera: + return {'FINISHED'} + if self.data_type == 'text': + obj = annotation.Annotator.add_text() + else: + obj = annotation.Annotator.get_annotation_obj(self.obj_name, self.data_type) + obj = annotation.Annotator.add_line_to_annotation(obj) + bpy.ops.object.select_all(action='DESELECT') + bpy.context.view_layer.objects.active = obj + bpy.ops.object.mode_set(mode='EDIT') + return {'FINISHED'} diff --git a/src/ifcblenderexport/blenderbim/bim/ui.py b/src/ifcblenderexport/blenderbim/bim/ui.py index c6e25b4e33..eed7d87414 100644 --- a/src/ifcblenderexport/blenderbim/bim/ui.py +++ b/src/ifcblenderexport/blenderbim/bim/ui.py @@ -547,6 +547,38 @@ class BIM_PT_documentation(Panel): row.operator('bim.select_doc_ifc_file', icon='FILE_FOLDER', text='') row.operator('bim.remove_ifc_file', icon='X', text='').index = index + layout.label(text="Annotation:") + row = layout.row(align=True) + op = row.operator('bim.add_annotation', text='Dim', icon='ARROW_LEFTRIGHT') + op.obj_name = 'Dimension' + op.data_type = 'curve' + op = row.operator('bim.add_annotation', text='Dim (Eq)', icon='ARROW_LEFTRIGHT') + op.obj_name = 'Equal' + op.data_type = 'curve' + + row = layout.row(align=True) + op = row.operator('bim.add_annotation', text='Text', icon='SMALL_CAPS') + op.data_type = 'text' + op = row.operator('bim.add_annotation', text='Leader', icon='TRACKING_BACKWARDS') + op.obj_name = 'Leader' + op.data_type = 'curve' + + row = layout.row(align=True) + op = row.operator('bim.add_annotation', text='Stair Arrow', icon='SCREEN_BACK') + op.obj_name = 'Stair' + op.data_type = 'curve' + op = row.operator('bim.add_annotation', text='Hidden', icon='CON_TRACKTO') + op.obj_name = 'Hidden' + op.data_type = 'mesh' + + row = layout.row(align=True) + op = row.operator('bim.add_annotation', text='Level (Plan)', icon='SORTBYEXT') + op.obj_name = 'Plan Level' + op.data_type = 'curve' + op = row.operator('bim.add_annotation', text='Level (Section)', icon='TRIA_DOWN') + op.obj_name = 'Section Level' + op.data_type = 'curve' + row = layout.row() row.operator('bim.generate_digital_twin')