mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 23:36:20 +00:00
#1153 Reimplement ability to build SVG tables from referenced ODS documents
This commit is contained in:
@@ -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")
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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):
|
||||||
|
|||||||
Reference in New Issue
Block a user