mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +00:00
You can now add schedules to sheets
This commit is contained in:
@@ -117,7 +117,6 @@ if bpy is not None:
|
||||
operator.CutSection,
|
||||
operator.AddSheet,
|
||||
operator.OpenSheet,
|
||||
operator.OpenCompiledSheet,
|
||||
operator.AddDrawingToSheet,
|
||||
operator.CreateSheets,
|
||||
operator.OpenView,
|
||||
@@ -190,6 +189,7 @@ if bpy is not None:
|
||||
operator.RemoveSchedule,
|
||||
operator.SelectScheduleFile,
|
||||
operator.BuildSchedule,
|
||||
operator.AddScheduleToSheet,
|
||||
prop.StrProperty,
|
||||
prop.Variable,
|
||||
prop.Role,
|
||||
|
||||
@@ -8,7 +8,6 @@ import webbrowser
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.selector
|
||||
import tempfile
|
||||
import ntpath
|
||||
from . import export_ifc
|
||||
from . import import_ifc
|
||||
from . import qto
|
||||
@@ -2196,19 +2195,6 @@ class OpenSheet(bpy.types.Operator):
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class OpenCompiledSheet(bpy.types.Operator):
|
||||
bl_idname = 'bim.open_compiled_sheet'
|
||||
bl_label = 'Open Compiled Sheet'
|
||||
|
||||
def execute(self, context):
|
||||
props = bpy.context.scene.DocProperties
|
||||
webbrowser.open('file://' + os.path.join(
|
||||
bpy.context.scene.BIMProperties.data_dir, 'build',
|
||||
props.sheets[props.active_sheet_index].name,
|
||||
props.sheets[props.active_sheet_index].name + '.svg'))
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AddDrawingToSheet(bpy.types.Operator):
|
||||
bl_idname = 'bim.add_drawing_to_sheet'
|
||||
bl_label = 'Add Drawing To Sheet'
|
||||
@@ -2217,7 +2203,7 @@ class AddDrawingToSheet(bpy.types.Operator):
|
||||
props = bpy.context.scene.DocProperties
|
||||
sheet_builder = sheeter.SheetBuilder()
|
||||
sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir
|
||||
sheet_builder.add_view(
|
||||
sheet_builder.add_drawing(
|
||||
props.drawings[props.active_drawing_index].name,
|
||||
props.sheets[props.active_sheet_index].name)
|
||||
return {'FINISHED'}
|
||||
@@ -3678,7 +3664,21 @@ class BuildSchedule(bpy.types.Operator):
|
||||
schedule_creator = scheduler.Scheduler()
|
||||
outfile = os.path.join(
|
||||
bpy.context.scene.BIMProperties.data_dir, 'schedules',
|
||||
ntpath.basename(schedule.file).replace('.ods', '.svg'))
|
||||
schedule.name + '.svg')
|
||||
schedule_creator.schedule(schedule.file, outfile)
|
||||
webbrowser.open('file://' + outfile)
|
||||
return {'FINISHED'}
|
||||
|
||||
|
||||
class AddScheduleToSheet(bpy.types.Operator):
|
||||
bl_idname = 'bim.add_schedule_to_sheet'
|
||||
bl_label = 'Add Schedule 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_schedule(
|
||||
props.schedules[props.active_schedule_index].name,
|
||||
props.sheets[props.active_sheet_index].name)
|
||||
return {'FINISHED'}
|
||||
|
||||
@@ -45,7 +45,7 @@ class Scheduler():
|
||||
repeat = int(repeat) if repeat else 1
|
||||
for i in range(0, repeat):
|
||||
width = column_widths[tdi]
|
||||
self.svg.add(self.svg.rect(insert=(x, y), size=(width, height), style='fill:rgba(255,255,255,1); stroke-width:.125; stroke:rgb(0,0,0)'))
|
||||
self.svg.add(self.svg.rect(insert=(x, y), size=(width, height), style='fill: #ffffff; stroke-width:.125; stroke: #000000;'))
|
||||
value = td.getElementsByType(P)
|
||||
if value:
|
||||
self.add_text(value[0], x+self.padding, y+self.padding)
|
||||
|
||||
@@ -21,7 +21,9 @@ class SheetBuilder:
|
||||
root.attrib['width'] = '841mm'
|
||||
root.attrib['height'] = '594mm'
|
||||
|
||||
titleblock = ET.SubElement(root, 'image')
|
||||
view = ET.SubElement(root, 'g')
|
||||
view.attrib['data-type'] = 'titleblock'
|
||||
titleblock = ET.SubElement(view, 'image')
|
||||
titleblock.attrib['xlink:href'] = '../templates/titleblock.svg'
|
||||
titleblock.attrib['x'] = '0'
|
||||
titleblock.attrib['y'] = '0'
|
||||
@@ -31,9 +33,9 @@ class SheetBuilder:
|
||||
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)
|
||||
def add_drawing(self, view_name, sheet_name):
|
||||
sheet_path = os.path.join(self.data_dir, 'sheets', sheet_name + '.svg')
|
||||
view_path = os.path.join(self.data_dir, 'diagrams', view_name + '.svg')
|
||||
|
||||
ET.register_namespace('', 'http://www.w3.org/2000/svg')
|
||||
ET.register_namespace('xlink', 'http://www.w3.org/1999/xlink')
|
||||
@@ -48,6 +50,7 @@ class SheetBuilder:
|
||||
# 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')
|
||||
view.attrib['data-type'] = 'drawing'
|
||||
|
||||
background = ET.SubElement(view, 'image')
|
||||
background.attrib['xlink:href'] = '../diagrams/{}.png'.format(view_name)
|
||||
@@ -70,6 +73,36 @@ class SheetBuilder:
|
||||
|
||||
sheet_tree.write(sheet_path)
|
||||
|
||||
def add_schedule(self, schedule_name, sheet_name):
|
||||
sheet_path = os.path.join(self.data_dir, 'sheets', sheet_name + '.svg')
|
||||
view_path = os.path.join(self.data_dir, 'schedules', schedule_name + '.svg')
|
||||
|
||||
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()
|
||||
|
||||
group = ET.SubElement(sheet_root, 'g')
|
||||
group.attrib['data-type'] = 'schedule'
|
||||
|
||||
foreground = ET.SubElement(group, 'image')
|
||||
foreground.attrib['xlink:href'] = '../schedules/{}.svg'.format(schedule_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')
|
||||
|
||||
title = ET.SubElement(group, 'image')
|
||||
title.attrib['xlink:href'] = '../templates/view-title.svg'
|
||||
title.attrib['x'] = '0'
|
||||
title.attrib['y'] = view_root.attrib.get('height')
|
||||
|
||||
sheet_tree.write(sheet_path)
|
||||
|
||||
def build(self, sheet_name):
|
||||
os.makedirs('{}build/{}/'.format(self.data_dir, sheet_name), exist_ok=True)
|
||||
|
||||
@@ -81,17 +114,23 @@ class SheetBuilder:
|
||||
tree = ET.parse(sheet_path)
|
||||
root = tree.getroot()
|
||||
|
||||
titleblock = root.findall('{http://www.w3.org/2000/svg}image')[0]
|
||||
root.append(self.parse_embedded_svg(titleblock, {
|
||||
titleblock = root.findall('{http://www.w3.org/2000/svg}g[@data-type="titleblock"]')[0]
|
||||
image = titleblock.findall('{http://www.w3.org/2000/svg}image')[0]
|
||||
titleblock.append(self.parse_embedded_svg(image, {
|
||||
'number': sheet_name,
|
||||
'revision': 'A'
|
||||
}))
|
||||
root.remove(titleblock)
|
||||
titleblock.remove(image)
|
||||
|
||||
views = root.findall('{http://www.w3.org/2000/svg}g')
|
||||
self.group_number = 1
|
||||
self.build_drawings(root.findall('{http://www.w3.org/2000/svg}g[@data-type="drawing"]'), sheet_name)
|
||||
self.build_schedules(root.findall('{http://www.w3.org/2000/svg}g[@data-type="schedule"]'))
|
||||
|
||||
view_number = 1
|
||||
for view in views:
|
||||
with open('{}build/{}/{}.svg'.format(self.data_dir, sheet_name, sheet_name), 'wb') as output:
|
||||
tree.write(output)
|
||||
|
||||
def build_drawings(self, drawings, sheet_name):
|
||||
for view in drawings:
|
||||
images = view.findall('{http://www.w3.org/2000/svg}image')
|
||||
background = images[0]
|
||||
foreground = images[1]
|
||||
@@ -108,7 +147,7 @@ class SheetBuilder:
|
||||
# Add view title
|
||||
foreground_path = self.get_href(foreground)
|
||||
view.append(self.parse_embedded_svg(view_title, {
|
||||
'no' : view_number,
|
||||
'no' : self.group_number,
|
||||
'name': ntpath.basename(foreground_path)[0:-4],
|
||||
'scale': self.scale
|
||||
}))
|
||||
@@ -116,10 +155,28 @@ class SheetBuilder:
|
||||
for image in images:
|
||||
view.remove(image)
|
||||
|
||||
view_number += 1
|
||||
self.group_number += 1
|
||||
|
||||
with open('{}build/{}/{}.svg'.format(self.data_dir, sheet_name, sheet_name), 'wb') as output:
|
||||
tree.write(output)
|
||||
def build_schedules(self, schedules):
|
||||
for group in schedules:
|
||||
images = group.findall('{http://www.w3.org/2000/svg}image')
|
||||
schedule = images[0]
|
||||
group_title = images[1]
|
||||
self.scale = 'NTS'
|
||||
|
||||
group.append(self.parse_embedded_svg(schedule, {}))
|
||||
|
||||
path = self.get_href(schedule)
|
||||
group.append(self.parse_embedded_svg(group_title, {
|
||||
'no' : self.group_number,
|
||||
'name': ntpath.basename(path)[0:-4],
|
||||
'scale': self.scale
|
||||
}))
|
||||
|
||||
for image in images:
|
||||
group.remove(image)
|
||||
|
||||
self.group_number += 1
|
||||
|
||||
def get_href(self, element):
|
||||
return urllib.parse.unquote(element.attrib.get('{http://www.w3.org/1999/xlink}href'))
|
||||
|
||||
@@ -793,13 +793,14 @@ class BIM_PT_sheets(Panel):
|
||||
|
||||
if props.sheets:
|
||||
row.operator('bim.open_sheet', icon='URL', text='')
|
||||
row.operator('bim.open_compiled_sheet', icon='OUTPUT', text='')
|
||||
row.operator('bim.remove_sheet', icon='X', text='').index = props.active_sheet_index
|
||||
|
||||
layout.template_list('BIM_UL_generic', '', props, 'sheets', props, 'active_sheet_index')
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator('bim.add_drawing_to_sheet')
|
||||
row.operator('bim.add_schedule_to_sheet')
|
||||
row = layout.row()
|
||||
row.operator('bim.create_sheets')
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user