mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
#1153 You can now add / remove / open schedules, implemented as IFC documents
This commit is contained in:
@@ -39,6 +39,7 @@ classes = (
|
||||
operator.CreateDrawing,
|
||||
operator.CreateSheets,
|
||||
operator.DisableEditingDrawings,
|
||||
operator.DisableEditingSchedules,
|
||||
operator.DisableEditingSheets,
|
||||
operator.DisableEditingText,
|
||||
operator.DisableEditingTextProduct,
|
||||
@@ -49,7 +50,9 @@ classes = (
|
||||
operator.EnableEditingTextProduct,
|
||||
operator.ExpandSheet,
|
||||
operator.LoadDrawings,
|
||||
operator.LoadSchedules,
|
||||
operator.LoadSheets,
|
||||
operator.OpenSchedule,
|
||||
operator.OpenSheet,
|
||||
operator.OpenView,
|
||||
operator.RemoveDrawing,
|
||||
@@ -61,7 +64,6 @@ classes = (
|
||||
operator.ResizeText,
|
||||
operator.SaveDrawingStyle,
|
||||
operator.SelectDocIfcFile,
|
||||
operator.SelectScheduleFile,
|
||||
prop.Variable,
|
||||
prop.Drawing,
|
||||
prop.Schedule,
|
||||
|
||||
@@ -24,6 +24,7 @@ import blenderbim.tool as tool
|
||||
def refresh():
|
||||
TextData.is_loaded = False
|
||||
SheetsData.is_loaded = False
|
||||
SchedulesData.is_loaded = False
|
||||
DrawingsData.is_loaded = False
|
||||
|
||||
|
||||
@@ -94,3 +95,17 @@ class DrawingsData:
|
||||
)
|
||||
return results
|
||||
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))
|
||||
|
||||
|
||||
class AddSchedule(bpy.types.Operator):
|
||||
class AddSchedule(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.add_schedule"
|
||||
bl_label = "Add Schedule"
|
||||
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")
|
||||
filter_glob: bpy.props.StringProperty(default="*.ods", options={"HIDDEN"})
|
||||
index: bpy.props.IntProperty()
|
||||
filter_glob: bpy.props.StringProperty(default="*.ods;*.xls;*.xlsx", options={"HIDDEN"})
|
||||
use_relative_path: bpy.props.BoolProperty(name="Use Relative Path", default=False)
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.DocProperties
|
||||
props.active_schedule.file = self.filepath
|
||||
return {"FINISHED"}
|
||||
def _execute(self, context):
|
||||
filepath = self.filepath
|
||||
if self.use_relative_path:
|
||||
filepath = os.path.relpath(filepath, bpy.path.abspath("//"))
|
||||
core.add_schedule(
|
||||
tool.Ifc,
|
||||
tool.Drawing,
|
||||
uri=filepath,
|
||||
)
|
||||
|
||||
def invoke(self, context, event):
|
||||
context.window_manager.fileselect_add(self)
|
||||
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):
|
||||
bl_idname = "bim.build_schedule"
|
||||
bl_label = "Build Schedule"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.scene.DocProperties.active_schedule.file
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.DocProperties
|
||||
schedule = props.active_schedule
|
||||
@@ -1269,6 +1267,24 @@ class DisableEditingSheets(bpy.types.Operator, Operator):
|
||||
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):
|
||||
bl_idname = "bim.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)
|
||||
|
||||
|
||||
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):
|
||||
update_layer(self, context, "HasUnderlay", self.has_underlay)
|
||||
|
||||
@@ -231,8 +236,9 @@ class Drawing(PropertyGroup):
|
||||
|
||||
|
||||
class Schedule(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
file: StringProperty(name="File")
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
name: StringProperty(name="Name", update=update_schedule_name)
|
||||
identification: StringProperty(name="Identification")
|
||||
|
||||
|
||||
class Sheet(PropertyGroup):
|
||||
@@ -305,6 +311,7 @@ class DocProperties(PropertyGroup):
|
||||
should_use_annotation_cache: BoolProperty(name="Use Annotation Cache", default=False)
|
||||
should_extract: BoolProperty(name="Should Extract", default=True)
|
||||
is_editing_drawings: BoolProperty(name="Is Editing Drawings", default=False)
|
||||
is_editing_schedules: BoolProperty(name="Is Editing Schedules", default=False)
|
||||
target_view: EnumProperty(
|
||||
items=[
|
||||
("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
|
||||
)
|
||||
|
||||
@property
|
||||
def active_schedule(self):
|
||||
return self.schedules[self.active_schedule_index]
|
||||
|
||||
|
||||
class BIMCameraProperties(PropertyGroup):
|
||||
has_underlay: BoolProperty(name="Underlay", default=False, update=update_has_underlay)
|
||||
|
||||
@@ -20,7 +20,7 @@ import bpy
|
||||
import blenderbim.bim.helper
|
||||
import blenderbim.tool as tool
|
||||
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):
|
||||
@@ -196,22 +196,31 @@ class BIM_PT_schedules(Panel):
|
||||
bl_category = "BIM Documentation"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_split = True
|
||||
props = context.scene.DocProperties
|
||||
if not SchedulesData.is_loaded:
|
||||
SchedulesData.load()
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.operator("bim.add_schedule")
|
||||
self.props = context.scene.DocProperties
|
||||
|
||||
if props.schedules:
|
||||
row.operator("bim.build_schedule", icon="LINENUMBERS_ON", text="")
|
||||
row.operator("bim.remove_schedule", icon="X", text="").index = props.active_schedule_index
|
||||
if not self.props.is_editing_schedules:
|
||||
row = self.layout.row(align=True)
|
||||
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()
|
||||
row.prop(props.active_schedule, "file")
|
||||
row.operator("bim.select_schedule_file", icon="FILE_FOLDER", text="")
|
||||
if self.props.schedules:
|
||||
if self.props.active_schedule_index < len(self.props.schedules):
|
||||
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):
|
||||
|
||||
@@ -106,8 +106,9 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
||||
name="SVG to DXF Command",
|
||||
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]]")
|
||||
pdf_command: StringProperty(name="PDF 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', path]]")
|
||||
spreadsheet_command: StringProperty(name="Spreadsheet Command", description="E.g. [['libreoffice', path]]")
|
||||
openlca_port: IntProperty(name="OpenLCA IPC Port", default=8080)
|
||||
should_hide_empty_props: BoolProperty(name="Should Hide Empty Properties", default=True)
|
||||
should_play_chaching_sound: BoolProperty(
|
||||
@@ -141,6 +142,8 @@ class BIM_ADDON_preferences(bpy.types.AddonPreferences):
|
||||
row = layout.row()
|
||||
row.prop(self, "pdf_command")
|
||||
row = layout.row()
|
||||
row.prop(self, "spreadsheet_command")
|
||||
row = layout.row()
|
||||
row.prop(self, "openlca_port")
|
||||
row = layout.row()
|
||||
row.prop(self, "should_hide_empty_props")
|
||||
|
||||
@@ -89,6 +89,42 @@ def remove_sheet(ifc, drawing, sheet=None):
|
||||
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):
|
||||
drawing.import_drawings()
|
||||
drawing.enable_editing_drawings()
|
||||
|
||||
@@ -161,11 +161,13 @@ class Drawing:
|
||||
def delete_drawing_elements(cls, elements): pass
|
||||
def delete_object(cls, obj): pass
|
||||
def disable_editing_drawings(cls): pass
|
||||
def disable_editing_schedules(cls): pass
|
||||
def disable_editing_sheets(cls): pass
|
||||
def disable_editing_text(cls, obj): pass
|
||||
def disable_editing_text_product(cls, obj): pass
|
||||
def enable_editing(cls, obj): pass
|
||||
def enable_editing_drawings(cls): pass
|
||||
def enable_editing_schedules(cls): pass
|
||||
def enable_editing_sheets(cls): pass
|
||||
def enable_editing_text(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_product(cls, element): pass
|
||||
def import_drawings(cls): pass
|
||||
def import_schedules(cls): pass
|
||||
def import_sheets(cls): pass
|
||||
def import_text_attributes(cls, obj): pass
|
||||
def import_text_product(cls, obj): pass
|
||||
|
||||
@@ -98,6 +98,10 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
def disable_editing_drawings(cls):
|
||||
bpy.context.scene.DocProperties.is_editing_drawings = False
|
||||
|
||||
@classmethod
|
||||
def disable_editing_schedules(cls):
|
||||
bpy.context.scene.DocProperties.is_editing_schedules = False
|
||||
|
||||
@classmethod
|
||||
def disable_editing_sheets(cls):
|
||||
bpy.context.scene.DocProperties.is_editing_sheets = False
|
||||
@@ -122,6 +126,10 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
def enable_editing_drawings(cls):
|
||||
bpy.context.scene.DocProperties.is_editing_drawings = True
|
||||
|
||||
@classmethod
|
||||
def enable_editing_schedules(cls):
|
||||
bpy.context.scene.DocProperties.is_editing_schedules = True
|
||||
|
||||
@classmethod
|
||||
def enable_editing_sheets(cls):
|
||||
bpy.context.scene.DocProperties.is_editing_sheets = True
|
||||
@@ -197,6 +205,12 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
def get_name(cls, element):
|
||||
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
|
||||
def get_sheet_filename(cls, document):
|
||||
if hasattr(document, "Identification"):
|
||||
@@ -273,6 +287,19 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
new.name = drawing.Name or "Unnamed"
|
||||
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
|
||||
def import_sheets(cls):
|
||||
props = bpy.context.scene.DocProperties
|
||||
@@ -333,6 +360,12 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
else:
|
||||
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
|
||||
def open_svg(cls, filename):
|
||||
cls.open_with_user_command(
|
||||
|
||||
@@ -126,6 +126,71 @@ class TestRemoveSheet:
|
||||
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:
|
||||
def test_run(self, drawing):
|
||||
drawing.import_drawings().should_be_called()
|
||||
|
||||
@@ -60,8 +60,8 @@ class TestAddRepresentation:
|
||||
profile_set_usage="profile_set_usage",
|
||||
).should_be_called().will_return("representation")
|
||||
|
||||
# Styles are relevant for meshes with faces only
|
||||
geometry.does_object_have_mesh_with_faces("obj").should_be_called().will_return(True)
|
||||
# Styles are relevant for body representations only (as a simplification)
|
||||
geometry.is_body_representation("representation").should_be_called().will_return(True)
|
||||
|
||||
# Add styles
|
||||
geometry.get_object_materials_without_styles("obj").should_be_called().will_return(["material"])
|
||||
@@ -102,7 +102,7 @@ class TestAddRepresentation:
|
||||
== "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)
|
||||
|
||||
# Add representation
|
||||
@@ -126,8 +126,8 @@ class TestAddRepresentation:
|
||||
profile_set_usage="profile_set_usage",
|
||||
).should_be_called().will_return("representation")
|
||||
|
||||
# Styles are relevant for meshes with faces only
|
||||
geometry.does_object_have_mesh_with_faces("obj").should_be_called().will_return(False)
|
||||
# Styles are relevant for body representations only (as a simplification)
|
||||
geometry.is_body_representation("representation").should_be_called().will_return(False)
|
||||
|
||||
# Assign representation to product
|
||||
ifc.run("geometry.assign_representation", product="element", representation="representation").should_be_called()
|
||||
|
||||
@@ -87,6 +87,13 @@ class TestDisableEditingDrawings(NewFile):
|
||||
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):
|
||||
def test_run(self):
|
||||
bpy.context.scene.DocProperties.is_editing_sheets = True
|
||||
@@ -125,6 +132,13 @@ class TestEnableEditingDrawings(NewFile):
|
||||
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):
|
||||
def test_run(self):
|
||||
bpy.context.scene.DocProperties.is_editing_sheets = False
|
||||
@@ -263,6 +277,22 @@ class TestGetName(NewFile):
|
||||
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):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
@@ -408,6 +438,30 @@ class TestImportDrawings(NewFile):
|
||||
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):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
@@ -475,6 +529,11 @@ class TestImportTextProduct(NewFile):
|
||||
assert label_obj.BIMTextProperties.relating_product is None
|
||||
|
||||
|
||||
class TestOpenSchedule(NewFile):
|
||||
def open_spreadsheet(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestOpenSvg(NewFile):
|
||||
def test_nothing(self):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user