mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 10:06:47 +00:00
Fix #1576. Managing IfcSystem subtypes is now possible.
This commit is contained in:
@@ -20,17 +20,16 @@ import bpy
|
||||
from . import ui, prop, operator
|
||||
|
||||
classes = (
|
||||
operator.LoadSystems,
|
||||
operator.DisableSystemEditingUI,
|
||||
operator.AddSystem,
|
||||
operator.EditSystem,
|
||||
operator.RemoveSystem,
|
||||
operator.ToggleAssigningSystem,
|
||||
operator.AssignSystem,
|
||||
operator.UnassignSystem,
|
||||
operator.EnableEditingSystem,
|
||||
operator.DisableEditingSystem,
|
||||
operator.DisableSystemEditingUI,
|
||||
operator.EditSystem,
|
||||
operator.EnableEditingSystem,
|
||||
operator.LoadSystems,
|
||||
operator.RemoveSystem,
|
||||
operator.SelectSystemProducts,
|
||||
operator.UnassignSystem,
|
||||
prop.System,
|
||||
prop.BIMSystemProperties,
|
||||
ui.BIM_PT_systems,
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.schema
|
||||
import blenderbim.tool as tool
|
||||
|
||||
|
||||
def refresh():
|
||||
SystemData.is_loaded = False
|
||||
ObjectSystemData.is_loaded = False
|
||||
|
||||
|
||||
class SystemData:
|
||||
data = {}
|
||||
is_loaded = False
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.data = {
|
||||
"system_class": cls.system_class(),
|
||||
"total_systems": cls.total_systems(),
|
||||
}
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def system_class(cls):
|
||||
declaration = tool.Ifc.schema().declaration_by_name("IfcSystem")
|
||||
declarations = ifcopenshell.util.schema.get_subtypes(declaration)
|
||||
# We're only interested in systems for services. Not sure why IFC groups these together.
|
||||
return [
|
||||
(c, c, "")
|
||||
for c in sorted([d.name() for d in declarations])
|
||||
if c not in ("IfcZone", "IfcStructuralAnalysisModel")
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def total_systems(cls):
|
||||
return len(tool.Ifc.get().by_type("IfcSystem"))
|
||||
|
||||
|
||||
class ObjectSystemData:
|
||||
data = {}
|
||||
is_loaded = False
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.data = {
|
||||
"systems": cls.systems(),
|
||||
"total_systems": cls.total_systems(),
|
||||
}
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def systems(cls):
|
||||
results = []
|
||||
element = tool.Ifc.get_entity(bpy.context.active_object)
|
||||
if not element:
|
||||
return results
|
||||
for system in ifcopenshell.util.system.get_element_systems(element):
|
||||
results.append({"id": system.id(), "name": system.Name or "Unnamed", "ifc_class": system.is_a()})
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def total_systems(cls):
|
||||
return len(tool.Ifc.get().by_type("IfcSystem"))
|
||||
@@ -17,208 +17,118 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.util.attribute
|
||||
import ifcopenshell.api
|
||||
import blenderbim.bim.helper
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.core.system as core
|
||||
import blenderbim.bim.handler
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from ifcopenshell.api.system.data import Data
|
||||
|
||||
|
||||
class LoadSystems(bpy.types.Operator):
|
||||
class Operator:
|
||||
def execute(self, context):
|
||||
IfcStore.execute_ifc_operator(self, context)
|
||||
blenderbim.bim.handler.refresh_ui_data()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class LoadSystems(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.load_systems"
|
||||
bl_label = "Load Systems"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMSystemProperties
|
||||
props.systems.clear()
|
||||
for ifc_definition_id, system in Data.systems.items():
|
||||
new = props.systems.add()
|
||||
new.ifc_definition_id = ifc_definition_id
|
||||
new.name = system["Name"]
|
||||
props.is_editing = True
|
||||
bpy.ops.bim.disable_editing_system()
|
||||
return {"FINISHED"}
|
||||
def _execute(self, context):
|
||||
core.load_systems(tool.System)
|
||||
|
||||
|
||||
class DisableSystemEditingUI(bpy.types.Operator):
|
||||
class DisableSystemEditingUI(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.disable_system_editing_ui"
|
||||
bl_label = "Disable System Editing UI"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
context.scene.BIMSystemProperties.is_editing = False
|
||||
context.scene.BIMSystemProperties.active_system_id = 0
|
||||
return {"FINISHED"}
|
||||
def _execute(self, context):
|
||||
core.disable_system_editing_ui(tool.System)
|
||||
|
||||
|
||||
class AddSystem(bpy.types.Operator):
|
||||
class AddSystem(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.add_system"
|
||||
bl_label = "Add System"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
result = ifcopenshell.api.run("system.add_system", IfcStore.get_file())
|
||||
Data.load(IfcStore.get_file())
|
||||
bpy.ops.bim.load_systems()
|
||||
bpy.ops.bim.enable_editing_system(system=result.id())
|
||||
return {"FINISHED"}
|
||||
core.add_system(tool.Ifc, tool.System, ifc_class=context.scene.BIMSystemProperties.system_class)
|
||||
|
||||
|
||||
class EditSystem(bpy.types.Operator):
|
||||
class EditSystem(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.edit_system"
|
||||
bl_label = "Edit System"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMSystemProperties
|
||||
attributes = {}
|
||||
for attribute in props.system_attributes:
|
||||
if attribute.is_null:
|
||||
attributes[attribute.name] = None
|
||||
else:
|
||||
attributes[attribute.name] = attribute.string_value
|
||||
self.file = IfcStore.get_file()
|
||||
ifcopenshell.api.run(
|
||||
"system.edit_system",
|
||||
self.file,
|
||||
**{"system": self.file.by_id(props.active_system_id), "attributes": attributes}
|
||||
core.edit_system(
|
||||
tool.Ifc, tool.System, system=tool.Ifc.get().by_id(context.scene.BIMSystemProperties.active_system_id)
|
||||
)
|
||||
Data.load(IfcStore.get_file())
|
||||
bpy.ops.bim.load_systems()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class RemoveSystem(bpy.types.Operator):
|
||||
class RemoveSystem(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.remove_system"
|
||||
bl_label = "Remove System"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
system: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMSystemProperties
|
||||
self.file = IfcStore.get_file()
|
||||
ifcopenshell.api.run("system.remove_system", self.file, **{"system": self.file.by_id(self.system)})
|
||||
Data.load(IfcStore.get_file())
|
||||
bpy.ops.bim.load_systems()
|
||||
return {"FINISHED"}
|
||||
core.remove_system(tool.Ifc, tool.System, system=tool.Ifc.get().by_id(self.system))
|
||||
|
||||
|
||||
class EnableEditingSystem(bpy.types.Operator):
|
||||
class EnableEditingSystem(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.enable_editing_system"
|
||||
bl_label = "Enable Editing System"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
system: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.BIMSystemProperties
|
||||
props.system_attributes.clear()
|
||||
|
||||
blenderbim.bim.helper.import_attributes("IfcSystem", props.system_attributes, Data.systems[self.system])
|
||||
props.active_system_id = self.system
|
||||
return {"FINISHED"}
|
||||
def _execute(self, context):
|
||||
core.enable_editing_system(tool.System, system=tool.Ifc.get().by_id(self.system))
|
||||
|
||||
|
||||
class DisableEditingSystem(bpy.types.Operator):
|
||||
class DisableEditingSystem(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.disable_editing_system"
|
||||
bl_label = "Disable Editing System"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
context.scene.BIMSystemProperties.active_system_id = 0
|
||||
return {"FINISHED"}
|
||||
def _execute(self, context):
|
||||
core.disable_editing_system(tool.System)
|
||||
|
||||
|
||||
class ToggleAssigningSystem(bpy.types.Operator):
|
||||
bl_idname = "bim.toggle_assigning_system"
|
||||
bl_label = "Toggle Assigning System"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def execute(self, context):
|
||||
context.scene.BIMSystemProperties.is_adding = not context.scene.BIMSystemProperties.is_adding
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AssignSystem(bpy.types.Operator):
|
||||
class AssignSystem(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.assign_system"
|
||||
bl_label = "Assign System"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
product: bpy.props.StringProperty()
|
||||
system: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
products = [bpy.data.objects.get(self.product)] if self.product else context.selected_objects
|
||||
for product in products:
|
||||
if not product.BIMObjectProperties.ifc_definition_id:
|
||||
continue
|
||||
ifcopenshell.api.run(
|
||||
"system.assign_system",
|
||||
self.file,
|
||||
**{
|
||||
"product": self.file.by_id(product.BIMObjectProperties.ifc_definition_id),
|
||||
"system": self.file.by_id(self.system),
|
||||
}
|
||||
)
|
||||
Data.load(self.file)
|
||||
return {"FINISHED"}
|
||||
for obj in context.selected_objects:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if element:
|
||||
core.assign_system(tool.Ifc, system=tool.Ifc.get().by_id(self.system), product=element)
|
||||
|
||||
|
||||
class UnassignSystem(bpy.types.Operator):
|
||||
class UnassignSystem(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.unassign_system"
|
||||
bl_label = "Unassign System"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
product: bpy.props.StringProperty()
|
||||
system: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
return IfcStore.execute_ifc_operator(self, context)
|
||||
|
||||
def _execute(self, context):
|
||||
self.file = IfcStore.get_file()
|
||||
products = [bpy.data.objects.get(self.product)] if self.product else context.selected_objects
|
||||
for product in products:
|
||||
props = product.BIMObjectProperties
|
||||
if not props.ifc_definition_id:
|
||||
continue
|
||||
if not (props.ifc_definition_id in Data.products and self.system in Data.products[props.ifc_definition_id]):
|
||||
continue
|
||||
ifcopenshell.api.run(
|
||||
"system.unassign_system",
|
||||
self.file,
|
||||
**{
|
||||
"product": self.file.by_id(product.BIMObjectProperties.ifc_definition_id),
|
||||
"system": self.file.by_id(self.system),
|
||||
}
|
||||
)
|
||||
Data.load(self.file)
|
||||
return {"FINISHED"}
|
||||
for obj in context.selected_objects:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if element:
|
||||
core.unassign_system(tool.Ifc, system=tool.Ifc.get().by_id(self.system), product=element)
|
||||
|
||||
|
||||
class SelectSystemProducts(bpy.types.Operator):
|
||||
class SelectSystemProducts(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.select_system_products"
|
||||
bl_label = "Select System Products"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
system: bpy.props.IntProperty()
|
||||
|
||||
def execute(self, context):
|
||||
for obj in context.visible_objects:
|
||||
obj.select_set(False)
|
||||
if not obj.BIMObjectProperties.ifc_definition_id:
|
||||
continue
|
||||
product_systems = Data.products.get(obj.BIMObjectProperties.ifc_definition_id, [])
|
||||
if self.system in product_systems:
|
||||
obj.select_set(True)
|
||||
return {"FINISHED"}
|
||||
def _execute(self, context):
|
||||
core.select_system_products(tool.System, system=tool.Ifc.get().by_id(self.system))
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
from blenderbim.bim.module.system.data import SystemData
|
||||
from blenderbim.bim.prop import StrProperty, Attribute
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
@@ -31,8 +32,15 @@ from bpy.props import (
|
||||
)
|
||||
|
||||
|
||||
def get_system_class(self, context):
|
||||
if not SystemData.is_loaded:
|
||||
SystemData.load()
|
||||
return SystemData.data["system_class"]
|
||||
|
||||
|
||||
class System(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
ifc_class: StringProperty(name="IFC Class")
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
|
||||
|
||||
@@ -43,3 +51,4 @@ class BIMSystemProperties(PropertyGroup):
|
||||
systems: CollectionProperty(name="Systems", type=System)
|
||||
active_system_index: IntProperty(name="Active System Index")
|
||||
active_system_id: IntProperty(name="Active System Id")
|
||||
system_class: EnumProperty(items=get_system_class, name="Class")
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
from bpy.types import Panel, UIList
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from ifcopenshell.api.system.data import Data
|
||||
from blenderbim.bim.module.system.data import SystemData, ObjectSystemData
|
||||
|
||||
|
||||
class BIM_PT_systems(Panel):
|
||||
@@ -35,15 +35,18 @@ class BIM_PT_systems(Panel):
|
||||
return IfcStore.get_file()
|
||||
|
||||
def draw(self, context):
|
||||
if not Data.is_loaded:
|
||||
Data.load(IfcStore.get_file())
|
||||
if not SystemData.is_loaded:
|
||||
SystemData.load()
|
||||
self.props = context.scene.BIMSystemProperties
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="{} Systems Found".format(len(Data.systems)), icon="OUTLINER")
|
||||
row.label(text="{} Systems Found".format(SystemData.data["total_systems"]), icon="OUTLINER")
|
||||
if self.props.is_editing:
|
||||
row.operator("bim.add_system", text="", icon="ADD")
|
||||
row.operator("bim.disable_system_editing_ui", text="", icon="CANCEL")
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.prop(self.props, "system_class", text="")
|
||||
row.operator("bim.add_system", text="", icon="ADD")
|
||||
else:
|
||||
row.operator("bim.load_systems", text="", icon="GREASEPENCIL")
|
||||
|
||||
@@ -84,13 +87,13 @@ class BIM_PT_object_systems(Panel):
|
||||
return IfcStore.get_file() and context.active_object.BIMObjectProperties.ifc_definition_id
|
||||
|
||||
def draw(self, context):
|
||||
if not Data.is_loaded:
|
||||
Data.load(IfcStore.get_file())
|
||||
if not ObjectSystemData.is_loaded:
|
||||
ObjectSystemData.load()
|
||||
self.props = context.scene.BIMSystemProperties
|
||||
row = self.layout.row(align=True)
|
||||
if self.props.is_adding:
|
||||
row.label(text="Adding Systems", icon="OUTLINER")
|
||||
row.operator("bim.toggle_assigning_system", text="", icon="CANCEL")
|
||||
if self.props.is_editing:
|
||||
row = self.layout.row()
|
||||
row.alignment = "RIGHT"
|
||||
row.operator("bim.disable_system_editing_ui", text="", icon="CANCEL")
|
||||
self.layout.template_list(
|
||||
"BIM_UL_object_systems",
|
||||
"",
|
||||
@@ -100,17 +103,23 @@ class BIM_PT_object_systems(Panel):
|
||||
"active_system_index",
|
||||
)
|
||||
else:
|
||||
row.label(text=f"{len(Data.systems)} Systems in IFC Project", icon="OUTLINER")
|
||||
row.operator("bim.toggle_assigning_system", text="", icon="ADD")
|
||||
|
||||
systems_object = Data.products.get(context.active_object.BIMObjectProperties.ifc_definition_id, [])
|
||||
for system_id in systems_object:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=Data.systems[system_id].get("Name", "Unnamed"))
|
||||
row.label(text=f"{ObjectSystemData.data['total_systems']} Systems in IFC Project", icon="OUTLINER")
|
||||
row.operator("bim.load_systems", text="", icon="GREASEPENCIL")
|
||||
|
||||
system_icons = {
|
||||
"IfcSystem": "EXTERNAL_DRIVE",
|
||||
"IfcDistributionSystem": "NETWORK_DRIVE",
|
||||
"IfcDistributionCircuit": "DRIVER",
|
||||
"IfcBuildingSystem": "MOD_BUILD",
|
||||
}
|
||||
for system in ObjectSystemData.data["systems"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=system["name"], icon=system_icons[system["ifc_class"]])
|
||||
op = row.operator("bim.select_system_products", text="", icon="RESTRICT_SELECT_OFF")
|
||||
op.system = system_id
|
||||
op.system = system["id"]
|
||||
op = row.operator("bim.unassign_system", text="", icon="X")
|
||||
op.system = system_id
|
||||
op.system = system["id"]
|
||||
|
||||
if not systems_object:
|
||||
self.layout.label(text="No System associated with Active Object")
|
||||
@@ -118,9 +127,15 @@ class BIM_PT_object_systems(Panel):
|
||||
|
||||
class BIM_UL_systems(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
system_icons = {
|
||||
"IfcSystem": "EXTERNAL_DRIVE",
|
||||
"IfcDistributionSystem": "NETWORK_DRIVE",
|
||||
"IfcDistributionCircuit": "DRIVER",
|
||||
"IfcBuildingSystem": "MOD_BUILD",
|
||||
}
|
||||
if item:
|
||||
row = layout.row(align=True)
|
||||
row.label(text=item.name)
|
||||
row.label(text=item.name, icon=system_icons[item.ifc_class])
|
||||
system_id = item.ifc_definition_id
|
||||
if context.scene.BIMSystemProperties.active_system_id == system_id:
|
||||
op = row.operator("bim.select_system_products", text="", icon="RESTRICT_SELECT_OFF")
|
||||
@@ -143,8 +158,13 @@ class BIM_UL_systems(UIList):
|
||||
|
||||
class BIM_UL_object_systems(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
system_icons = {
|
||||
"IfcSystem": "EXTERNAL_DRIVE",
|
||||
"IfcDistributionSystem": "NETWORK_DRIVE",
|
||||
"IfcDistributionCircuit": "DRIVER",
|
||||
"IfcBuildingSystem": "MOD_BUILD",
|
||||
}
|
||||
if item:
|
||||
row = layout.row(align=True)
|
||||
row.label(text=item.name)
|
||||
op = row.operator("bim.assign_system", text="", icon="ADD")
|
||||
op.system = item.ifc_definition_id
|
||||
row.label(text=item.name, icon=system_icons[item.ifc_class])
|
||||
row.operator("bim.assign_system", text="", icon="ADD").system = item.ifc_definition_id
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
|
||||
def load_systems(system):
|
||||
system.import_systems()
|
||||
system.enable_system_editing_ui()
|
||||
system.disable_editing_system()
|
||||
|
||||
|
||||
def disable_system_editing_ui(system):
|
||||
system.disable_editing_system()
|
||||
system.disable_system_editing_ui()
|
||||
|
||||
|
||||
def add_system(ifc, system, ifc_class=None):
|
||||
ifc.run("system.add_system", ifc_class=ifc_class)
|
||||
system.import_systems()
|
||||
|
||||
|
||||
def edit_system(ifc, system_tool, system=None):
|
||||
attributes = system_tool.export_system_attributes()
|
||||
ifc.run("system.edit_system", system=system, attributes=attributes)
|
||||
system_tool.disable_editing_system()
|
||||
system_tool.import_systems()
|
||||
|
||||
|
||||
def remove_system(ifc, system_tool, system=None):
|
||||
ifc.run("system.remove_system", system=system)
|
||||
system_tool.import_systems()
|
||||
|
||||
|
||||
def enable_editing_system(system_tool, system=None):
|
||||
system_tool.import_system_attributes(system)
|
||||
system_tool.set_active_system(system)
|
||||
|
||||
|
||||
def disable_editing_system(system):
|
||||
system.disable_editing_system()
|
||||
|
||||
|
||||
def assign_system(ifc, system=None, product=None):
|
||||
ifc.run("system.assign_system", product=product, system=system)
|
||||
|
||||
|
||||
def unassign_system(ifc, system=None, product=None):
|
||||
ifc.run("system.unassign_system", product=product, system=system)
|
||||
|
||||
|
||||
def select_system_products(system_tool, system=None):
|
||||
system_tool.select_system_products(system)
|
||||
@@ -315,6 +315,18 @@ class Surveyor:
|
||||
def get_absolute_matrix(cls, obj): pass
|
||||
|
||||
|
||||
@interface
|
||||
class System:
|
||||
def disable_editing_system(cls): pass
|
||||
def disable_system_editing_ui(cls): pass
|
||||
def enable_system_editing_ui(cls): pass
|
||||
def export_system_attributes(cls): pass
|
||||
def import_system_attributes(cls, system): pass
|
||||
def import_systems(cls): pass
|
||||
def select_system_products(cls, system): pass
|
||||
def set_active_system(cls, system): pass
|
||||
|
||||
|
||||
@interface
|
||||
class Type:
|
||||
def change_object_data(cls, obj, data, is_global=False): pass
|
||||
|
||||
@@ -37,5 +37,6 @@ from blenderbim.tool.spatial import Spatial
|
||||
from blenderbim.tool.structural import Structural
|
||||
from blenderbim.tool.style import Style
|
||||
from blenderbim.tool.surveyor import Surveyor
|
||||
from blenderbim.tool.system import System
|
||||
from blenderbim.tool.type import Type
|
||||
from blenderbim.tool.unit import Unit
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
import bpy
|
||||
import ifcopenshell.util.system
|
||||
import blenderbim.core.tool
|
||||
import blenderbim.tool as tool
|
||||
|
||||
|
||||
class System(blenderbim.core.tool.System):
|
||||
@classmethod
|
||||
def disable_editing_system(cls):
|
||||
bpy.context.scene.BIMSystemProperties.active_system_id = 0
|
||||
|
||||
@classmethod
|
||||
def disable_system_editing_ui(cls):
|
||||
bpy.context.scene.BIMSystemProperties.is_editing = False
|
||||
|
||||
@classmethod
|
||||
def enable_system_editing_ui(cls):
|
||||
bpy.context.scene.BIMSystemProperties.is_editing = True
|
||||
|
||||
@classmethod
|
||||
def export_system_attributes(cls):
|
||||
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMSystemProperties.system_attributes)
|
||||
|
||||
@classmethod
|
||||
def import_system_attributes(cls, system):
|
||||
blenderbim.bim.helper.import_attributes2(system, bpy.context.scene.BIMSystemProperties.system_attributes)
|
||||
|
||||
@classmethod
|
||||
def import_systems(cls):
|
||||
props = bpy.context.scene.BIMSystemProperties
|
||||
props.systems.clear()
|
||||
for system in tool.Ifc.get().by_type("IfcSystem"):
|
||||
if system.is_a() in ["IfcZone", "IfcStructuralAnalysisModel"]:
|
||||
continue
|
||||
new = props.systems.add()
|
||||
new.ifc_definition_id = system.id()
|
||||
new.name = system.Name or "Unnamed"
|
||||
new.ifc_class = system.is_a()
|
||||
|
||||
@classmethod
|
||||
def select_system_products(cls, system):
|
||||
for element in ifcopenshell.util.system.get_system_elements(system):
|
||||
obj = tool.Ifc.get_object(element)
|
||||
if obj:
|
||||
obj.select_set(True)
|
||||
|
||||
@classmethod
|
||||
def set_active_system(cls, system):
|
||||
bpy.context.scene.BIMSystemProperties.active_system_id = system.id()
|
||||
@@ -23,6 +23,7 @@ markers =
|
||||
spatial
|
||||
structural
|
||||
style
|
||||
system
|
||||
type
|
||||
unit
|
||||
void
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
@system
|
||||
Feature: System
|
||||
|
||||
Scenario: Load systems
|
||||
Given an empty IFC project
|
||||
When I press "bim.load_systems"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Disable system editing UI
|
||||
Given an empty IFC project
|
||||
When I press "bim.load_systems"
|
||||
And I press "bim.disable_system_editing_ui"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Add system
|
||||
Given an empty IFC project
|
||||
And I press "bim.load_systems"
|
||||
When I press "bim.add_system"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Edit system
|
||||
Given an empty IFC project
|
||||
And I press "bim.load_systems"
|
||||
And I press "bim.add_system"
|
||||
And the variable "system" is "{ifc}.by_type('IfcSystem')[0].id()"
|
||||
And I press "bim.enable_editing_system(system={system})"
|
||||
When I press "bim.edit_system"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Edit system
|
||||
Given an empty IFC project
|
||||
And I press "bim.load_systems"
|
||||
And I press "bim.add_system"
|
||||
And the variable "system" is "{ifc}.by_type('IfcSystem')[0].id()"
|
||||
When I press "bim.remove_system(system={system})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Enable editing system
|
||||
Given an empty IFC project
|
||||
And I press "bim.load_systems"
|
||||
And I press "bim.add_system"
|
||||
And the variable "system" is "{ifc}.by_type('IfcSystem')[0].id()"
|
||||
When I press "bim.enable_editing_system(system={system})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Disable editing system
|
||||
Given an empty IFC project
|
||||
And I press "bim.load_systems"
|
||||
And I press "bim.add_system"
|
||||
And the variable "system" is "{ifc}.by_type('IfcSystem')[0].id()"
|
||||
And I press "bim.enable_editing_system(system={system})"
|
||||
When I press "bim.disable_editing_system"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Assign system
|
||||
Given an empty IFC project
|
||||
And I press "bim.load_systems"
|
||||
And I press "bim.add_system"
|
||||
And the variable "system" is "{ifc}.by_type('IfcSystem')[0].id()"
|
||||
And I press "bim.enable_editing_system(system={system})"
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcPump"
|
||||
And I press "bim.assign_class"
|
||||
And the object "IfcPump/Cube" is selected
|
||||
When I press "bim.assign_system(system={system})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Unassign system
|
||||
Given an empty IFC project
|
||||
And I press "bim.load_systems"
|
||||
And I press "bim.add_system"
|
||||
And the variable "system" is "{ifc}.by_type('IfcSystem')[0].id()"
|
||||
And I press "bim.enable_editing_system(system={system})"
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcPump"
|
||||
And I press "bim.assign_class"
|
||||
And the object "IfcPump/Cube" is selected
|
||||
And I press "bim.assign_system(system={system})"
|
||||
When I press "bim.unassign_system(system={system})"
|
||||
Then nothing happens
|
||||
|
||||
Scenario: Select system products
|
||||
Given an empty IFC project
|
||||
And I press "bim.load_systems"
|
||||
And I press "bim.add_system"
|
||||
And the variable "system" is "{ifc}.by_type('IfcSystem')[0].id()"
|
||||
And I press "bim.enable_editing_system(system={system})"
|
||||
And I add a cube
|
||||
And the object "Cube" is selected
|
||||
And I set "scene.BIMRootProperties.ifc_class" to "IfcPump"
|
||||
And I press "bim.assign_class"
|
||||
And the object "IfcPump/Cube" is selected
|
||||
And I press "bim.assign_system(system={system})"
|
||||
When I press "bim.select_system_products(system={system})"
|
||||
Then nothing happens
|
||||
@@ -168,6 +168,13 @@ def surveyor():
|
||||
prophet.verify()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def system():
|
||||
prophet = Prophecy(blenderbim.core.tool.System)
|
||||
yield prophet
|
||||
prophet.verify()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def type():
|
||||
prophet = Prophecy(blenderbim.core.tool.Type)
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
|
||||
import blenderbim.core.system as subject
|
||||
from test.core.bootstrap import ifc, system
|
||||
|
||||
|
||||
class TestLoadSystems:
|
||||
def test_run(self, system):
|
||||
system.import_systems().should_be_called()
|
||||
system.enable_system_editing_ui().should_be_called()
|
||||
system.disable_editing_system().should_be_called()
|
||||
subject.load_systems(system)
|
||||
|
||||
|
||||
class TestDisableSystemEditingUI:
|
||||
def test_run(self, system):
|
||||
system.disable_editing_system().should_be_called()
|
||||
system.disable_system_editing_ui().should_be_called()
|
||||
subject.disable_system_editing_ui(system)
|
||||
|
||||
|
||||
class TestAddSystem:
|
||||
def test_run(self, ifc, system):
|
||||
ifc.run("system.add_system", ifc_class="ifc_class").should_be_called()
|
||||
system.import_systems().should_be_called()
|
||||
subject.add_system(ifc, system, ifc_class="ifc_class")
|
||||
|
||||
|
||||
class TestEditSystem:
|
||||
def test_run(self, ifc, system):
|
||||
system.export_system_attributes().should_be_called().will_return("attributes")
|
||||
ifc.run("system.edit_system", system="system", attributes="attributes").should_be_called()
|
||||
system.disable_editing_system().should_be_called()
|
||||
system.import_systems().should_be_called()
|
||||
subject.edit_system(ifc, system, system="system")
|
||||
|
||||
|
||||
class TestRemoveSystem:
|
||||
def test_run(self, ifc, system):
|
||||
ifc.run("system.remove_system", system="system").should_be_called()
|
||||
system.import_systems().should_be_called()
|
||||
subject.remove_system(ifc, system, system="system")
|
||||
|
||||
|
||||
class TestEnableEditingSystem:
|
||||
def test_run(self, system):
|
||||
system.import_system_attributes("system").should_be_called()
|
||||
system.set_active_system("system").should_be_called()
|
||||
subject.enable_editing_system(system, system="system")
|
||||
|
||||
|
||||
class TestDisableEditingSystem:
|
||||
def test_run(self, system):
|
||||
system.disable_editing_system().should_be_called()
|
||||
subject.disable_editing_system(system)
|
||||
|
||||
|
||||
class TestAssignSystem:
|
||||
def test_run(self, ifc):
|
||||
ifc.run("system.assign_system", product="product", system="system").should_be_called()
|
||||
subject.assign_system(ifc, system="system", product="product")
|
||||
|
||||
|
||||
class TestUnassignSystem:
|
||||
def test_run(self, ifc):
|
||||
ifc.run("system.unassign_system", product="product", system="system").should_be_called()
|
||||
subject.unassign_system(ifc, system="system", product="product")
|
||||
|
||||
|
||||
class TestSelectSystemProducts:
|
||||
def test_run(self, system):
|
||||
system.select_system_products("system").should_be_called()
|
||||
subject.select_system_products(system, system="system")
|
||||
@@ -0,0 +1,152 @@
|
||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of BlenderBIM Add-on.
|
||||
#
|
||||
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# 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/>.
|
||||
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import blenderbim.core.tool
|
||||
import blenderbim.tool as tool
|
||||
from test.bim.bootstrap import NewFile
|
||||
from blenderbim.tool.system import System as subject
|
||||
|
||||
|
||||
class TestImplementsTool(NewFile):
|
||||
def test_run(self):
|
||||
assert isinstance(subject(), blenderbim.core.tool.System)
|
||||
|
||||
|
||||
class TestDisableEditingSystem(NewFile):
|
||||
def test_run(self):
|
||||
bpy.context.scene.BIMSystemProperties.active_system_id = 10
|
||||
subject.disable_editing_system()
|
||||
assert bpy.context.scene.BIMSystemProperties.active_system_id == 0
|
||||
|
||||
|
||||
class TestDisableSystemEditingUI(NewFile):
|
||||
def test_run(self):
|
||||
subject.enable_system_editing_ui()
|
||||
subject.disable_system_editing_ui()
|
||||
assert bpy.context.scene.BIMSystemProperties.is_editing is False
|
||||
|
||||
|
||||
class TestEnableSystemEditingUI(NewFile):
|
||||
def test_run(self):
|
||||
subject.enable_system_editing_ui()
|
||||
assert bpy.context.scene.BIMSystemProperties.is_editing is True
|
||||
|
||||
|
||||
class TestExportSystemAttributes(NewFile):
|
||||
def test_run(self):
|
||||
TestImportSystemAttributes().test_importing_a_system()
|
||||
assert subject.export_system_attributes() == {
|
||||
"GlobalId": "GlobalId",
|
||||
"Name": "Name",
|
||||
"Description": "Description",
|
||||
"ObjectType": "ObjectType",
|
||||
}
|
||||
|
||||
|
||||
class TestImportSystemAttributes(NewFile):
|
||||
def test_importing_a_system(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc().set(ifc)
|
||||
system = ifc.createIfcSystem()
|
||||
system.GlobalId = "GlobalId"
|
||||
system.Name = "Name"
|
||||
system.Description = "Description"
|
||||
system.ObjectType = "ObjectType"
|
||||
subject().import_system_attributes(system)
|
||||
props = bpy.context.scene.BIMSystemProperties
|
||||
assert props.system_attributes.get("GlobalId").string_value == "GlobalId"
|
||||
assert props.system_attributes.get("Name").string_value == "Name"
|
||||
assert props.system_attributes.get("Description").string_value == "Description"
|
||||
assert props.system_attributes.get("ObjectType").string_value == "ObjectType"
|
||||
|
||||
def test_importing_a_building_system(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc().set(ifc)
|
||||
system = ifc.createIfcBuildingSystem()
|
||||
system.GlobalId = "GlobalId"
|
||||
system.Name = "Name"
|
||||
system.Description = "Description"
|
||||
system.ObjectType = "ObjectType"
|
||||
system.PredefinedType = "SHADING"
|
||||
system.LongName = "LongName"
|
||||
subject().import_system_attributes(system)
|
||||
props = bpy.context.scene.BIMSystemProperties
|
||||
assert props.system_attributes.get("GlobalId").string_value == "GlobalId"
|
||||
assert props.system_attributes.get("Name").string_value == "Name"
|
||||
assert props.system_attributes.get("Description").string_value == "Description"
|
||||
assert props.system_attributes.get("ObjectType").string_value == "ObjectType"
|
||||
assert props.system_attributes.get("PredefinedType").enum_value == "SHADING"
|
||||
assert props.system_attributes.get("LongName").string_value == "LongName"
|
||||
|
||||
def test_importing_a_distribution_system(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc().set(ifc)
|
||||
system = ifc.createIfcDistributionSystem()
|
||||
system.GlobalId = "GlobalId"
|
||||
system.Name = "Name"
|
||||
system.Description = "Description"
|
||||
system.ObjectType = "ObjectType"
|
||||
system.PredefinedType = "ELECTRICAL"
|
||||
system.LongName = "LongName"
|
||||
subject().import_system_attributes(system)
|
||||
props = bpy.context.scene.BIMSystemProperties
|
||||
assert props.system_attributes.get("GlobalId").string_value == "GlobalId"
|
||||
assert props.system_attributes.get("Name").string_value == "Name"
|
||||
assert props.system_attributes.get("Description").string_value == "Description"
|
||||
assert props.system_attributes.get("ObjectType").string_value == "ObjectType"
|
||||
assert props.system_attributes.get("PredefinedType").enum_value == "ELECTRICAL"
|
||||
assert props.system_attributes.get("LongName").string_value == "LongName"
|
||||
|
||||
|
||||
class TestImportSystems(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc().set(ifc)
|
||||
system = ifc.createIfcDistributionSystem()
|
||||
zone = ifc.createIfcZone()
|
||||
subject.import_systems()
|
||||
props = bpy.context.scene.BIMSystemProperties
|
||||
assert len(props.systems) == 1
|
||||
assert props.systems[0].ifc_definition_id == system.id()
|
||||
assert props.systems[0].name == "Unnamed"
|
||||
assert props.systems[0].ifc_class == "IfcDistributionSystem"
|
||||
|
||||
|
||||
class TestSelectSystemProducts(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc().set(ifc)
|
||||
element = ifcopenshell.api.run("root.create_entity", ifc, ifc_class="IfcPump")
|
||||
system = ifcopenshell.api.run("system.add_system", ifc, ifc_class="IfcSystem")
|
||||
ifcopenshell.api.run("system.assign_system", ifc, product=element, system=system)
|
||||
obj = bpy.data.objects.new("Object", None)
|
||||
bpy.context.scene.collection.objects.link(obj)
|
||||
tool.Ifc.link(element, obj)
|
||||
subject.select_system_products(system)
|
||||
assert obj in bpy.context.selected_objects
|
||||
|
||||
|
||||
class TestSetActiveSystem(NewFile):
|
||||
def test_run(self):
|
||||
ifc = ifcopenshell.file()
|
||||
tool.Ifc().set(ifc)
|
||||
system = ifcopenshell.api.run("system.add_system", ifc, ifc_class="IfcSystem")
|
||||
subject.set_active_system(system)
|
||||
assert bpy.context.scene.BIMSystemProperties.active_system_id == system.id()
|
||||
@@ -9,8 +9,8 @@ qa:
|
||||
|
||||
.PHONY: license
|
||||
license:
|
||||
#copyright-header --license LGPL3 --copyright-holder "Thomas Krijnen <thomas@aecgeeks.com>" --copyright-year "2021" --copyright-software "IfcOpenShell" --copyright-software-description "IFC toolkit and geometry engine" -a ./ -o ./
|
||||
copyright-header --license LGPL3 --copyright-holder "Dion Moult <dion@thinkmoult.com>" --copyright-year "2021" --copyright-software "IfcOpenShell" --copyright-software-description "IFC toolkit and geometry engine" -a ./ -o ./
|
||||
#copyright-header --license LGPL3 --copyright-holder "Thomas Krijnen <thomas@aecgeeks.com>" --copyright-year "2022" --copyright-software "IfcOpenShell" --copyright-software-description "IFC toolkit and geometry engine" -a ./ -o ./
|
||||
copyright-header --license LGPL3 --copyright-holder "Dion Moult <dion@thinkmoult.com>" --copyright-year "2022" --copyright-software "IfcOpenShell" --copyright-software-description "IFC toolkit and geometry engine" -a ./ -o ./
|
||||
|
||||
.PHONY: coverage
|
||||
coverage:
|
||||
|
||||
@@ -23,13 +23,13 @@ import ifcopenshell.api
|
||||
class Usecase:
|
||||
def __init__(self, file, **settings):
|
||||
self.file = file
|
||||
self.settings = {}
|
||||
self.settings = {"ifc_class": "IfcSystem"}
|
||||
for key, value in settings.items():
|
||||
self.settings[key] = value
|
||||
|
||||
def execute(self):
|
||||
return self.file.create_entity(
|
||||
"IfcSystem",
|
||||
self.settings["ifc_class"],
|
||||
**{
|
||||
"GlobalId": ifcopenshell.guid.new(),
|
||||
"OwnerHistory": ifcopenshell.api.run("owner.create_owner_history", self.file),
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
def get_system_elements(system):
|
||||
results = []
|
||||
for rel in system.IsGroupedBy:
|
||||
results.extend(rel.RelatedObjects)
|
||||
return results
|
||||
|
||||
|
||||
def get_element_systems(element):
|
||||
results = []
|
||||
for rel in element.HasAssignments:
|
||||
if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.is_a() in [
|
||||
"IfcSystem",
|
||||
"IfcDistributionSystem",
|
||||
"IfcBuildingSystem",
|
||||
]:
|
||||
results.append(rel.RelatingGroup)
|
||||
return results
|
||||
@@ -0,0 +1,28 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
class TestAddSystem(test.bootstrap.IFC4):
|
||||
def test_adding_a_system(self):
|
||||
system = ifcopenshell.api.run("system.add_system", self.file, ifc_class="IfcSystem")
|
||||
system2 = ifcopenshell.api.run("system.add_system", self.file, ifc_class="IfcDistributionSystem")
|
||||
assert system.is_a("IfcSystem")
|
||||
assert system2.is_a("IfcDistributionSystem")
|
||||
@@ -0,0 +1,27 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
class TestRemoveSystem(test.bootstrap.IFC4):
|
||||
def test_removing_a_system(self):
|
||||
system = ifcopenshell.api.run("system.add_system", self.file, ifc_class="IfcSystem")
|
||||
ifcopenshell.api.run("system.remove_system", self.file, system=system)
|
||||
assert len(self.file.by_type("IfcSystem")) == 0
|
||||
@@ -0,0 +1,47 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import pytest
|
||||
import test.bootstrap
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.system as subject
|
||||
|
||||
|
||||
class TestGetSystemElements(test.bootstrap.IFC4):
|
||||
def test_run(self):
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcPump")
|
||||
system = ifcopenshell.api.run("system.add_system", self.file, ifc_class="IfcSystem")
|
||||
ifcopenshell.api.run("system.assign_system", self.file, product=element, system=system)
|
||||
assert subject.get_system_elements(system) == [element]
|
||||
|
||||
|
||||
class TestGetElementSystems(test.bootstrap.IFC4):
|
||||
def test_run(self):
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcPump")
|
||||
system = ifcopenshell.api.run("system.add_system", self.file, ifc_class="IfcSystem")
|
||||
ifcopenshell.api.run("system.assign_system", self.file, product=element, system=system)
|
||||
assert subject.get_element_systems(element) == [system]
|
||||
|
||||
def test_do_not_get_non_services_groups(self):
|
||||
element = ifcopenshell.api.run("root.create_entity", self.file, ifc_class="IfcPump")
|
||||
ifcopenshell.api.run("system.assign_system", self.file, product=element, system=self.file.createIfcGroup())
|
||||
ifcopenshell.api.run("system.assign_system", self.file, product=element, system=self.file.createIfcZone())
|
||||
ifcopenshell.api.run(
|
||||
"system.assign_system", self.file, product=element, system=self.file.createIfcStructuralAnalysisModel()
|
||||
)
|
||||
assert not subject.get_element_systems(element)
|
||||
Reference in New Issue
Block a user