#1153 Reimplement ability to build SVG tables from referenced ODS documents

This commit is contained in:
Dion Moult
2022-04-28 19:57:47 +10:00
parent 952d1c3b79
commit 6bcf00ef31
8 changed files with 65 additions and 48 deletions
@@ -624,7 +624,7 @@ class CreateSheets(bpy.types.Operator):
props = scene.DocProperties props = scene.DocProperties
active_sheet = props.sheets[props.active_sheet_index] active_sheet = props.sheets[props.active_sheet_index]
sheet = tool.Ifc.get().by_id(active_sheet.ifc_definition_id) sheet = tool.Ifc.get().by_id(active_sheet.ifc_definition_id)
name = tool.Drawing.get_sheet_filename(sheet) name = os.path.splitext(os.path.basename(tool.Drawing.get_document_uri(sheet)))[0]
sheet_builder = sheeter.SheetBuilder() sheet_builder = sheeter.SheetBuilder()
sheet_builder.data_dir = scene.BIMProperties.data_dir sheet_builder.data_dir = scene.BIMProperties.data_dir
sheet_builder.build(sheet) sheet_builder.build(sheet)
@@ -956,18 +956,13 @@ class OpenSchedule(bpy.types.Operator, Operator):
core.open_schedule(tool.Drawing, schedule=tool.Ifc.get().by_id(self.schedule)) core.open_schedule(tool.Drawing, schedule=tool.Ifc.get().by_id(self.schedule))
class BuildSchedule(bpy.types.Operator): class BuildSchedule(bpy.types.Operator, Operator):
bl_idname = "bim.build_schedule" bl_idname = "bim.build_schedule"
bl_label = "Build Schedule" bl_label = "Build Schedule"
schedule: bpy.props.IntProperty()
def execute(self, context): def _execute(self, context):
props = context.scene.DocProperties core.build_schedule(tool.Drawing, schedule=tool.Ifc.get().by_id(self.schedule))
schedule = props.active_schedule
schedule_creator = scheduler.Scheduler()
outfile = os.path.join(context.scene.BIMProperties.data_dir, "schedules", schedule.name + ".svg")
schedule_creator.schedule(schedule.file, outfile)
open_with_user_command(context.preferences.addons["blenderbim"].preferences.svg_command, outfile)
return {"FINISHED"}
class AddScheduleToSheet(bpy.types.Operator): class AddScheduleToSheet(bpy.types.Operator):
@@ -31,8 +31,7 @@ class SheetBuilder:
self.data_dir = None self.data_dir = None
self.scale = "NTS" self.scale = "NTS"
def create(self, name, titleblock_name): def create(self, sheet_path, titleblock_name):
sheet_path = os.path.join(self.data_dir, "sheets", f"{name}.svg")
root = ET.Element("svg") root = ET.Element("svg")
root.attrib["xmlns"] = "http://www.w3.org/2000/svg" root.attrib["xmlns"] = "http://www.w3.org/2000/svg"
root.attrib["xmlns:xlink"] = "http://www.w3.org/1999/xlink" root.attrib["xmlns:xlink"] = "http://www.w3.org/1999/xlink"
@@ -62,7 +61,7 @@ class SheetBuilder:
def add_drawing(self, drawing, sheet): def add_drawing(self, drawing, sheet):
filename = drawing.Name filename = drawing.Name
sheet_name = tool.Drawing.get_sheet_filename(sheet) sheet_name = os.path.splitext(os.path.basename(tool.Drawing.get_document_uri(sheet)))[0]
sheet_dir = os.path.join(self.data_dir, "sheets") sheet_dir = os.path.join(self.data_dir, "sheets")
drawing_dir = os.path.join(self.data_dir, "diagrams") drawing_dir = os.path.join(self.data_dir, "diagrams")
sheet_path = os.path.join(sheet_dir, sheet_name + ".svg") sheet_path = os.path.join(sheet_dir, sheet_name + ".svg")
@@ -112,7 +111,7 @@ class SheetBuilder:
sheet_tree.write(sheet_path) sheet_tree.write(sheet_path)
def remove_drawing(self, drawing, sheet): def remove_drawing(self, drawing, sheet):
sheet_name = tool.Drawing.get_sheet_filename(sheet) sheet_name = os.path.splitext(os.path.basename(tool.Drawing.get_document_uri(sheet)))[0]
sheet_dir = os.path.join(self.data_dir, "sheets") sheet_dir = os.path.join(self.data_dir, "sheets")
sheet_path = os.path.join(sheet_dir, sheet_name + ".svg") sheet_path = os.path.join(sheet_dir, sheet_name + ".svg")
@@ -168,7 +167,7 @@ class SheetBuilder:
title.attrib["height"] = str(self.convert_to_mm(title_root.attrib.get("height"))) title.attrib["height"] = str(self.convert_to_mm(title_root.attrib.get("height")))
def build(self, sheet): def build(self, sheet):
sheet_name = tool.Drawing.get_sheet_filename(sheet) sheet_name = os.path.splitext(os.path.basename(tool.Drawing.get_document_uri(sheet)))[0]
os.makedirs(os.path.join(self.data_dir, "build", sheet_name), exist_ok=True) os.makedirs(os.path.join(self.data_dir, "build", sheet_name), exist_ok=True)
sheet_path = os.path.join(self.data_dir, "sheets", f"{sheet_name}.svg") sheet_path = os.path.join(self.data_dir, "sheets", f"{sheet_name}.svg")
@@ -193,7 +192,7 @@ class SheetBuilder:
titleblock.remove(image) titleblock.remove(image)
def build_drawings(self, root, sheet): def build_drawings(self, root, sheet):
sheet_name = tool.Drawing.get_sheet_filename(sheet) sheet_name = os.path.splitext(os.path.basename(tool.Drawing.get_document_uri(sheet)))[0]
references = tool.Drawing.get_document_references(sheet) references = tool.Drawing.get_document_references(sheet)
drawing_references = {tool.Drawing.get_reference_element(r): r for r in references} drawing_references = {tool.Drawing.get_reference_element(r): r for r in references}
@@ -217,7 +217,7 @@ class BIM_PT_schedules(Panel):
row = self.layout.row(align=True) row = self.layout.row(align=True)
row.alignment = "RIGHT" row.alignment = "RIGHT"
row.operator("bim.open_schedule", icon="URL", text="").schedule = active_schedule.ifc_definition_id row.operator("bim.open_schedule", icon="URL", text="").schedule = active_schedule.ifc_definition_id
row.operator("bim.build_schedule", icon="LINENUMBERS_ON", text="") row.operator("bim.build_schedule", icon="LINENUMBERS_ON", text="").schedule = active_schedule.ifc_definition_id
row.operator("bim.remove_schedule", icon="X", text="").schedule = active_schedule.ifc_definition_id row.operator("bim.remove_schedule", icon="X", text="").schedule = active_schedule.ifc_definition_id
self.layout.template_list("BIM_UL_generic", "", self.props, "schedules", self.props, "active_schedule_index") self.layout.template_list("BIM_UL_generic", "", self.props, "schedules", self.props, "active_schedule_index")
+6 -1
View File
@@ -81,7 +81,7 @@ def add_sheet(ifc, drawing, titleblock=None):
def open_sheet(drawing, sheet=None): def open_sheet(drawing, sheet=None):
drawing.open_svg(drawing.get_sheet_filename(sheet)) drawing.open_svg(drawing.get_document_uri(sheet))
def remove_sheet(ifc, drawing, sheet=None): def remove_sheet(ifc, drawing, sheet=None):
@@ -208,6 +208,11 @@ def add_annotation(ifc, collector, drawing_tool, drawing=None, object_type=None)
drawing_tool.enable_editing(obj) drawing_tool.enable_editing(obj)
def build_schedule(drawing, schedule=None):
drawing.create_svg_schedule(schedule)
drawing.open_svg(drawing.get_document_uri(schedule))
def sync_references(ifc, collector, drawing_tool, drawing=None): def sync_references(ifc, collector, drawing_tool, drawing=None):
if not drawing_tool.has_linework(drawing): if not drawing_tool.has_linework(drawing):
return return
+2 -1
View File
@@ -156,6 +156,7 @@ class Document:
class Drawing: class Drawing:
def create_annotation_object(cls, object_type): pass def create_annotation_object(cls, object_type): pass
def create_camera(cls, name, matrix): pass def create_camera(cls, name, matrix): pass
def create_svg_schedule(cls, schedule): pass
def create_svg_sheet(cls, document, titleblock): pass def create_svg_sheet(cls, document, titleblock): pass
def delete_collection(cls, collection): pass def delete_collection(cls, collection): pass
def delete_drawing_elements(cls, elements): pass def delete_drawing_elements(cls, elements): pass
@@ -179,6 +180,7 @@ class Drawing:
def generate_sheet_identification(cls): pass def generate_sheet_identification(cls): pass
def get_annotation_context(cls, target_view): pass def get_annotation_context(cls, target_view): pass
def get_body_context(cls): pass def get_body_context(cls): pass
def get_document_uri(cls, document): pass
def get_drawing_collection(cls, drawing): pass def get_drawing_collection(cls, drawing): pass
def get_drawing_group(cls, drawing): pass def get_drawing_group(cls, drawing): pass
def get_drawing_target_view(cls, drawing): pass def get_drawing_target_view(cls, drawing): pass
@@ -186,7 +188,6 @@ class Drawing:
def get_ifc_representation_class(cls, object_type): pass def get_ifc_representation_class(cls, object_type): pass
def get_name(cls, element): pass def get_name(cls, element): pass
def get_schedule_location(cls, schedule): pass def get_schedule_location(cls, schedule): pass
def get_sheet_filename(cls, document): pass
def get_text_literal(cls, obj): pass def get_text_literal(cls, obj): pass
def get_text_product(cls, element): pass def get_text_product(cls, element): pass
def import_drawings(cls): pass def import_drawings(cls): pass
+21 -13
View File
@@ -29,6 +29,7 @@ import blenderbim.core.geometry
import blenderbim.tool as tool import blenderbim.tool as tool
import ifcopenshell.util.representation import ifcopenshell.util.representation
import blenderbim.bim.module.drawing.sheeter as sheeter import blenderbim.bim.module.drawing.sheeter as sheeter
import blenderbim.bim.module.drawing.scheduler as scheduler
import blenderbim.bim.module.drawing.annotation as annotation import blenderbim.bim.module.drawing.annotation as annotation
import blenderbim.bim.module.drawing.helper as helper import blenderbim.bim.module.drawing.helper as helper
@@ -72,11 +73,16 @@ class Drawing(blenderbim.core.tool.Drawing):
bpy.context.scene.collection.objects.link(camera) bpy.context.scene.collection.objects.link(camera)
return camera return camera
@classmethod
def create_svg_schedule(cls, schedule):
schedule_creator = scheduler.Scheduler()
schedule_creator.schedule(cls.get_schedule_location(schedule), cls.get_document_uri(schedule))
@classmethod @classmethod
def create_svg_sheet(cls, document, titleblock): def create_svg_sheet(cls, document, titleblock):
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.create(cls.get_sheet_filename(document), titleblock) sheet_builder.create(cls.get_document_uri(document), titleblock)
@classmethod @classmethod
def delete_collection(cls, collection): def delete_collection(cls, collection):
@@ -173,6 +179,18 @@ class Drawing(blenderbim.core.tool.Drawing):
def get_body_context(cls): def get_body_context(cls):
return ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW") return ifcopenshell.util.representation.get_context(tool.Ifc.get(), "Model", "Body", "MODEL_VIEW")
@classmethod
def get_document_uri(cls, document):
if hasattr(document, "Identification"):
name = document.Identification or "X"
else:
name = document.DocumentId or "X"
name += " - " + (document.Name or "Unnamed")
if document.Scope == "DOCUMENTATION":
return os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets", name + ".svg")
elif document.Scope == "SCHEDULE":
return os.path.join(bpy.context.scene.BIMProperties.data_dir, "schedules", name + ".svg")
@classmethod @classmethod
def get_drawing_collection(cls, drawing): def get_drawing_collection(cls, drawing):
obj = tool.Ifc.get_object(drawing) obj = tool.Ifc.get_object(drawing)
@@ -211,15 +229,6 @@ class Drawing(blenderbim.core.tool.Drawing):
return schedule.DocumentReferences[0].Location return schedule.DocumentReferences[0].Location
return schedule.Location return schedule.Location
@classmethod
def get_sheet_filename(cls, document):
if hasattr(document, "Identification"):
name = document.Identification or "X"
else:
name = document.DocumentId or "X"
name += " - " + (document.Name or "Unnamed")
return name
@classmethod @classmethod
def generate_drawing_matrix(cls, target_view, location_hint): def generate_drawing_matrix(cls, target_view, location_hint):
x = 0 if location_hint == 0 else bpy.context.scene.cursor.matrix[0][3] x = 0 if location_hint == 0 else bpy.context.scene.cursor.matrix[0][3]
@@ -367,10 +376,9 @@ class Drawing(blenderbim.core.tool.Drawing):
) )
@classmethod @classmethod
def open_svg(cls, filename): def open_svg(cls, uri):
cls.open_with_user_command( cls.open_with_user_command(
bpy.context.preferences.addons["blenderbim"].preferences.svg_command, bpy.context.preferences.addons["blenderbim"].preferences.svg_command, uri
os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets", filename + ".svg"),
) )
@classmethod @classmethod
+2 -2
View File
@@ -114,8 +114,8 @@ class TestAddSheet:
class TestOpenSheet: class TestOpenSheet:
def test_run(self, drawing): def test_run(self, drawing):
drawing.get_sheet_filename("sheet").should_be_called().will_return("filename") drawing.get_document_uri("sheet").should_be_called().will_return("uri")
drawing.open_svg("filename").should_be_called() drawing.open_svg("uri").should_be_called()
subject.open_sheet(drawing, sheet="sheet") subject.open_sheet(drawing, sheet="sheet")
+23 -14
View File
@@ -51,7 +51,7 @@ class TestCreateCamera(NewFile):
class TestCreateSvgSheet(NewFile): class TestCreateSvgSheet(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
document = ifc.createIfcDocumentInformation(Identification="X", Name="FOOBAR") document = ifc.createIfcDocumentInformation(Identification="X", Name="FOOBAR", Scope="DOCUMENTATION")
subject.create_svg_sheet(document, "A1") subject.create_svg_sheet(document, "A1")
assert os.path.isfile(os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets", "X - FOOBAR.svg")) assert os.path.isfile(os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets", "X - FOOBAR.svg"))
@@ -221,6 +221,26 @@ class TestGetBodyContext(NewFile):
assert subject.get_body_context() == context assert subject.get_body_context() == context
class TestGetDocumentUri(NewFile):
def test_get_sheet_uri(self):
ifc = ifcopenshell.file()
document = ifc.createIfcDocumentInformation(Identification="X", Name="FOOBAR", Scope="DOCUMENTATION")
result = subject.get_document_uri(document)
assert result == os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets", "X - FOOBAR.svg")
def test_get_schedule_uri(self):
ifc = ifcopenshell.file()
document = ifc.createIfcDocumentInformation(Identification="X", Name="FOOBAR", Scope="SCHEDULE")
result = subject.get_document_uri(document)
assert result == os.path.join(bpy.context.scene.BIMProperties.data_dir, "schedules", "X - FOOBAR.svg")
def test_run_ifc2x3(self):
ifc = ifcopenshell.file(schema="IFC2X3")
document = ifc.createIfcDocumentInformation(DocumentId="X", Name="FOOBAR", Scope="DOCUMENTATION")
result = subject.get_document_uri(document)
assert result == os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets", "X - FOOBAR.svg")
class TestGetDrawingCollection(NewFile): class TestGetDrawingCollection(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
@@ -288,21 +308,10 @@ class TestGetScheduleLocation(NewFile):
def test_run_ifc2x3(self): def test_run_ifc2x3(self):
ifc = ifcopenshell.file(schema="IFC2X3") ifc = ifcopenshell.file(schema="IFC2X3")
tool.Ifc.set(ifc)
reference = ifc.createIfcDocumentReference(Location="uri") reference = ifc.createIfcDocumentReference(Location="uri")
schedule = ifc.createIfcDocumentInformation(DocumentReferences=[reference]) schedule = ifc.createIfcDocumentInformation(DocumentReferences=[reference])
subject.get_sheet_filename(schedule) == "uri" subject.get_schedule_location(schedule) == "uri"
class TestGetSheetFilename(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
document = ifc.createIfcDocumentInformation(Identification="X", Name="FOOBAR", Scope="DOCUMENTATION")
subject.get_sheet_filename(document) == "X - FOOBAR"
def test_run_ifc2x3(self):
ifc = ifcopenshell.file(schema="IFC2X3")
document = ifc.createIfcDocumentInformation(DocumentId="X", Name="FOOBAR", Scope="DOCUMENTATION")
subject.get_sheet_filename(document) == "X - FOOBAR"
class TestGenerateDrawingMatrix(NewFile): class TestGenerateDrawingMatrix(NewFile):