#1153 You can now add / remove / open schedules, implemented as IFC documents

This commit is contained in:
Dion Moult
2022-04-28 14:16:39 +10:00
parent 9ea6499b5a
commit 3f28ae18c0
12 changed files with 305 additions and 61 deletions
@@ -39,6 +39,7 @@ classes = (
operator.CreateDrawing, operator.CreateDrawing,
operator.CreateSheets, operator.CreateSheets,
operator.DisableEditingDrawings, operator.DisableEditingDrawings,
operator.DisableEditingSchedules,
operator.DisableEditingSheets, operator.DisableEditingSheets,
operator.DisableEditingText, operator.DisableEditingText,
operator.DisableEditingTextProduct, operator.DisableEditingTextProduct,
@@ -49,7 +50,9 @@ classes = (
operator.EnableEditingTextProduct, operator.EnableEditingTextProduct,
operator.ExpandSheet, operator.ExpandSheet,
operator.LoadDrawings, operator.LoadDrawings,
operator.LoadSchedules,
operator.LoadSheets, operator.LoadSheets,
operator.OpenSchedule,
operator.OpenSheet, operator.OpenSheet,
operator.OpenView, operator.OpenView,
operator.RemoveDrawing, operator.RemoveDrawing,
@@ -61,7 +64,6 @@ classes = (
operator.ResizeText, operator.ResizeText,
operator.SaveDrawingStyle, operator.SaveDrawingStyle,
operator.SelectDocIfcFile, operator.SelectDocIfcFile,
operator.SelectScheduleFile,
prop.Variable, prop.Variable,
prop.Drawing, prop.Drawing,
prop.Schedule, prop.Schedule,
@@ -24,6 +24,7 @@ import blenderbim.tool as tool
def refresh(): def refresh():
TextData.is_loaded = False TextData.is_loaded = False
SheetsData.is_loaded = False SheetsData.is_loaded = False
SchedulesData.is_loaded = False
DrawingsData.is_loaded = False DrawingsData.is_loaded = False
@@ -94,3 +95,17 @@ class DrawingsData:
) )
return results return results
return [(h.upper(), h, "") for h in ["North", "South", "East", "West"]] return [(h.upper(), h, "") for h in ["North", "South", "East", "West"]]
class SchedulesData:
data = {}
is_loaded = False
@classmethod
def load(cls):
cls.data = {"total_schedules": cls.total_schedules()}
cls.is_loaded = True
@classmethod
def total_schedules(cls):
return len([d for d in tool.Ifc.get().by_type("IfcDocumentInformation") if d.Scope == "SCHEDULE"])
@@ -913,55 +913,53 @@ class RemoveSheet(bpy.types.Operator, Operator):
core.remove_sheet(tool.Ifc, tool.Drawing, sheet=tool.Ifc.get().by_id(self.sheet)) core.remove_sheet(tool.Ifc, tool.Drawing, sheet=tool.Ifc.get().by_id(self.sheet))
class AddSchedule(bpy.types.Operator): class AddSchedule(bpy.types.Operator, Operator):
bl_idname = "bim.add_schedule" bl_idname = "bim.add_schedule"
bl_label = "Add Schedule" bl_label = "Add Schedule"
bl_options = {"REGISTER", "UNDO"} bl_options = {"REGISTER", "UNDO"}
def execute(self, context):
new = context.scene.DocProperties.schedules.add()
new.name = "SCHEDULE {}".format(len(context.scene.DocProperties.schedules))
return {"FINISHED"}
class RemoveSchedule(bpy.types.Operator):
bl_idname = "bim.remove_schedule"
bl_label = "Remove Schedule"
bl_options = {"REGISTER", "UNDO"}
index: bpy.props.IntProperty()
def execute(self, context):
props = context.scene.DocProperties
props.schedules.remove(self.index)
return {"FINISHED"}
class SelectScheduleFile(bpy.types.Operator):
bl_idname = "bim.select_schedule_file"
bl_label = "Select Documentation IFC File"
bl_options = {"REGISTER", "UNDO"}
filepath: bpy.props.StringProperty(subtype="FILE_PATH") filepath: bpy.props.StringProperty(subtype="FILE_PATH")
filter_glob: bpy.props.StringProperty(default="*.ods", options={"HIDDEN"}) filter_glob: bpy.props.StringProperty(default="*.ods;*.xls;*.xlsx", options={"HIDDEN"})
index: bpy.props.IntProperty() use_relative_path: bpy.props.BoolProperty(name="Use Relative Path", default=False)
def execute(self, context): def _execute(self, context):
props = context.scene.DocProperties filepath = self.filepath
props.active_schedule.file = self.filepath if self.use_relative_path:
return {"FINISHED"} filepath = os.path.relpath(filepath, bpy.path.abspath("//"))
core.add_schedule(
tool.Ifc,
tool.Drawing,
uri=filepath,
)
def invoke(self, context, event): def invoke(self, context, event):
context.window_manager.fileselect_add(self) context.window_manager.fileselect_add(self)
return {"RUNNING_MODAL"} return {"RUNNING_MODAL"}
class RemoveSchedule(bpy.types.Operator, Operator):
bl_idname = "bim.remove_schedule"
bl_label = "Remove Schedule"
bl_options = {"REGISTER", "UNDO"}
schedule: bpy.props.IntProperty()
def _execute(self, context):
core.remove_schedule(tool.Ifc, tool.Drawing, schedule=tool.Ifc.get().by_id(self.schedule))
class OpenSchedule(bpy.types.Operator, Operator):
bl_idname = "bim.open_schedule"
bl_label = "Open Schedule"
bl_options = {"REGISTER", "UNDO"}
schedule: bpy.props.IntProperty()
def _execute(self, context):
core.open_schedule(tool.Drawing, schedule=tool.Ifc.get().by_id(self.schedule))
class BuildSchedule(bpy.types.Operator): class BuildSchedule(bpy.types.Operator):
bl_idname = "bim.build_schedule" bl_idname = "bim.build_schedule"
bl_label = "Build Schedule" bl_label = "Build Schedule"
@classmethod
def poll(cls, context):
return context.scene.DocProperties.active_schedule.file
def execute(self, context): def execute(self, context):
props = context.scene.DocProperties props = context.scene.DocProperties
schedule = props.active_schedule schedule = props.active_schedule
@@ -1269,6 +1267,24 @@ class DisableEditingSheets(bpy.types.Operator, Operator):
core.disable_editing_sheets(tool.Drawing) core.disable_editing_sheets(tool.Drawing)
class LoadSchedules(bpy.types.Operator, Operator):
bl_idname = "bim.load_schedules"
bl_label = "Load Schedules"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
core.load_schedules(tool.Drawing)
class DisableEditingSchedules(bpy.types.Operator, Operator):
bl_idname = "bim.disable_editing_schedules"
bl_label = "Disable Editing Text Product"
bl_options = {"REGISTER", "UNDO"}
def _execute(self, context):
core.disable_editing_schedules(tool.Drawing)
class LoadDrawings(bpy.types.Operator, Operator): class LoadDrawings(bpy.types.Operator, Operator):
bl_idname = "bim.load_drawings" bl_idname = "bim.load_drawings"
bl_label = "Load Drawings" bl_label = "Load Drawings"
@@ -153,6 +153,11 @@ def update_drawing_name(self, context):
core.update_drawing_name(tool.Ifc, tool.Drawing, drawing=drawing, name=self.name) core.update_drawing_name(tool.Ifc, tool.Drawing, drawing=drawing, name=self.name)
def update_schedule_name(self, context):
schedule = tool.Ifc.get().by_id(self.ifc_definition_id)
core.update_schedule_name(tool.Ifc, tool.Drawing, schedule=schedule, name=self.name)
def update_has_underlay(self, context): def update_has_underlay(self, context):
update_layer(self, context, "HasUnderlay", self.has_underlay) update_layer(self, context, "HasUnderlay", self.has_underlay)
@@ -231,8 +236,9 @@ class Drawing(PropertyGroup):
class Schedule(PropertyGroup): class Schedule(PropertyGroup):
name: StringProperty(name="Name") ifc_definition_id: IntProperty(name="IFC Definition ID")
file: StringProperty(name="File") name: StringProperty(name="Name", update=update_schedule_name)
identification: StringProperty(name="Identification")
class Sheet(PropertyGroup): class Sheet(PropertyGroup):
@@ -305,6 +311,7 @@ class DocProperties(PropertyGroup):
should_use_annotation_cache: BoolProperty(name="Use Annotation Cache", default=False) should_use_annotation_cache: BoolProperty(name="Use Annotation Cache", default=False)
should_extract: BoolProperty(name="Should Extract", default=True) should_extract: BoolProperty(name="Should Extract", default=True)
is_editing_drawings: BoolProperty(name="Is Editing Drawings", default=False) is_editing_drawings: BoolProperty(name="Is Editing Drawings", default=False)
is_editing_schedules: BoolProperty(name="Is Editing Schedules", default=False)
target_view: EnumProperty( target_view: EnumProperty(
items=[ items=[
("PLAN_VIEW", "Plan", ""), ("PLAN_VIEW", "Plan", ""),
@@ -335,10 +342,6 @@ class DocProperties(PropertyGroup):
name="Decorations Colour", subtype="COLOR", default=(1, 1, 1, 1), min=0.0, max=1.0, size=4 name="Decorations Colour", subtype="COLOR", default=(1, 1, 1, 1), min=0.0, max=1.0, size=4
) )
@property
def active_schedule(self):
return self.schedules[self.active_schedule_index]
class BIMCameraProperties(PropertyGroup): class BIMCameraProperties(PropertyGroup):
has_underlay: BoolProperty(name="Underlay", default=False, update=update_has_underlay) has_underlay: BoolProperty(name="Underlay", default=False, update=update_has_underlay)
@@ -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, SheetsData, DrawingsData from blenderbim.bim.module.drawing.data import TextData, SheetsData, SchedulesData, DrawingsData
class BIM_PT_camera(Panel): class BIM_PT_camera(Panel):
@@ -196,22 +196,31 @@ class BIM_PT_schedules(Panel):
bl_category = "BIM Documentation" bl_category = "BIM Documentation"
def draw(self, context): def draw(self, context):
layout = self.layout if not SchedulesData.is_loaded:
layout.use_property_split = True SchedulesData.load()
props = context.scene.DocProperties
row = layout.row(align=True) self.props = context.scene.DocProperties
row.operator("bim.add_schedule")
if props.schedules: if not self.props.is_editing_schedules:
row.operator("bim.build_schedule", icon="LINENUMBERS_ON", text="") row = self.layout.row(align=True)
row.operator("bim.remove_schedule", icon="X", text="").index = props.active_schedule_index row.label(text=f"{SchedulesData.data['total_schedules']} Schedules Found", icon="LONGDISPLAY")
row.operator("bim.load_schedules", text="", icon="IMPORT")
return
layout.template_list("BIM_UL_generic", "", props, "schedules", props, "active_schedule_index") row = self.layout.row(align=True)
row.operator("bim.add_schedule", icon="ADD")
row.operator("bim.disable_editing_schedules", text="", icon="CANCEL")
row = layout.row() if self.props.schedules:
row.prop(props.active_schedule, "file") if self.props.active_schedule_index < len(self.props.schedules):
row.operator("bim.select_schedule_file", icon="FILE_FOLDER", text="") active_schedule = self.props.schedules[self.props.active_schedule_index]
row = self.layout.row(align=True)
row.alignment = "RIGHT"
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.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")
class BIM_PT_sheets(Panel): class BIM_PT_sheets(Panel):
+5 -2
View File
@@ -106,8 +106,9 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
name="SVG to DXF Command", name="SVG to DXF Command",
description="E.g. [['inkscape', svg, '-o', eps], ['pstoedit', '-dt', '-f', 'dxf:-polyaslines -mm', eps, dxf, '-psarg', '-dNOSAFER']]", description="E.g. [['inkscape', svg, '-o', eps], ['pstoedit', '-dt', '-f', 'dxf:-polyaslines -mm', eps, dxf, '-psarg', '-dNOSAFER']]",
) )
svg_command: StringProperty(name="SVG Command", description="E.g. [['firefox-bin', path]]") svg_command: StringProperty(name="SVG Command", description="E.g. [['firefox', path]]")
pdf_command: StringProperty(name="PDF Command", description="E.g. [['firefox-bin', path]]") pdf_command: StringProperty(name="PDF Command", description="E.g. [['firefox', path]]")
spreadsheet_command: StringProperty(name="Spreadsheet Command", description="E.g. [['libreoffice', path]]")
openlca_port: IntProperty(name="OpenLCA IPC Port", default=8080) openlca_port: IntProperty(name="OpenLCA IPC Port", default=8080)
should_hide_empty_props: BoolProperty(name="Should Hide Empty Properties", default=True) should_hide_empty_props: BoolProperty(name="Should Hide Empty Properties", default=True)
should_play_chaching_sound: BoolProperty( should_play_chaching_sound: BoolProperty(
@@ -141,6 +142,8 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
row = layout.row() row = layout.row()
row.prop(self, "pdf_command") row.prop(self, "pdf_command")
row = layout.row() row = layout.row()
row.prop(self, "spreadsheet_command")
row = layout.row()
row.prop(self, "openlca_port") row.prop(self, "openlca_port")
row = layout.row() row = layout.row()
row.prop(self, "should_hide_empty_props") row.prop(self, "should_hide_empty_props")
+36
View File
@@ -89,6 +89,42 @@ def remove_sheet(ifc, drawing, sheet=None):
drawing.import_sheets() drawing.import_sheets()
def load_schedules(drawing):
drawing.import_schedules()
drawing.enable_editing_schedules()
def disable_editing_schedules(drawing):
drawing.disable_editing_schedules()
def add_schedule(ifc, drawing, uri=None):
schedule = ifc.run("document.add_information")
reference = ifc.run("document.add_reference", information=schedule)
if ifc.get_schema() == "IFC2X3":
attributes = {"DocumentId": "X", "Name": "UNTITLED", "Scope": "SCHEDULE"}
ifc.run("document.edit_information", information=schedule, attributes=attributes)
ifc.run("document.edit_reference", reference=reference, attributes={"Location": uri})
else:
attributes = {"Identification": "X", "Name": "UNTITLED", "Scope": "SCHEDULE", "Location": uri}
ifc.run("document.edit_information", information=schedule, attributes=attributes)
drawing.import_schedules()
def remove_schedule(ifc, drawing, schedule=None):
ifc.run("document.remove_information", information=schedule)
drawing.import_schedules()
def open_schedule(drawing, schedule=None):
drawing.open_spreadsheet(drawing.get_schedule_location(schedule))
def update_schedule_name(ifc, drawing, schedule=None, name=None):
if drawing.get_name(schedule) != name:
ifc.run("document.edit_information", information=schedule, attributes={"Name": name})
def load_drawings(drawing): def load_drawings(drawing):
drawing.import_drawings() drawing.import_drawings()
drawing.enable_editing_drawings() drawing.enable_editing_drawings()
+3
View File
@@ -161,11 +161,13 @@ class Drawing:
def delete_drawing_elements(cls, elements): pass def delete_drawing_elements(cls, elements): pass
def delete_object(cls, obj): pass def delete_object(cls, obj): pass
def disable_editing_drawings(cls): pass def disable_editing_drawings(cls): pass
def disable_editing_schedules(cls): pass
def disable_editing_sheets(cls): 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(cls, obj): pass def enable_editing(cls, obj): pass
def enable_editing_drawings(cls): pass def enable_editing_drawings(cls): pass
def enable_editing_schedules(cls): pass
def enable_editing_sheets(cls): 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
@@ -187,6 +189,7 @@ class Drawing:
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
def import_schedules(cls): pass
def import_sheets(cls): 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
+33
View File
@@ -98,6 +98,10 @@ class Drawing(blenderbim.core.tool.Drawing):
def disable_editing_drawings(cls): def disable_editing_drawings(cls):
bpy.context.scene.DocProperties.is_editing_drawings = False bpy.context.scene.DocProperties.is_editing_drawings = False
@classmethod
def disable_editing_schedules(cls):
bpy.context.scene.DocProperties.is_editing_schedules = False
@classmethod @classmethod
def disable_editing_sheets(cls): def disable_editing_sheets(cls):
bpy.context.scene.DocProperties.is_editing_sheets = False bpy.context.scene.DocProperties.is_editing_sheets = False
@@ -122,6 +126,10 @@ class Drawing(blenderbim.core.tool.Drawing):
def enable_editing_drawings(cls): def enable_editing_drawings(cls):
bpy.context.scene.DocProperties.is_editing_drawings = True bpy.context.scene.DocProperties.is_editing_drawings = True
@classmethod
def enable_editing_schedules(cls):
bpy.context.scene.DocProperties.is_editing_schedules = True
@classmethod @classmethod
def enable_editing_sheets(cls): def enable_editing_sheets(cls):
bpy.context.scene.DocProperties.is_editing_sheets = True bpy.context.scene.DocProperties.is_editing_sheets = True
@@ -197,6 +205,12 @@ class Drawing(blenderbim.core.tool.Drawing):
def get_name(cls, element): def get_name(cls, element):
return element.Name return element.Name
@classmethod
def get_schedule_location(cls, schedule):
if tool.Ifc.get_schema() == "IFC2X3":
return schedule.DocumentReferences[0].Location
return schedule.Location
@classmethod @classmethod
def get_sheet_filename(cls, document): def get_sheet_filename(cls, document):
if hasattr(document, "Identification"): if hasattr(document, "Identification"):
@@ -273,6 +287,19 @@ class Drawing(blenderbim.core.tool.Drawing):
new.name = drawing.Name or "Unnamed" new.name = drawing.Name or "Unnamed"
new.target_view = cls.get_drawing_target_view(drawing) new.target_view = cls.get_drawing_target_view(drawing)
@classmethod
def import_schedules(cls):
bpy.context.scene.DocProperties.schedules.clear()
schedules = [d for d in tool.Ifc.get().by_type("IfcDocumentInformation") if d.Scope == "SCHEDULE"]
for schedule in schedules:
new = bpy.context.scene.DocProperties.schedules.add()
new.ifc_definition_id = schedule.id()
new.name = schedule.Name or "Unnamed"
if tool.Ifc.get_schema() == "IFC2X3":
new.identification = schedule.DocumentId
else:
new.identification = schedule.Identification
@classmethod @classmethod
def import_sheets(cls): def import_sheets(cls):
props = bpy.context.scene.DocProperties props = bpy.context.scene.DocProperties
@@ -333,6 +360,12 @@ class Drawing(blenderbim.core.tool.Drawing):
else: else:
webbrowser.open("file://" + path) webbrowser.open("file://" + path)
@classmethod
def open_spreadsheet(cls, uri):
cls.open_with_user_command(
bpy.context.preferences.addons["blenderbim"].preferences.spreadsheet_command, uri
)
@classmethod @classmethod
def open_svg(cls, filename): def open_svg(cls, filename):
cls.open_with_user_command( cls.open_with_user_command(
+65
View File
@@ -126,6 +126,71 @@ class TestRemoveSheet:
subject.remove_sheet(ifc, drawing, sheet="sheet") subject.remove_sheet(ifc, drawing, sheet="sheet")
class TestLoadSchedules:
def test_run(self, drawing):
drawing.import_schedules().should_be_called()
drawing.enable_editing_schedules().should_be_called()
subject.load_schedules(drawing)
class TestDisableEditingSchedules:
def test_run(self, drawing):
drawing.disable_editing_schedules().should_be_called()
subject.disable_editing_schedules(drawing)
class TestAddSchedule:
def test_run(self, ifc, drawing):
ifc.run("document.add_information").should_be_called().will_return("schedule")
ifc.run("document.add_reference", information="schedule").should_be_called().will_return("reference")
ifc.get_schema().should_be_called().will_return("IFC4")
ifc.run(
"document.edit_information",
information="schedule",
attributes={"Identification": "X", "Name": "UNTITLED", "Scope": "SCHEDULE", "Location": "uri"},
).should_be_called()
drawing.import_schedules().should_be_called()
subject.add_schedule(ifc, drawing, uri="uri")
def test_using_a_document_id_in_ifc2x3(self, ifc, drawing):
ifc.run("document.add_information").should_be_called().will_return("schedule")
ifc.run("document.add_reference", information="schedule").should_be_called().will_return("reference")
ifc.get_schema().should_be_called().will_return("IFC2X3")
ifc.run(
"document.edit_information",
information="schedule",
attributes={"DocumentId": "X", "Name": "UNTITLED", "Scope": "SCHEDULE"},
).should_be_called()
ifc.run("document.edit_reference", reference="reference", attributes={"Location": "uri"}).should_be_called()
drawing.import_schedules().should_be_called()
subject.add_schedule(ifc, drawing, uri="uri")
class TestRemoveSchedule:
def test_run(self, ifc, drawing):
ifc.run("document.remove_information", information="schedule").should_be_called()
drawing.import_schedules().should_be_called()
subject.remove_schedule(ifc, drawing, schedule="schedule")
class TestOpenSchedule:
def test_run(self, drawing):
drawing.get_schedule_location("schedule").should_be_called().will_return("uri")
drawing.open_spreadsheet("uri").should_be_called()
subject.open_schedule(drawing, schedule="schedule")
class TestUpdateScheduleName:
def test_do_not_update_if_name_unchanged(self, ifc, drawing):
drawing.get_name("schedule").should_be_called().will_return("name")
subject.update_drawing_name(ifc, drawing, schedule="schedule", name="name")
def test_run(self, ifc, drawing):
drawing.get_name("schedule").should_be_called().will_return("oldname")
ifc.run("document.edit_information", information="schedule", attributes={"Name": "name"}).should_be_called()
subject.update_drawing_name(ifc, drawing, schedule="schedule", name="name")
class TestLoadDrawings: class TestLoadDrawings:
def test_run(self, drawing): def test_run(self, drawing):
drawing.import_drawings().should_be_called() drawing.import_drawings().should_be_called()
+5 -5
View File
@@ -60,8 +60,8 @@ class TestAddRepresentation:
profile_set_usage="profile_set_usage", profile_set_usage="profile_set_usage",
).should_be_called().will_return("representation") ).should_be_called().will_return("representation")
# Styles are relevant for meshes with faces only # Styles are relevant for body representations only (as a simplification)
geometry.does_object_have_mesh_with_faces("obj").should_be_called().will_return(True) geometry.is_body_representation("representation").should_be_called().will_return(True)
# Add styles # Add styles
geometry.get_object_materials_without_styles("obj").should_be_called().will_return(["material"]) geometry.get_object_materials_without_styles("obj").should_be_called().will_return(["material"])
@@ -102,7 +102,7 @@ class TestAddRepresentation:
== "representation" == "representation"
) )
def test_not_handling_styles_if_representation_has_no_faces(self, ifc, geometry, style, surveyor): def test_not_handling_styles_if_not_a_body_representation(self, ifc, geometry, style, surveyor):
TestEditObjectPlacement.predict(self, ifc, geometry, surveyor) TestEditObjectPlacement.predict(self, ifc, geometry, surveyor)
# Add representation # Add representation
@@ -126,8 +126,8 @@ class TestAddRepresentation:
profile_set_usage="profile_set_usage", profile_set_usage="profile_set_usage",
).should_be_called().will_return("representation") ).should_be_called().will_return("representation")
# Styles are relevant for meshes with faces only # Styles are relevant for body representations only (as a simplification)
geometry.does_object_have_mesh_with_faces("obj").should_be_called().will_return(False) geometry.is_body_representation("representation").should_be_called().will_return(False)
# Assign representation to product # Assign representation to product
ifc.run("geometry.assign_representation", product="element", representation="representation").should_be_called() ifc.run("geometry.assign_representation", product="element", representation="representation").should_be_called()
+59
View File
@@ -87,6 +87,13 @@ class TestDisableEditingDrawings(NewFile):
assert bpy.context.scene.DocProperties.is_editing_drawings == False assert bpy.context.scene.DocProperties.is_editing_drawings == False
class TestDisableEditingSchedules(NewFile):
def test_run(self):
bpy.context.scene.DocProperties.is_editing_schedules = True
subject.disable_editing_schedules()
assert bpy.context.scene.DocProperties.is_editing_schedules == False
class TestDisableEditingSheets(NewFile): class TestDisableEditingSheets(NewFile):
def test_run(self): def test_run(self):
bpy.context.scene.DocProperties.is_editing_sheets = True bpy.context.scene.DocProperties.is_editing_sheets = True
@@ -125,6 +132,13 @@ class TestEnableEditingDrawings(NewFile):
assert bpy.context.scene.DocProperties.is_editing_drawings == True assert bpy.context.scene.DocProperties.is_editing_drawings == True
class TestEnableEditingSchedules(NewFile):
def test_run(self):
bpy.context.scene.DocProperties.is_editing_schedules = False
subject.enable_editing_schedules()
assert bpy.context.scene.DocProperties.is_editing_schedules == True
class TestEnableEditingSheets(NewFile): class TestEnableEditingSheets(NewFile):
def test_run(self): def test_run(self):
bpy.context.scene.DocProperties.is_editing_sheets = False bpy.context.scene.DocProperties.is_editing_sheets = False
@@ -263,6 +277,22 @@ class TestGetName(NewFile):
assert subject.get_name(ifc.createIfcWall(Name="Foobar")) == "Foobar" assert subject.get_name(ifc.createIfcWall(Name="Foobar")) == "Foobar"
class TestGetScheduleLocation(NewFile):
def test_run(self):
ifc = ifcopenshell.file()
ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcProject")
schedule = ifcopenshell.api.run("document.add_information", ifc)
schedule.Location = "uri"
reference = ifcopenshell.api.run("document.add_reference", ifc, information=schedule)
subject.get_schedule_location(schedule) == "uri"
def test_run_ifc2x3(self):
ifc = ifcopenshell.file(schema="IFC2X3")
reference = ifc.createIfcDocumentReference(Location="uri")
schedule = ifc.createIfcDocumentInformation(DocumentReferences=[reference])
subject.get_sheet_filename(schedule) == "uri"
class TestGetSheetFilename(NewFile): class TestGetSheetFilename(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
@@ -408,6 +438,30 @@ class TestImportDrawings(NewFile):
assert props.drawings[0].target_view == "PLAN_VIEW" assert props.drawings[0].target_view == "PLAN_VIEW"
class TestImportSchedules(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="SCHEDULE")
subject.import_schedules()
props = bpy.context.scene.DocProperties
assert props.schedules[0].ifc_definition_id == document.id()
assert props.schedules[0].identification == "X"
assert props.schedules[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="SCHEDULE")
subject.import_schedules()
props = bpy.context.scene.DocProperties
assert props.schedules[0].ifc_definition_id == document.id()
assert props.schedules[0].identification == "X"
assert props.schedules[0].name == "FOOBAR"
class TestImportSheets(NewFile): class TestImportSheets(NewFile):
def test_run(self): def test_run(self):
ifc = ifcopenshell.file() ifc = ifcopenshell.file()
@@ -475,6 +529,11 @@ class TestImportTextProduct(NewFile):
assert label_obj.BIMTextProperties.relating_product is None assert label_obj.BIMTextProperties.relating_product is None
class TestOpenSchedule(NewFile):
def open_spreadsheet(self):
pass
class TestOpenSvg(NewFile): class TestOpenSvg(NewFile):
def test_nothing(self): def test_nothing(self):
pass pass