From bf4eb330e0a392c98d15f446cc5ddfcc6a754ad8 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Thu, 26 Mar 2020 18:26:35 +1100 Subject: [PATCH] New feature to add a sheet, and add a view to a sheet --- src/ifcblenderexport/blenderbim/__init__.py | 2 + src/ifcblenderexport/blenderbim/cut_ifc.py | 2 +- .../blenderbim/data/sheets/SHEET.svg | 4 ++ .../blenderbim/data/sheets/sheet1.svg | 13 ----- src/ifcblenderexport/blenderbim/operator.py | 26 +++++++++ src/ifcblenderexport/blenderbim/prop.py | 18 ++++++ src/ifcblenderexport/blenderbim/sheeter.py | 55 +++++++++++++++++++ src/ifcblenderexport/blenderbim/ui.py | 8 +++ 8 files changed, 114 insertions(+), 14 deletions(-) create mode 100644 src/ifcblenderexport/blenderbim/data/sheets/SHEET.svg delete mode 100644 src/ifcblenderexport/blenderbim/data/sheets/sheet1.svg diff --git a/src/ifcblenderexport/blenderbim/__init__.py b/src/ifcblenderexport/blenderbim/__init__.py index f8f62e8c2f..3a73ee0ce6 100644 --- a/src/ifcblenderexport/blenderbim/__init__.py +++ b/src/ifcblenderexport/blenderbim/__init__.py @@ -101,6 +101,8 @@ if bpy is not None: operator.AddSubcontext, operator.RemoveSubcontext, operator.CutSection, + operator.CreateSheet, + operator.AddViewToSheet, operator.CreateSheets, operator.GenerateDigitalTwin, operator.CreateView, diff --git a/src/ifcblenderexport/blenderbim/cut_ifc.py b/src/ifcblenderexport/blenderbim/cut_ifc.py index 41cf411207..9b4d2da1be 100644 --- a/src/ifcblenderexport/blenderbim/cut_ifc.py +++ b/src/ifcblenderexport/blenderbim/cut_ifc.py @@ -723,7 +723,7 @@ class SvgWriter(): def draw_background_image(self): self.svg.add(self.svg.image( - os.path.basename(self.ifc_cutter.background_image), **{ + os.path.join('..', 'diagrams', os.path.basename(self.ifc_cutter.background_image)), **{ 'width': self.width, 'height': self.height } diff --git a/src/ifcblenderexport/blenderbim/data/sheets/SHEET.svg b/src/ifcblenderexport/blenderbim/data/sheets/SHEET.svg new file mode 100644 index 0000000000..1650be34e7 --- /dev/null +++ b/src/ifcblenderexport/blenderbim/data/sheets/SHEET.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/ifcblenderexport/blenderbim/data/sheets/sheet1.svg b/src/ifcblenderexport/blenderbim/data/sheets/sheet1.svg deleted file mode 100644 index 8381f3616c..0000000000 --- a/src/ifcblenderexport/blenderbim/data/sheets/sheet1.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/ifcblenderexport/blenderbim/operator.py b/src/ifcblenderexport/blenderbim/operator.py index e4fc636db2..8b705e0c3a 100644 --- a/src/ifcblenderexport/blenderbim/operator.py +++ b/src/ifcblenderexport/blenderbim/operator.py @@ -1346,6 +1346,31 @@ class CutSection(bpy.types.Operator): def is_landscape(self): return bpy.context.scene.render.resolution_x > bpy.context.scene.render.resolution_y + +class CreateSheet(bpy.types.Operator): + bl_idname = 'bim.create_sheet' + bl_label = 'Create Sheet' + + def execute(self, context): + sheet_builder = sheeter.SheetBuilder() + sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir + sheet_builder.create(bpy.context.scene.DocProperties.sheet_name) + bpy.context.scene.DocProperties.sheet_name = '' + return {'FINISHED'} + + +class AddViewToSheet(bpy.types.Operator): + bl_idname = 'bim.add_view_to_sheet' + bl_label = 'Add View To Sheet' + + def execute(self, context): + props = bpy.context.scene.DocProperties + sheet_builder = sheeter.SheetBuilder() + sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir + sheet_builder.add_view(props.available_views, props.available_sheets) + return {'FINISHED'} + + class CreateSheets(bpy.types.Operator): bl_idname = 'bim.create_sheets' bl_label = 'Create Sheets' @@ -1356,6 +1381,7 @@ class CreateSheets(bpy.types.Operator): sheet_builder.build() return {'FINISHED'} + class GenerateDigitalTwin(bpy.types.Operator): bl_idname = 'bim.generate_digital_twin' bl_label = 'Generate Digital Twin' diff --git a/src/ifcblenderexport/blenderbim/prop.py b/src/ifcblenderexport/blenderbim/prop.py index a05e9239d5..4daa150cf4 100644 --- a/src/ifcblenderexport/blenderbim/prop.py +++ b/src/ifcblenderexport/blenderbim/prop.py @@ -42,6 +42,7 @@ target_views_enum = [] persons_enum = [] organisations_enum = [] views_enum = [] +sheets_enum = [] bcfviewpoints_enum = [] @persistent @@ -344,6 +345,21 @@ def getViews(self, context): return views_enum +def refreshSheets(self, context): + global sheets_enum + sheets_enum.clear() + getSheets(self, context) + +def getSheets(self, context): + global sheets_enum + if len(sheets_enum) < 1: + sheets_enum.clear() + for filename in Path(os.path.join(context.scene.BIMProperties.data_dir, 'sheets')).glob('*.svg'): + f = str(filename.stem) + sheets_enum.append((f, f, '')) + return sheets_enum + + class Subcontext(PropertyGroup): name: StringProperty(name='Name') target_view: StringProperty(name='Target View') @@ -353,6 +369,8 @@ class DocProperties(PropertyGroup): should_recut: BoolProperty(name="Should Recut", default=True) view_name: StringProperty(name="View Name") available_views: EnumProperty(items=getViews, name="Available Views") + sheet_name: StringProperty(name="Sheet Name", update=refreshSheets) + available_sheets: EnumProperty(items=getSheets, name="Available Sheets") class BIMCameraProperties(PropertyGroup): diff --git a/src/ifcblenderexport/blenderbim/sheeter.py b/src/ifcblenderexport/blenderbim/sheeter.py index 1440bdc92a..ca9491f424 100644 --- a/src/ifcblenderexport/blenderbim/sheeter.py +++ b/src/ifcblenderexport/blenderbim/sheeter.py @@ -3,11 +3,66 @@ import pystache import ntpath import os from shutil import copy +from xml.dom import minidom class SheetBuilder: def __init__(self): self.data_dir = None + def create(self, name): + sheet_path = '{}sheets/{}.svg'.format(self.data_dir, name) + root = ET.Element('svg') + root.attrib['xmlns'] = 'http://www.w3.org/2000/svg' + root.attrib['xmlns:xlink'] = 'http://www.w3.org/1999/xlink' + root.attrib['id'] = 'root' + root.attrib['version'] = '1.1' + root.attrib['width'] = '841mm' + root.attrib['height'] = '594mm' + + titleblock = ET.SubElement(root, 'image') + titleblock.attrib['xlink:href'] = '../templates/titleblock.svg' + titleblock.attrib['x'] = '0' + titleblock.attrib['y'] = '0' + titleblock.attrib['width'] = '841mm' + titleblock.attrib['height'] = '594mm' + + with open(sheet_path, 'w') as f: + f.write(minidom.parseString(ET.tostring(root)).toprettyxml(indent=' ')) + + def add_view(self, view_name, sheet_name): + sheet_path = '{}sheets/{}.svg'.format(self.data_dir, sheet_name) + view_path = '{}diagrams/{}.svg'.format(self.data_dir, view_name) + + ET.register_namespace('', 'http://www.w3.org/2000/svg') + ET.register_namespace('xlink', 'http://www.w3.org/1999/xlink') + + sheet_tree = ET.parse(sheet_path) + sheet_root = sheet_tree.getroot() + + view_tree = ET.parse(view_path) + view_root = view_tree.getroot() + + # The view is placed into a group with a background image element. + # Although the foreground SVG already has a background, it is duplicated + # here to accommodate browsers which do not nest images. + view = ET.SubElement(sheet_root, 'g') + + background = ET.SubElement(view, 'image') + background.attrib['xlink:href'] = '../diagrams/{}.png'.format(view_name) + background.attrib['x'] = '0' + background.attrib['y'] = '0' + background.attrib['width'] = view_root.attrib.get('width') + background.attrib['height'] = view_root.attrib.get('height') + + foreground = ET.SubElement(view, 'image') + foreground.attrib['xlink:href'] = '../diagrams/{}.svg'.format(view_name) + foreground.attrib['x'] = '0' + foreground.attrib['y'] = '0' + foreground.attrib['width'] = view_root.attrib.get('width') + foreground.attrib['height'] = view_root.attrib.get('height') + + sheet_tree.write(sheet_path) + def build(self): sheet_path = '{}sheets/sheet1.svg'.format(self.data_dir) sheet_filename = ntpath.basename(sheet_path) diff --git a/src/ifcblenderexport/blenderbim/ui.py b/src/ifcblenderexport/blenderbim/ui.py index 5653770516..e56b2ff281 100644 --- a/src/ifcblenderexport/blenderbim/ui.py +++ b/src/ifcblenderexport/blenderbim/ui.py @@ -309,6 +309,14 @@ class BIM_PT_documentation(Panel): row = layout.row() row.operator('bim.set_view_preset_1') + row = layout.row() + row.prop(props, 'sheet_name') + row.operator('bim.create_sheet', icon='ADD', text='') + + row = layout.row() + row.prop(props, 'available_sheets') + row.operator('bim.add_view_to_sheet', icon='ADD', text='') + row = layout.row() row.operator('bim.create_sheets')