diff --git a/src/ifcblenderexport/blenderbim/__init__.py b/src/ifcblenderexport/blenderbim/__init__.py
index da448a7b07..d8ad5321f1 100644
--- a/src/ifcblenderexport/blenderbim/__init__.py
+++ b/src/ifcblenderexport/blenderbim/__init__.py
@@ -62,6 +62,7 @@ classes = (
operator.AddSubcontext,
operator.RemoveSubcontext,
operator.CutSection,
+ operator.CreateSheets,
prop.Subcontext,
prop.BIMProperties,
prop.DocProperties,
diff --git a/src/ifcblenderexport/blenderbim/cut_ifc.py b/src/ifcblenderexport/blenderbim/cut_ifc.py
index 208158d066..adb7fb2258 100644
--- a/src/ifcblenderexport/blenderbim/cut_ifc.py
+++ b/src/ifcblenderexport/blenderbim/cut_ifc.py
@@ -598,7 +598,9 @@ class SvgWriter():
self.output,
debug=False,
size=('{}mm'.format(self.width), '{}mm'.format(self.height)),
- viewBox=('0 0 {} {}'.format(self.width, self.height)))
+ viewBox=('0 0 {} {}'.format(self.width, self.height)),
+ id='root'
+ )
self.add_stylesheet()
self.add_defs()
@@ -622,7 +624,7 @@ class SvgWriter():
self.svg.defs.add(self.svg.style(stylesheet.read()))
def add_defs(self):
- tree = ET.parse('{}styles/defs.svg'.format(self.ifc_cutter.data_dir))
+ tree = ET.parse('{}templates/defs.svg'.format(self.ifc_cutter.data_dir))
root = tree.getroot()
for child in root.getchildren():
self.svg.defs.add(External(child))
@@ -651,11 +653,18 @@ class SvgWriter():
classes = ['annotation', 'dimension']
v0 = self.ifc_cutter.annotation_obj.data.vertices[edge.vertices[0]].co
v1 = self.ifc_cutter.annotation_obj.data.vertices[edge.vertices[1]].co
- start = ((x_offset + v0.x) * self.scale, (y_offset - v0.y) * self.scale)
- end = ((x_offset + v1.x) * self.scale, (y_offset - v1.y) * self.scale)
- line = self.svg.add(self.svg.line(start=start, end=end, class_=' '.join(classes)))
+ start = Vector(((x_offset + v0.x), (y_offset - v0.y)))
+ end = Vector(((x_offset + v1.x), (y_offset - v1.y)))
+ mid = ((end - start) / 2) + start
+ # TODO: hardcoded meters to mm conversion, until I properly do units
+ dimension = (end - start).length * 1000
+ line = self.svg.add(self.svg.line(start=tuple(start * self.scale),
+ end=tuple(end * self.scale), class_=' '.join(classes)))
line['marker-start'] = 'url(#dimension-marker)'
line['marker-end'] = 'url(#dimension-marker)'
+ self.svg.add(self.svg.text(str(round(dimension)), insert=tuple(mid * self.scale), **{
+ 'font-size': '0.2mm'
+ }))
def draw_cut_polygons(self):
for polygon in self.ifc_cutter.cut_polygons:
diff --git a/src/ifcblenderexport/blenderbim/data/sheets/sheet1.svg b/src/ifcblenderexport/blenderbim/data/sheets/sheet1.svg
new file mode 100644
index 0000000000..8381f3616c
--- /dev/null
+++ b/src/ifcblenderexport/blenderbim/data/sheets/sheet1.svg
@@ -0,0 +1,13 @@
+
+
diff --git a/src/ifcblenderexport/blenderbim/data/templates/defs.svg b/src/ifcblenderexport/blenderbim/data/templates/defs.svg
new file mode 100644
index 0000000000..2f90264534
--- /dev/null
+++ b/src/ifcblenderexport/blenderbim/data/templates/defs.svg
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/src/ifcblenderexport/blenderbim/data/templates/titleblock.svg b/src/ifcblenderexport/blenderbim/data/templates/titleblock.svg
new file mode 100644
index 0000000000..943a85c6c9
--- /dev/null
+++ b/src/ifcblenderexport/blenderbim/data/templates/titleblock.svg
@@ -0,0 +1,3084 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+ /home/dion/Projects/IfcOpenShell/src/ifcblenderexport/titleblock.dxf - scale = 1.000000, origin = (0.000000, 0.000000), method = manual
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DATE
+
+
+ REV. BY
+
+
+ REV. NO.
+
+
+ DESCRIPTION TO REVISION
+
+
+
+
+
+ CUSTOMER
+
+
+
+
+ REV.
+
+
+ REFERENCE TO:
+
+
+ DRG No.
+
+
+
+ SCALE
+
+
+ A1
+
+
+
+
+
+
+ PROJECT PORTION
+
+
+ CLIENT APPROVED
+
+
+ ENGINEER APPROVED
+
+
+ CHECKED PROPOSAL
+
+
+ APPROVED PROPOSAL
+
+
+
+ DRAWN BY:
+
+
+
+
+ PROJECT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DRAWING NUMBER?DRAWING
+
+
+ DRAWING REVISION?REV
+
+
+ REFERENCE DWG.REFERENCE
+
+
+ SCALE?SCALE
+
+
+ NAMENAME
+
+
+ CUSTOMER - 1CUSTOMER
+
+
+ CUSTOMER - 2CUSTOMER
+
+
+ PROJECT - 1PROJECT
+
+
+ PROJECT - 2PROJECT
+
+
+ PROJECT - 3PROJECT
+
+
+ PROJECT - 4PROJECT
+
+
+ PORTION DISC 1PORTION
+
+
+ PORTION DISC 2PORTION
+
+
+ REV. NO. ATEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. BTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. CTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. DTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. ETEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. FTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. GTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. HTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. JTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. KTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. LTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+
+
+
+ DATE
+
+
+ REV. BY
+
+
+ REV. NO.
+
+
+ DESCRIPTION TO REVISION
+
+
+
+
+
+ CUSTOMER
+
+
+
+
+ REV.
+
+
+ REFERENCE TO:
+
+
+ DRG No.
+
+
+
+ SCALE
+
+
+ A1
+
+
+
+
+
+
+ PROJECT PORTION
+
+
+ CLIENT APPROVED
+
+
+ ENGINEER APPROVED
+
+
+ CHECKED PROPOSAL
+
+
+ APPROVED PROPOSAL
+
+
+
+ DRAWN BY:
+
+
+
+
+ PROJECT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ This drawing has been prepared based on the following design criteria.
+
+ Falsework:Concrete Mass=kN/m³
+ Live Load=kN/m²
+ Max. Axial Load on Standard / Prop=kN
+ Max. Jack Thread Extension=mm (U.N.O)
+ {
+ Scaffolding:Max. Working Lifts=No.
+ Max. Working Lift Load=kg/m² (UDL)
+ Max. Axial Load on Standard=kN
+ {
+ Back Propping / Re-propping: As per the Concrete Design Engineer's instruction.
+
+
+
+
+
+
+
+
+
+
+
+
+
+ NOTES
+ {
+ 1) This drawing is the exclusive property of Form-Scaff, a division of Waco Africa (Pty) Limited. It is subject to recall by Form-Scaff and must not be reproduced or its contents divulged
+ to third parties without Form-Scaff's prior written permission having been obtained.
+ {
+ 2) This drawing has been prepared from information supplied to Form-Scaff by the user, and is subject to final approval by user. It is the user's responsibility to ensure that the information supplied
+ to Form-Scaff has been correctly interpreted by Form-Scaff and that all dimensions and details shown are correct.
+ {
+ 3) Notwithstanding the provision of this drawing by Form-Scaff to the user, design responsibilityrests solely with the user.
+
+ 4) The user is referred to the provisions of the OHS Act, the Construction Regulations, and any relevant Codes of Practice, and the user confirms by accepting this drawing that it is familiar with the
+ provisions of the aforesaid statute, regulations and codes. It is further recommended that the user should have due regard to the provisions of British Standard BS5975.
+ {
+ 5) The user must ensure that "Good Practice" is adopted on site.
+ {
+ 6) This drawing has no status beyond that expressly denoted on the drawing. Where applicable, the user must ensure that any methods or specific instructions shown on this drawing are in
+ accordance with the user's requirements.
+
+ 7) The user must approach Form-Scaff for any advice or assistance in interpreting or complying with any of the above, or in the event of there being any ambiguity, contradiction, error or omission
+ apparent from this drawing or in respect of the specifications or use of any Form-Scaff equipment.
+
+
+
+ DRAWING NUMBER?DRAWING
+
+
+ DRAWING REVISION?REV
+
+
+ REFERENCE DWG.REFERENCE
+
+
+ SCALE?SCALE
+
+
+ NAMENAME
+
+
+ CUSTOMER - 1CUSTOMER
+
+
+ CUSTOMER - 2CUSTOMER
+
+
+ PROJECT - 1PROJECT
+
+
+ PROJECT - 2PROJECT
+
+
+ PROJECT - 3PROJECT
+
+
+ PROJECT - 4PROJECT
+
+
+ PORTION DISC 1PORTION
+
+
+ PORTION DISC 2PORTION
+
+
+ Falsework Concrete Mass?FALSEWORK
+
+
+ Falsework Live Load?FALSEWORK
+
+
+ Falsework Max. Axial load on Std / Prop?FALSEWORK
+
+
+ Falsework Max. Jack Thread Ext?FALSEWORK
+
+
+ Formwork Concrete pressure?FORMWORK
+
+
+ Formwork Max. Formwork Mass?FORMWORK
+
+
+ Formwork Max. Mass of Gang-formed unit?FORMWORK
+
+
+ Formwork Max. Rate of Pour?FORMWORK
+
+
+ Formwork Ambient Temperature?FORMWORK
+
+
+ Scaffolding Max. Working Lifts?SCAFFOLDING
+
+
+ Scaffolding Max. Working Lift Load?SCAFFOLDING
+
+
+ Scaffolding Max. Axial Load on Standard?SCAFFOLDING
+
+
+ REV. NO. ATEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. BTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. CTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. DTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. ETEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. FTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. GTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. HTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. JTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. KTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+ REV. NO. LTEXT
+
+
+ REVISION DESCRIPTION:-TEXT
+
+
+ REVISED BY?TEXT
+
+
+ DATE OF REVISION?TEXT
+
+
+
+
+
+
+
+
+
+
+ REV. NO.
+
+
+
+
+
+
+
+
+
+
+
+
+ DESCRIPTION
+ AUTHOR
+ DATE
+
+
+ DRAWING NUMBER
+
+ REV
+ {{number}}
+ {{revision}}
+
+
+
+
+
+
+
diff --git a/src/ifcblenderexport/blenderbim/data/templates/view-title.svg b/src/ifcblenderexport/blenderbim/data/templates/view-title.svg
new file mode 100644
index 0000000000..a04f3d3fcb
--- /dev/null
+++ b/src/ifcblenderexport/blenderbim/data/templates/view-title.svg
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+ {{no}}
+ {{name}}
+ {{scale}}
+
+
diff --git a/src/ifcblenderexport/blenderbim/operator.py b/src/ifcblenderexport/blenderbim/operator.py
index c32b9ea491..d9aeb5449e 100644
--- a/src/ifcblenderexport/blenderbim/operator.py
+++ b/src/ifcblenderexport/blenderbim/operator.py
@@ -7,6 +7,7 @@ import ifcopenshell
from . import export_ifc
from . import import_ifc
from . import cut_ifc
+from . import sheeter
from bpy_extras.io_utils import ImportHelper
from itertools import cycle
from mathutils import Vector
@@ -809,3 +810,13 @@ class CutSection(bpy.types.Operator):
def is_landscape(self):
return bpy.context.scene.render.resolution_x > bpy.context.scene.render.resolution_y
+
+class CreateSheets(bpy.types.Operator):
+ bl_idname = 'bim.create_sheets'
+ bl_label = 'Create Sheets'
+
+ def execute(self, context):
+ sheet_builder = sheeter.SheetBuilder()
+ sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir
+ sheet_builder.build()
+ return {'FINISHED'}
diff --git a/src/ifcblenderexport/blenderbim/sheeter.py b/src/ifcblenderexport/blenderbim/sheeter.py
new file mode 100644
index 0000000000..1440bdc92a
--- /dev/null
+++ b/src/ifcblenderexport/blenderbim/sheeter.py
@@ -0,0 +1,51 @@
+import xml.etree.ElementTree as ET
+import pystache
+import ntpath
+import os
+from shutil import copy
+
+class SheetBuilder:
+ def __init__(self):
+ self.data_dir = None
+
+ def build(self):
+ sheet_path = '{}sheets/sheet1.svg'.format(self.data_dir)
+ sheet_filename = ntpath.basename(sheet_path)
+ sheet_name = sheet_filename[0:-4]
+
+ data = [
+ {'number': 'ASDF', 'revision': 'A'},
+ {},
+ {'no': '01', 'name': 'HOUSE', 'scale': '1:100'},
+ {},
+ {'no': '02', 'name': 'ELEVATION', 'scale': '1:100'},
+ {},
+ {'no': '03', 'name': 'PLAN', 'scale': '1:100'},
+ {},
+ {'no': '04', 'name': 'SECTION', 'scale': '1:100'},
+ ]
+ tree = ET.parse(sheet_path)
+ root = tree.getroot()
+ embedded_svgs = root.findall('{http://www.w3.org/2000/svg}svg')
+ n = 0
+ for svg in embedded_svgs:
+ use = svg.findall('{http://www.w3.org/2000/svg}use')[0]
+ source = use.attrib.get('{http://www.w3.org/1999/xlink}href')
+ source_path = source.split('#')[0]
+ source_filename = ntpath.basename(source_path)
+ source_background = '{}diagrams/{}.png'.format(self.data_dir, source_filename[0:-4])
+ source_anchor = source.split('#')[1]
+ dest_filename = '{}-{}.svg'.format(source_filename[0:-4], n)
+ os.makedirs('{}build/{}/'.format(self.data_dir, sheet_name), exist_ok=True)
+ with open('{}build/{}/{}'.format(self.data_dir, sheet_name, dest_filename), 'w') as out:
+ with open('{}sheets/{}'.format(self.data_dir, source_path), 'r') as template:
+ out.write(pystache.render(template.read(), data[n]))
+ use.set('{http://www.w3.org/1999/xlink}href',
+ '{}#{}'.format(dest_filename, source_anchor))
+ # TODO: hardcoded that all diagrams have a raster background
+ if 'diagrams/' in source_path:
+ copy(source_background, '{}build/{}/'.format(self.data_dir, sheet_name))
+ n += 1
+
+ with open('{}build/{}/{}'.format(self.data_dir, sheet_name, sheet_filename), 'wb') as output:
+ tree.write(output)
diff --git a/src/ifcblenderexport/blenderbim/ui.py b/src/ifcblenderexport/blenderbim/ui.py
index ddad30abec..f15aab8a79 100644
--- a/src/ifcblenderexport/blenderbim/ui.py
+++ b/src/ifcblenderexport/blenderbim/ui.py
@@ -196,6 +196,9 @@ class BIM_PT_documentation(Panel):
row = layout.row()
row.operator('bim.cut_section')
+ row = layout.row()
+ row.operator('bim.create_sheets')
+
class BIM_PT_context(Panel):
bl_label = "Geometric Representation Contexts"
bl_idname = "BIM_PT_context"