mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 06:39:13 +00:00
Compile views and sheets with automatic numbers, names, and scales
This commit is contained in:
@@ -103,6 +103,7 @@ if bpy is not None:
|
|||||||
operator.CutSection,
|
operator.CutSection,
|
||||||
operator.CreateSheet,
|
operator.CreateSheet,
|
||||||
operator.OpenSheet,
|
operator.OpenSheet,
|
||||||
|
operator.OpenCompiledSheet,
|
||||||
operator.AddViewToSheet,
|
operator.AddViewToSheet,
|
||||||
operator.CreateSheets,
|
operator.CreateSheets,
|
||||||
operator.GenerateDigitalTwin,
|
operator.GenerateDigitalTwin,
|
||||||
|
|||||||
@@ -1385,6 +1385,18 @@ class OpenSheet(bpy.types.Operator):
|
|||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
class OpenCompiledSheet(bpy.types.Operator):
|
||||||
|
bl_idname = 'bim.open_compiled_sheet'
|
||||||
|
bl_label = 'Open Compiled Sheet'
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
webbrowser.open('file:///' + os.path.join(
|
||||||
|
bpy.context.scene.BIMProperties.data_dir, 'build',
|
||||||
|
bpy.context.scene.DocProperties.available_sheets,
|
||||||
|
bpy.context.scene.DocProperties.available_sheets + '.svg'))
|
||||||
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
class AddViewToSheet(bpy.types.Operator):
|
class AddViewToSheet(bpy.types.Operator):
|
||||||
bl_idname = 'bim.add_view_to_sheet'
|
bl_idname = 'bim.add_view_to_sheet'
|
||||||
bl_label = 'Add View To Sheet'
|
bl_label = 'Add View To Sheet'
|
||||||
@@ -1404,7 +1416,7 @@ class CreateSheets(bpy.types.Operator):
|
|||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
sheet_builder = sheeter.SheetBuilder()
|
sheet_builder = sheeter.SheetBuilder()
|
||||||
sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir
|
sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir
|
||||||
sheet_builder.build()
|
sheet_builder.build(bpy.context.scene.DocProperties.available_sheets)
|
||||||
return {'FINISHED'}
|
return {'FINISHED'}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
|
import urllib.parse
|
||||||
import pystache
|
import pystache
|
||||||
import ntpath
|
import ntpath
|
||||||
import os
|
import os
|
||||||
@@ -8,6 +9,7 @@ from xml.dom import minidom
|
|||||||
class SheetBuilder:
|
class SheetBuilder:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.data_dir = None
|
self.data_dir = None
|
||||||
|
self.scale = 'NTS'
|
||||||
|
|
||||||
def create(self, name):
|
def create(self, name):
|
||||||
sheet_path = '{}sheets/{}.svg'.format(self.data_dir, name)
|
sheet_path = '{}sheets/{}.svg'.format(self.data_dir, name)
|
||||||
@@ -68,44 +70,70 @@ class SheetBuilder:
|
|||||||
|
|
||||||
sheet_tree.write(sheet_path)
|
sheet_tree.write(sheet_path)
|
||||||
|
|
||||||
def build(self):
|
def build(self, sheet_name):
|
||||||
sheet_path = '{}sheets/sheet1.svg'.format(self.data_dir)
|
os.makedirs('{}build/{}/'.format(self.data_dir, sheet_name), exist_ok=True)
|
||||||
sheet_filename = ntpath.basename(sheet_path)
|
|
||||||
sheet_name = sheet_filename[0:-4]
|
sheet_path = '{}sheets/{}.svg'.format(self.data_dir, sheet_name)
|
||||||
|
|
||||||
|
ET.register_namespace('', 'http://www.w3.org/2000/svg')
|
||||||
|
ET.register_namespace('xlink', 'http://www.w3.org/1999/xlink')
|
||||||
|
|
||||||
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)
|
tree = ET.parse(sheet_path)
|
||||||
root = tree.getroot()
|
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:
|
titleblock = root.findall('{http://www.w3.org/2000/svg}image')[0]
|
||||||
|
root.append(self.parse_embedded_svg(titleblock, {
|
||||||
|
'number': sheet_name,
|
||||||
|
'revision': 'A'
|
||||||
|
}))
|
||||||
|
root.remove(titleblock)
|
||||||
|
|
||||||
|
views = root.findall('{http://www.w3.org/2000/svg}g')
|
||||||
|
|
||||||
|
view_number = 1
|
||||||
|
for view in views:
|
||||||
|
images = view.findall('{http://www.w3.org/2000/svg}image')
|
||||||
|
background = images[0]
|
||||||
|
foreground = images[1]
|
||||||
|
view_title = images[2]
|
||||||
|
self.scale = 'NTS'
|
||||||
|
|
||||||
|
# Add foreground
|
||||||
|
view.append(self.parse_embedded_svg(foreground, {}))
|
||||||
|
|
||||||
|
# Add background
|
||||||
|
background_path = '{}sheets/{}'.format(self.data_dir, self.get_href(background))
|
||||||
|
copy(background_path, '{}build/{}/'.format(self.data_dir, sheet_name))
|
||||||
|
|
||||||
|
# Add view title
|
||||||
|
foreground_path = self.get_href(foreground)
|
||||||
|
view.append(self.parse_embedded_svg(view_title, {
|
||||||
|
'no' : view_number,
|
||||||
|
'name': ntpath.basename(foreground_path)[0:-4],
|
||||||
|
'scale': self.scale
|
||||||
|
}))
|
||||||
|
|
||||||
|
for image in images:
|
||||||
|
view.remove(image)
|
||||||
|
|
||||||
|
view_number += 1
|
||||||
|
|
||||||
|
with open('{}build/{}/{}.svg'.format(self.data_dir, sheet_name, sheet_name), 'wb') as output:
|
||||||
tree.write(output)
|
tree.write(output)
|
||||||
|
|
||||||
|
def get_href(self, element):
|
||||||
|
return urllib.parse.unquote(element.attrib.get('{http://www.w3.org/1999/xlink}href'))
|
||||||
|
|
||||||
|
def parse_embedded_svg(self, image, data):
|
||||||
|
group = ET.Element('g')
|
||||||
|
group.attrib['transform'] = 'translate({},{})'.format(image.attrib.get('x'), image.attrib.get('y'))
|
||||||
|
svg_path = self.get_href(image)
|
||||||
|
with open('{}sheets/{}'.format(self.data_dir, svg_path), 'r') as template:
|
||||||
|
embedded = ET.fromstring(pystache.render(template.read(), data))
|
||||||
|
self.scale = embedded.attrib.get('data-scale')
|
||||||
|
images = embedded.findall('{http://www.w3.org/2000/svg}image')
|
||||||
|
for image in images:
|
||||||
|
new_href = ntpath.basename(image.attrib.get('{http://www.w3.org/1999/xlink}href'))
|
||||||
|
image.attrib['{http://www.w3.org/1999/xlink}href'] = new_href
|
||||||
|
group.append(embedded)
|
||||||
|
return group
|
||||||
|
|||||||
@@ -311,12 +311,13 @@ class BIM_PT_documentation(Panel):
|
|||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(props, 'available_views')
|
row.prop(props, 'available_views')
|
||||||
row.operator('bim.activate_view', icon='SCENE', text='')
|
|
||||||
row.operator('bim.open_view', icon='URL', text='')
|
row.operator('bim.open_view', icon='URL', text='')
|
||||||
|
row.operator('bim.activate_view', icon='SCENE', text='')
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.prop(props, 'available_sheets')
|
row.prop(props, 'available_sheets')
|
||||||
row.operator('bim.open_sheet', icon='URL', text='')
|
row.operator('bim.open_sheet', icon='URL', text='')
|
||||||
|
row.operator('bim.open_compiled_sheet', icon='OUTPUT', text='')
|
||||||
|
|
||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.operator('bim.add_view_to_sheet')
|
row.operator('bim.add_view_to_sheet')
|
||||||
|
|||||||
Reference in New Issue
Block a user