You can now create drawing sheets in IFC. See #1153.

This commit is contained in:
Dion Moult
2022-01-29 13:42:46 +11:00
parent fb76f985c7
commit 27e6d702e9
11 changed files with 355 additions and 70 deletions
@@ -36,6 +36,7 @@ classes = (
operator.CopyGrid, operator.CopyGrid,
operator.CreateDrawing, operator.CreateDrawing,
operator.CreateSheets, operator.CreateSheets,
operator.DisableEditingSheets,
operator.DisableEditingText, operator.DisableEditingText,
operator.DisableEditingTextProduct, operator.DisableEditingTextProduct,
operator.EditText, operator.EditText,
@@ -44,6 +45,7 @@ classes = (
operator.EnableEditingText, operator.EnableEditingText,
operator.EnableEditingTextProduct, operator.EnableEditingTextProduct,
operator.GenerateReferences, operator.GenerateReferences,
operator.LoadSheets,
operator.OpenSheet, operator.OpenSheet,
operator.OpenView, operator.OpenView,
operator.OpenViewCamera, operator.OpenViewCamera,
@@ -67,12 +69,13 @@ classes = (
prop.BIMTextProperties, prop.BIMTextProperties,
ui.BIM_PT_camera, ui.BIM_PT_camera,
ui.BIM_PT_drawing_underlay, ui.BIM_PT_drawing_underlay,
ui.BIM_PT_annotation_utilities,
ui.BIM_PT_sheets,
ui.BIM_PT_drawings, ui.BIM_PT_drawings,
ui.BIM_PT_schedules, ui.BIM_PT_schedules,
ui.BIM_PT_sheets,
ui.BIM_PT_text, ui.BIM_PT_text,
ui.BIM_PT_annotation_utilities,
ui.BIM_UL_drawinglist, ui.BIM_UL_drawinglist,
ui.BIM_UL_sheets,
gizmos.UglyDotGizmo, gizmos.UglyDotGizmo,
gizmos.DotGizmo, gizmos.DotGizmo,
gizmos.DimensionLabelGizmo, gizmos.DimensionLabelGizmo,
@@ -23,6 +23,7 @@ import blenderbim.tool as tool
def refresh(): def refresh():
TextData.is_loaded = False TextData.is_loaded = False
SheetsData.is_loaded = False
class TextData: class TextData:
@@ -54,3 +55,17 @@ class TextData:
for rel in element.HasAssignments: for rel in element.HasAssignments:
if rel.is_a("IfcRelAssignsToProduct"): if rel.is_a("IfcRelAssignsToProduct"):
return rel.RelatingProduct.Name or "Unnamed" return rel.RelatingProduct.Name or "Unnamed"
class SheetsData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"total_sheets": cls.total_sheets()}
cls.is_loaded = True
@classmethod
def total_sheets(cls):
return len([d for d in tool.Ifc.get().by_type("IfcDocumentInformation") if d.Scope == "DOCUMENTATION"])
@@ -625,33 +625,24 @@ class AddAnnotation(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
class AddSheet(bpy.types.Operator): class AddSheet(bpy.types.Operator, Operator):
bl_idname = "bim.add_sheet" bl_idname = "bim.add_sheet"
bl_label = "Add Sheet" bl_label = "Add Sheet"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
# TODO: check undo redo
def execute(self, context): def _execute(self, context):
scene = context.scene core.add_sheet(tool.Ifc, tool.Drawing, titleblock=context.scene.DocProperties.titleblock)
new = scene.DocProperties.sheets.add()
new.name = "{} - SHEET".format(len(scene.DocProperties.sheets))
sheet_builder = sheeter.SheetBuilder()
sheet_builder.data_dir = scene.BIMProperties.data_dir
sheet_builder.create(new.name, scene.DocProperties.titleblock)
return {"FINISHED"}
class OpenSheet(bpy.types.Operator): class OpenSheet(bpy.types.Operator, Operator):
bl_idname = "bim.open_sheet" bl_idname = "bim.open_sheet"
bl_label = "Open Sheet" bl_label = "Open Sheet"
bl_options = {"REGISTER", "UNDO"}
def execute(self, context): def _execute(self, context):
props = context.scene.DocProperties self.props = context.scene.DocProperties
open_with_user_command( sheet = tool.Ifc.get().by_id(self.props.sheets[self.props.active_sheet_index].ifc_definition_id)
context.preferences.addons["blenderbim"].preferences.svg_command, core.open_sheet(tool.Drawing, sheet=sheet)
os.path.join(context.scene.BIMProperties.data_dir, "sheets", props.active_sheet.name + ".svg"),
)
return {"FINISHED"}
class AddDrawingToSheet(bpy.types.Operator): class AddDrawingToSheet(bpy.types.Operator):
@@ -1420,3 +1411,21 @@ class DisableEditingTextProduct(bpy.types.Operator, Operator):
def _execute(self, context): def _execute(self, context):
core.disable_editing_text_product(tool.Drawing, obj=context.active_object) core.disable_editing_text_product(tool.Drawing, obj=context.active_object)
class LoadSheets(bpy.types.Operator, Operator):
bl_idname = "bim.load_sheets"
bl_label = "Load Sheets"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
core.load_sheets(tool.Drawing)
class DisableEditingSheets(bpy.types.Operator, Operator):
bl_idname = "bim.disable_editing_sheets"
bl_label = "Disable Editing Text Product"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
core.disable_editing_sheets(tool.Drawing)
@@ -152,11 +152,9 @@ def getTitleblocks(self, context):
global titleblocks_enum global titleblocks_enum
if len(titleblocks_enum) < 1: if len(titleblocks_enum) < 1:
titleblocks_enum.clear() titleblocks_enum.clear()
for filename in Path(os.path.join(context.scene.BIMProperties.data_dir, "templates", "titleblocks")).glob( files = Path(os.path.join(context.scene.BIMProperties.data_dir, "templates", "titleblocks")).glob("*.svg")
"*.svg" files = sorted([str(f.stem) for f in files])
): titleblocks_enum.extend([(f, f, "") for f in files])
f = str(filename.stem)
titleblocks_enum.append((f, f, ""))
return titleblocks_enum return titleblocks_enum
@@ -218,6 +216,8 @@ class Sheet(PropertyGroup):
def get_name(self): def get_name(self):
return self.get("name") return self.get("name")
ifc_definition_id: IntProperty(name="IFC Definition ID")
identification: StringProperty(name="Identification")
name: StringProperty(name="Name", get=get_name, set=set_name) name: StringProperty(name="Name", get=get_name, set=set_name)
drawings: CollectionProperty(name="Drawings", type=Drawing) drawings: CollectionProperty(name="Drawings", type=Drawing)
active_drawing_index: IntProperty(name="Active Drawing Index") active_drawing_index: IntProperty(name="Active Drawing Index")
@@ -282,6 +282,7 @@ class DocProperties(PropertyGroup):
schedules: CollectionProperty(name="Schedules", type=Schedule) schedules: CollectionProperty(name="Schedules", type=Schedule)
active_schedule_index: IntProperty(name="Active Schedule Index") active_schedule_index: IntProperty(name="Active Schedule Index")
titleblock: EnumProperty(items=getTitleblocks, name="Titleblock", update=refreshTitleblocks) titleblock: EnumProperty(items=getTitleblocks, name="Titleblock", update=refreshTitleblocks)
is_editing_sheets: BoolProperty(name="Is Editing Sheets", default=False)
sheets: CollectionProperty(name="Sheets", type=Sheet) sheets: CollectionProperty(name="Sheets", type=Sheet)
active_sheet_index: IntProperty(name="Active Sheet Index") active_sheet_index: IntProperty(name="Active Sheet Index")
ifc_files: CollectionProperty(name="IFCs", type=StrProperty) ifc_files: CollectionProperty(name="IFCs", type=StrProperty)
@@ -31,7 +31,7 @@ class SheetBuilder:
self.scale = "NTS" self.scale = "NTS"
def create(self, name, titleblock_name): def create(self, name, titleblock_name):
sheet_path = os.path.join(self.data_dir, f"{name}.svg") 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"
@@ -20,7 +20,7 @@ import bpy
import blenderbim.bim.helper import blenderbim.bim.helper
import blenderbim.tool as tool import blenderbim.tool as tool
from bpy.types import Panel from bpy.types import Panel
from blenderbim.bim.module.drawing.data import TextData from blenderbim.bim.module.drawing.data import TextData, SheetsData
class BIM_PT_camera(Panel): class BIM_PT_camera(Panel):
@@ -149,11 +149,11 @@ class BIM_PT_drawing_underlay(Panel):
class BIM_PT_drawings(Panel): class BIM_PT_drawings(Panel):
bl_label = "SVG Drawings" bl_label = "Drawings"
bl_idname = "BIM_PT_drawings" bl_idname = "BIM_PT_drawings"
bl_space_type = "PROPERTIES" bl_space_type = "VIEW_3D"
bl_region_type = "WINDOW" bl_region_type = "UI"
bl_context = "output" bl_category = "BIM Documentation"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@@ -182,11 +182,12 @@ class BIM_PT_drawings(Panel):
class BIM_PT_schedules(Panel): class BIM_PT_schedules(Panel):
bl_label = "ODS Schedules" bl_label = "Schedules"
bl_idname = "BIM_PT_schedules" bl_idname = "BIM_PT_schedules"
bl_space_type = "PROPERTIES" bl_space_type = "VIEW_3D"
bl_region_type = "WINDOW" bl_region_type = "UI"
bl_context = "output" bl_category = "BIM Documentation"
bl_options = {"DEFAULT_CLOSED"}
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
@@ -208,31 +209,39 @@ class BIM_PT_schedules(Panel):
class BIM_PT_sheets(Panel): class BIM_PT_sheets(Panel):
bl_label = "SVG Sheets" bl_label = "Sheets"
bl_idname = "BIM_PT_sheets" bl_idname = "BIM_PT_sheets"
bl_space_type = "PROPERTIES" bl_space_type = "VIEW_3D"
bl_region_type = "WINDOW" bl_region_type = "UI"
bl_context = "output" bl_category = "BIM Documentation"
def draw(self, context): def draw(self, context):
layout = self.layout if not SheetsData.is_loaded:
props = context.scene.DocProperties SheetsData.load()
row = layout.row(align=True) self.props = context.scene.DocProperties
row.prop(props, "titleblock", text="")
row.operator("bim.add_sheet")
if props.sheets: if not self.props.is_editing_sheets:
row = self.layout.row(align=True)
row.label(text=f"{SheetsData.data['total_sheets']} Sheets Found", icon="FILE")
row.operator("bim.load_sheets", text="", icon="IMPORT")
return
row = self.layout.row(align=True)
row.prop(self.props, "titleblock", text="")
row.operator("bim.add_sheet", text="", icon="ADD")
row.operator("bim.disable_editing_sheets", text="", icon="CANCEL")
if self.props.sheets:
row = self.layout.row(align=True)
row.alignment = "RIGHT"
row.operator("bim.open_sheet", icon="URL", text="") row.operator("bim.open_sheet", icon="URL", text="")
row.operator("bim.remove_sheet", icon="X", text="").index = props.active_sheet_index row.operator("bim.add_drawing_to_sheet", icon="IMAGE_PLANE", text="")
row.operator("bim.add_schedule_to_sheet", icon="PRESET_NEW", text="")
row.operator("bim.create_sheets", icon="FILE_REFRESH", text="")
row.operator("bim.remove_sheet", icon="X", text="").index = self.props.active_sheet_index
layout.template_list("BIM_UL_generic", "", props, "sheets", props, "active_sheet_index") self.layout.template_list("BIM_UL_sheets", "", self.props, "sheets", self.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")
class BIM_PT_text(Panel): class BIM_PT_text(Panel):
@@ -289,15 +298,17 @@ class BIM_PT_text(Panel):
class BIM_PT_annotation_utilities(Panel): class BIM_PT_annotation_utilities(Panel):
bl_idname = "BIM_PT_annotation_utilities" bl_idname = "BIM_PT_annotation_utilities"
bl_label = "Drawing" bl_label = "Annotation"
bl_options = {"DEFAULT_CLOSED"} bl_options = {"DEFAULT_CLOSED"}
bl_space_type = "VIEW_3D" bl_space_type = "VIEW_3D"
bl_region_type = "UI" bl_region_type = "UI"
bl_category = "BlenderBIM" bl_category = "BIM Documentation"
def draw(self, context): def draw(self, context):
layout = self.layout layout = self.layout
self.props = context.scene.DocProperties
row = layout.row(align=True) row = layout.row(align=True)
row.operator("bim.clean_wireframes") row.operator("bim.clean_wireframes")
row = layout.row(align=True) row = layout.row(align=True)
@@ -345,21 +356,8 @@ class BIM_PT_annotation_utilities(Panel):
op.object_type = "MISC" op.object_type = "MISC"
op.data_type = "mesh" op.data_type = "mesh"
props = context.scene.DocProperties layout.prop(self.props, "should_draw_decorations")
layout.prop(self.props, "decorations_colour")
row = layout.row(align=True)
row.operator("bim.add_drawing")
row.operator("bim.refresh_drawing_list", icon="FILE_REFRESH", text="")
if props.drawings:
if props.active_drawing_index < len(props.drawings):
op = row.operator("bim.open_view", icon="URL", text="")
op.view = props.active_drawing.name
row.operator("bim.remove_drawing", icon="X", text="").index = props.active_drawing_index
layout.template_list("BIM_UL_drawinglist", "", props, "drawings", props, "active_drawing_index")
layout.prop(props, "should_draw_decorations")
layout.prop(props, "decorations_colour")
class BIM_UL_drawinglist(bpy.types.UIList): class BIM_UL_drawinglist(bpy.types.UIList):
@@ -371,3 +369,13 @@ class BIM_UL_drawinglist(bpy.types.UIList):
op.view_name = item.name op.view_name = item.name
else: else:
layout.label(text="", translate=False) layout.label(text="", translate=False)
class BIM_UL_sheets(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
if item:
row = layout.row(align=True)
row.label(text=item.identification or "X")
row.label(text=item.name or "Unnamed")
else:
layout.label(text="", translate=False)
+26
View File
@@ -56,3 +56,29 @@ def edit_text_product(ifc, drawing, obj=None, product=None):
ifc.run("drawing.assign_product", relating_product=product, related_object=element) ifc.run("drawing.assign_product", relating_product=product, related_object=element)
drawing.update_text_value(obj) drawing.update_text_value(obj)
drawing.disable_editing_text_product(obj) drawing.disable_editing_text_product(obj)
def load_sheets(drawing):
drawing.import_sheets()
drawing.enable_editing_sheets()
def disable_editing_sheets(drawing):
drawing.disable_editing_sheets()
def add_sheet(ifc, drawing, titleblock=None):
sheet = ifc.run("document.add_information")
identification = drawing.generate_sheet_identification()
identification = drawing.ensure_unique_identification(identification)
attributes = {"Identification": identification, "Name": "UNTITLED", "Scope": "DOCUMENTATION"}
if ifc.get_schema() == "IFC2X3":
attributes["DocumentId"] = attributes["Identification"]
del attributes["Identification"]
ifc.run("document.edit_information", information=sheet, attributes=attributes)
drawing.create_svg_sheet(sheet, titleblock)
drawing.import_sheets()
def open_sheet(drawing, sheet=None):
drawing.open_svg(drawing.get_sheet_filename(sheet))
+8
View File
@@ -135,15 +135,23 @@ class Debug:
@interface @interface
class Drawing: class Drawing:
def create_svg_sheet(cls, document, titleblock): pass
def disable_editing_sheets(cls): pass
def disable_editing_text(cls, obj): pass def disable_editing_text(cls, obj): pass
def disable_editing_text_product(cls, obj): pass def disable_editing_text_product(cls, obj): pass
def enable_editing_sheets(cls): pass
def enable_editing_text(cls, obj): pass def enable_editing_text(cls, obj): pass
def enable_editing_text_product(cls, obj): pass def enable_editing_text_product(cls, obj): pass
def ensure_unique_identification(cls, identification): pass
def export_text_literal_attributes(cls, obj): pass def export_text_literal_attributes(cls, obj): pass
def generate_sheet_identification(cls): 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_sheets(cls): pass
def import_text_attributes(cls, obj): pass def import_text_attributes(cls, obj): pass
def import_text_product(cls, obj): pass def import_text_product(cls, obj): pass
def open_svg(cls, filepath): pass
def update_text_value(cls, obj): pass def update_text_value(cls, obj): pass
+72
View File
@@ -16,14 +16,27 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>. # along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import os
import re import re
import bpy import bpy
import webbrowser
import blenderbim.core.tool import blenderbim.core.tool
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
class Drawing(blenderbim.core.tool.Drawing): class Drawing(blenderbim.core.tool.Drawing):
@classmethod
def create_svg_sheet(cls, document, titleblock):
sheet_builder = sheeter.SheetBuilder()
sheet_builder.data_dir = bpy.context.scene.BIMProperties.data_dir
sheet_builder.create(cls.get_sheet_filename(document), titleblock)
@classmethod
def disable_editing_sheets(cls):
bpy.context.scene.DocProperties.is_editing_sheets = False
@classmethod @classmethod
def disable_editing_text(cls, obj): def disable_editing_text(cls, obj):
obj.BIMTextProperties.is_editing = False obj.BIMTextProperties.is_editing = False
@@ -32,6 +45,10 @@ class Drawing(blenderbim.core.tool.Drawing):
def disable_editing_text_product(cls, obj): def disable_editing_text_product(cls, obj):
obj.BIMTextProperties.is_editing_product = False obj.BIMTextProperties.is_editing_product = False
@classmethod
def enable_editing_sheets(cls):
bpy.context.scene.DocProperties.is_editing_sheets = True
@classmethod @classmethod
def enable_editing_text(cls, obj): def enable_editing_text(cls, obj):
obj.BIMTextProperties.is_editing = True obj.BIMTextProperties.is_editing = True
@@ -40,10 +57,36 @@ class Drawing(blenderbim.core.tool.Drawing):
def enable_editing_text_product(cls, obj): def enable_editing_text_product(cls, obj):
obj.BIMTextProperties.is_editing_product = True obj.BIMTextProperties.is_editing_product = True
@classmethod
def ensure_unique_identification(cls, identification):
if tool.Ifc.get_schema() == "IFC2X3":
ids = [d.DocumentId for d in tool.Ifc.get().by_type("IfcDocumentInformation") if d.Scope == "DOCUMENTATION"]
else:
ids = [
d.Identification for d in tool.Ifc.get().by_type("IfcDocumentInformation") if d.Scope == "DOCUMENTATION"
]
while identification in ids:
identification += "-X"
return identification
@classmethod @classmethod
def export_text_literal_attributes(cls, obj): def export_text_literal_attributes(cls, obj):
return blenderbim.bim.helper.export_attributes(obj.BIMTextProperties.attributes) return blenderbim.bim.helper.export_attributes(obj.BIMTextProperties.attributes)
@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
def generate_sheet_identification(cls):
number = len([d for d in tool.Ifc.get().by_type("IfcDocumentInformation") if d.Scope == "DOCUMENTATION"])
return "A" + str(number).zfill(2)
@classmethod @classmethod
def get_text_literal(cls, obj): def get_text_literal(cls, obj):
element = tool.Ifc.get_entity(obj) element = tool.Ifc.get_entity(obj)
@@ -62,6 +105,19 @@ class Drawing(blenderbim.core.tool.Drawing):
if rel.is_a("IfcRelAssignsToProduct"): if rel.is_a("IfcRelAssignsToProduct"):
return rel.RelatingProduct return rel.RelatingProduct
@classmethod
def import_sheets(cls):
bpy.context.scene.DocProperties.sheets.clear()
sheets = [d for d in tool.Ifc.get().by_type("IfcDocumentInformation") if d.Scope == "DOCUMENTATION"]
for sheet in sheets:
new = bpy.context.scene.DocProperties.sheets.add()
new.ifc_definition_id = sheet.id()
if tool.Ifc.get_schema() == "IFC2X3":
new.identification = sheet.DocumentId
else:
new.identification = sheet.Identification
new.name = sheet.Name
@classmethod @classmethod
def import_text_attributes(cls, obj): def import_text_attributes(cls, obj):
props = obj.BIMTextProperties props = obj.BIMTextProperties
@@ -78,6 +134,22 @@ class Drawing(blenderbim.core.tool.Drawing):
else: else:
obj.BIMTextProperties.relating_product = None obj.BIMTextProperties.relating_product = None
@classmethod
def open_with_user_command(cls, user_command, path):
if user_command:
commands = eval(user_command)
for command in commands:
subprocess.run(command)
else:
webbrowser.open("file://" + path)
@classmethod
def open_svg(cls, filename):
cls.open_with_user_command(
bpy.context.preferences.addons["blenderbim"].preferences.svg_command,
os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets", filename + ".svg"),
)
@classmethod @classmethod
def update_text_value(cls, obj): def update_text_value(cls, obj):
element = cls.get_text_literal(obj) element = cls.get_text_literal(obj)
+50
View File
@@ -67,3 +67,53 @@ class TestEditTextProduct:
drawing.update_text_value("obj").should_be_called() drawing.update_text_value("obj").should_be_called()
drawing.disable_editing_text_product("obj").should_be_called() drawing.disable_editing_text_product("obj").should_be_called()
subject.edit_text_product(ifc, drawing, obj="obj", product="product") subject.edit_text_product(ifc, drawing, obj="obj", product="product")
class TestLoadSheets:
def test_run(self, drawing):
drawing.import_sheets().should_be_called()
drawing.enable_editing_sheets().should_be_called()
subject.load_sheets(drawing)
class TestDisableEditingSheets:
def test_run(self, drawing):
drawing.disable_editing_sheets().should_be_called()
subject.disable_editing_sheets(drawing)
class TestAddSheet:
def test_run(self, ifc, drawing):
ifc.run("document.add_information").should_be_called().will_return("sheet")
drawing.generate_sheet_identification().should_be_called().will_return("identification")
drawing.ensure_unique_identification("identification").should_be_called().will_return("u_identification")
ifc.get_schema().should_be_called().will_return("IFC4")
ifc.run(
"document.edit_information",
information="sheet",
attributes={"Identification": "u_identification", "Name": "UNTITLED", "Scope": "DOCUMENTATION"},
).should_be_called()
drawing.create_svg_sheet("sheet", "titleblock").should_be_called()
drawing.import_sheets().should_be_called()
subject.add_sheet(ifc, drawing, titleblock="titleblock")
def test_using_a_document_id_in_ifc2x3(self, ifc, drawing):
ifc.run("document.add_information").should_be_called().will_return("sheet")
drawing.generate_sheet_identification().should_be_called().will_return("identification")
drawing.ensure_unique_identification("identification").should_be_called().will_return("u_identification")
ifc.get_schema().should_be_called().will_return("IFC2X3")
ifc.run(
"document.edit_information",
information="sheet",
attributes={"DocumentId": "u_identification", "Name": "UNTITLED", "Scope": "DOCUMENTATION"},
).should_be_called()
drawing.create_svg_sheet("sheet", "titleblock").should_be_called()
drawing.import_sheets().should_be_called()
subject.add_sheet(ifc, drawing, titleblock="titleblock")
class TestOpenSheet:
def test_run(self, drawing):
drawing.get_sheet_filename("sheet").should_be_called().will_return("filename")
drawing.open_svg("filename").should_be_called()
subject.open_sheet(drawing, sheet="sheet")
+93
View File
@@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>. # along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import os
import bpy import bpy
import ifcopenshell import ifcopenshell
import blenderbim.core.tool import blenderbim.core.tool
@@ -29,6 +30,21 @@ class TestImplementsTool(NewFile):
assert isinstance(subject(), blenderbim.core.tool.Drawing) assert isinstance(subject(), blenderbim.core.tool.Drawing)
class TestCreateSvgSheet(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
document = ifc.createIfcDocumentInformation(Identification="X", Name="FOOBAR")
subject.create_svg_sheet(document, "A1")
assert os.path.isfile(os.path.join(bpy.context.scene.BIMProperties.data_dir, "sheets", "X - FOOBAR.svg"))
class TestDisableEditingSheets(NewFile):
def test_run(self):
bpy.context.scene.DocProperties.is_editing_sheets = True
subject.disable_editing_sheets()
assert bpy.context.scene.DocProperties.is_editing_sheets == False
class TestDisableEditingText(NewFile): class TestDisableEditingText(NewFile):
def test_run(self): def test_run(self):
obj = bpy.data.objects.new("Object", None) obj = bpy.data.objects.new("Object", None)
@@ -45,6 +61,13 @@ class TestDisableEditingTextProduct(NewFile):
assert obj.BIMTextProperties.is_editing_product == False assert obj.BIMTextProperties.is_editing_product == False
class TestEnableEditingSheets(NewFile):
def test_run(self):
bpy.context.scene.DocProperties.is_editing_sheets = False
subject.enable_editing_sheets()
assert bpy.context.scene.DocProperties.is_editing_sheets == True
class TestEnableEditingText(NewFile): class TestEnableEditingText(NewFile):
def test_run(self): def test_run(self):
obj = bpy.data.objects.new("Object", None) obj = bpy.data.objects.new("Object", None)
@@ -59,6 +82,26 @@ class TestEnableEditingTextProduct(NewFile):
assert obj.BIMTextProperties.is_editing_product == True assert obj.BIMTextProperties.is_editing_product == True
class TestEnsureUniqueIdentification(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
assert subject.ensure_unique_identification("FOOBAR") == "FOOBAR"
ifc.createIfcDocumentInformation(Identification="FOOBAR", Scope="DOCUMENTATION")
assert subject.ensure_unique_identification("FOOBAR") == "FOOBAR-X"
ifc.createIfcDocumentInformation(Identification="FOOBAR-X", Scope="DOCUMENTATION")
assert subject.ensure_unique_identification("FOOBAR") == "FOOBAR-X-X"
def test_unique_document_id_ifc2x3(self):
ifc = ifcopenshell.file(schema="IFC2X3")
tool.Ifc.set(ifc)
assert subject.ensure_unique_identification("FOOBAR") == "FOOBAR"
ifc.createIfcDocumentInformation(DocumentId="FOOBAR", Scope="DOCUMENTATION")
assert subject.ensure_unique_identification("FOOBAR") == "FOOBAR-X"
ifc.createIfcDocumentInformation(DocumentId="FOOBAR-X", Scope="DOCUMENTATION")
assert subject.ensure_unique_identification("FOOBAR") == "FOOBAR-X-X"
class TestExportTextLiteralAttributes(NewFile): class TestExportTextLiteralAttributes(NewFile):
def test_run(self): def test_run(self):
TestImportTextAttributes().test_run() TestImportTextAttributes().test_run()
@@ -69,6 +112,27 @@ class TestExportTextLiteralAttributes(NewFile):
} }
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 TestGenerateSheetIdentification(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
subject.generate_sheet_identification() == "A01"
document = ifc.createIfcDocumentInformation()
subject.generate_sheet_identification() == "A02"
class TestGetTextLiteral(NewFile): class TestGetTextLiteral(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
@@ -94,6 +158,30 @@ class TestGetTextProduct(NewFile):
assert subject.get_text_product(label) == wall assert subject.get_text_product(label) == wall
class TestImportSheets(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
tool.Ifc.set(ifc)
ifc.createIfcDocumentInformation(Identification="Y", Name="FOOBAZ")
document = ifc.createIfcDocumentInformation(Identification="X", Name="FOOBAR", Scope="DOCUMENTATION")
subject.import_sheets()
props = bpy.context.scene.DocProperties
assert props.sheets[0].ifc_definition_id == document.id()
assert props.sheets[0].identification == "X"
assert props.sheets[0].name == "FOOBAR"
def test_run_ifc2x3(self):
ifc = ifcopenshell.file(schema="IFC2X3")
tool.Ifc.set(ifc)
ifc.createIfcDocumentInformation(DocumentId="Y", Name="FOOBAZ")
document = ifc.createIfcDocumentInformation(DocumentId="X", Name="FOOBAR", Scope="DOCUMENTATION")
subject.import_sheets()
props = bpy.context.scene.DocProperties
assert props.sheets[0].ifc_definition_id == document.id()
assert props.sheets[0].identification == "X"
assert props.sheets[0].name == "FOOBAR"
class TestImportTextAttributes(NewFile): class TestImportTextAttributes(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
@@ -137,6 +225,11 @@ class TestImportTextProduct(NewFile):
assert label_obj.BIMTextProperties.relating_product is None assert label_obj.BIMTextProperties.relating_product is None
class TestOpenSvg(NewFile):
def test_nothing(self):
pass
class TestUpdateTextValue(NewFile): class TestUpdateTextValue(NewFile):
def test_updating_arbitrary_strings(self): def test_updating_arbitrary_strings(self):
TestGetTextLiteral().test_run() TestGetTextLiteral().test_run()