mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Fix #3095. Very basic implementation of a new zones panel.
This commit is contained in:
@@ -150,6 +150,7 @@ classes = [
|
||||
# Services and systems
|
||||
ui.BIM_PT_tab_services,
|
||||
ui.BIM_PT_tab_services_object,
|
||||
ui.BIM_PT_tab_zones,
|
||||
# Structural analysis
|
||||
ui.BIM_PT_tab_structural,
|
||||
# Construction scheduling
|
||||
|
||||
@@ -22,38 +22,52 @@ from . import ui, prop, operator, decorator
|
||||
classes = (
|
||||
operator.AddPort,
|
||||
operator.AddSystem,
|
||||
operator.AddZone,
|
||||
operator.AssignSystem,
|
||||
operator.ConnectPort,
|
||||
operator.DisableEditingSystem,
|
||||
operator.DisableEditingZone,
|
||||
operator.DisableSystemEditingUI,
|
||||
operator.DisconnectPort,
|
||||
operator.EditSystem,
|
||||
operator.EditZone,
|
||||
operator.EnableEditingSystem,
|
||||
operator.EnableEditingZone,
|
||||
operator.HidePorts,
|
||||
operator.LoadSystems,
|
||||
operator.LoadZones,
|
||||
operator.MEPConnectElements,
|
||||
operator.RemovePort,
|
||||
operator.RemoveSystem,
|
||||
operator.RemoveZone,
|
||||
operator.SelectSystemProducts,
|
||||
operator.MEPConnectElements,
|
||||
operator.SetFlowDirection,
|
||||
operator.ShowPorts,
|
||||
operator.UnassignSystem,
|
||||
operator.UnloadZones,
|
||||
prop.System,
|
||||
prop.Zone,
|
||||
prop.BIMSystemProperties,
|
||||
prop.BIMZoneProperties,
|
||||
ui.BIM_PT_systems,
|
||||
ui.BIM_PT_object_systems,
|
||||
ui.BIM_PT_zones,
|
||||
ui.BIM_PT_active_object_zones,
|
||||
ui.BIM_PT_ports,
|
||||
ui.BIM_PT_port,
|
||||
ui.BIM_UL_systems,
|
||||
ui.BIM_UL_object_systems,
|
||||
ui.BIM_UL_zones,
|
||||
)
|
||||
|
||||
|
||||
def register():
|
||||
bpy.types.Scene.BIMSystemProperties = bpy.props.PointerProperty(type=prop.BIMSystemProperties)
|
||||
bpy.types.Scene.BIMZoneProperties = bpy.props.PointerProperty(type=prop.BIMZoneProperties)
|
||||
bpy.app.handlers.load_post.append(decorator.toggle_decorations_on_load)
|
||||
|
||||
|
||||
def unregister():
|
||||
del bpy.types.Scene.BIMSystemProperties
|
||||
del bpy.types.Scene.BIMZoneProperties
|
||||
bpy.app.handlers.load_post.remove(decorator.toggle_decorations_on_load)
|
||||
|
||||
@@ -25,6 +25,8 @@ import blenderbim.tool as tool
|
||||
|
||||
def refresh():
|
||||
SystemData.is_loaded = False
|
||||
ZonesData.is_loaded = False
|
||||
ActiveObjectZonesData.is_loaded = False
|
||||
ObjectSystemData.is_loaded = False
|
||||
PortData.is_loaded = False
|
||||
SystemDecorationData.is_loaded = False
|
||||
@@ -47,8 +49,6 @@ class SystemData:
|
||||
declaration = tool.Ifc.schema().declaration_by_name("IfcSystem")
|
||||
declarations = ifcopenshell.util.schema.get_subtypes(declaration)
|
||||
version = tool.Ifc.get_schema()
|
||||
if version == "IFC2X3":
|
||||
declarations += [tool.Ifc.schema().declaration_by_name("IfcZone")]
|
||||
|
||||
# We're only interested in systems for services. Not sure why IFC groups these together.
|
||||
return [
|
||||
@@ -193,3 +193,32 @@ class SystemDecorationData:
|
||||
ports_data.append(port_data)
|
||||
cls.elements_ports_positions[element] = ports_data
|
||||
return cls.elements_ports_positions[element]
|
||||
|
||||
|
||||
class ZonesData:
|
||||
data = {}
|
||||
is_loaded = False
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.data = { "total_zones": cls.total_zones() }
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def total_zones(cls):
|
||||
return len(tool.Ifc.get().by_type("IfcZone"))
|
||||
|
||||
|
||||
class ActiveObjectZonesData:
|
||||
data = {}
|
||||
is_loaded = False
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
cls.data = { "zones": cls.zones() }
|
||||
cls.is_loaded = True
|
||||
|
||||
@classmethod
|
||||
def zones(cls):
|
||||
systems = ifcopenshell.util.system.get_element_systems(tool.Ifc.get_entity(bpy.context.active_object))
|
||||
return [s.Name or "Unnamed" for s in systems if s.is_a("IfcZone")]
|
||||
|
||||
@@ -21,6 +21,7 @@ import ifcopenshell.api
|
||||
import blenderbim.tool as tool
|
||||
import blenderbim.core.system as core
|
||||
import blenderbim.bim.handler
|
||||
import blenderbim.bim.helper
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.system.data import PortData
|
||||
from mathutils import Matrix
|
||||
@@ -326,3 +327,97 @@ class SetFlowDirection(bpy.types.Operator, Operator):
|
||||
|
||||
self.report({"ERROR"}, "Selected elements are not connected to set the flow direction")
|
||||
return {"CANCELLED"}
|
||||
|
||||
|
||||
class LoadZones(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.load_zones"
|
||||
bl_label = "Load Zones"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = bpy.context.scene.BIMZoneProperties
|
||||
props.zones.clear()
|
||||
for zone in tool.Ifc.get().by_type("IfcZone"):
|
||||
new = props.zones.add()
|
||||
new.ifc_definition_id = zone.id()
|
||||
new.name = zone.Name or "Unnamed"
|
||||
props.is_loaded = True
|
||||
props.is_editing = 0
|
||||
|
||||
|
||||
class UnloadZones(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.unload_zones"
|
||||
bl_label = "Unload Zones"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = bpy.context.scene.BIMZoneProperties
|
||||
props.is_loaded = False
|
||||
|
||||
|
||||
class AddZone(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.add_zone"
|
||||
bl_label = "Add Zone"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
name: bpy.props.StringProperty()
|
||||
|
||||
def invoke(self, context, event):
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
def draw(self, context):
|
||||
row = self.layout
|
||||
row.prop(self, "name", text="Name")
|
||||
|
||||
def _execute(self, context):
|
||||
element = ifcopenshell.api.run("system.add_system", tool.Ifc.get(), ifc_class="IfcZone")
|
||||
if self.name:
|
||||
element.Name = self.name
|
||||
bpy.ops.bim.load_zones()
|
||||
|
||||
|
||||
class EnableEditingZone(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.enable_editing_zone"
|
||||
bl_label = "Enable Editing Zone"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
zone: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
props = bpy.context.scene.BIMZoneProperties
|
||||
props.attributes.clear()
|
||||
blenderbim.bim.helper.import_attributes2(tool.Ifc.get().by_id(self.zone), props.attributes)
|
||||
props.is_editing = self.zone
|
||||
|
||||
|
||||
class DisableEditingZone(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.disable_editing_zone"
|
||||
bl_label = "Disable Editing Zone"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = bpy.context.scene.BIMZoneProperties
|
||||
props.is_editing = 0
|
||||
|
||||
|
||||
class EditZone(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.edit_zone"
|
||||
bl_label = "Edit Zone"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = bpy.context.scene.BIMZoneProperties
|
||||
zone = tool.Ifc.get().by_id(props.is_editing)
|
||||
attributes = blenderbim.bim.helper.export_attributes(props.attributes)
|
||||
ifcopenshell.api.run("system.edit_system", tool.Ifc.get(), system=zone, attributes=attributes)
|
||||
props.is_editing = 0
|
||||
bpy.ops.bim.load_zones()
|
||||
|
||||
|
||||
class RemoveZone(bpy.types.Operator, Operator):
|
||||
bl_idname = "bim.remove_zone"
|
||||
bl_label = "Remove Zone"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
zone: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
ifcopenshell.api.run("system.remove_system", tool.Ifc.get(), system=tool.Ifc.get().by_id(self.zone))
|
||||
bpy.ops.bim.load_zones()
|
||||
|
||||
@@ -45,6 +45,11 @@ class System(PropertyGroup):
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
|
||||
|
||||
class Zone(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
ifc_definition_id: IntProperty(name="IFC Definition ID")
|
||||
|
||||
|
||||
def toggle_decorations(self, context):
|
||||
toggle = self.should_draw_decorations
|
||||
if toggle:
|
||||
@@ -64,3 +69,11 @@ class BIMSystemProperties(PropertyGroup):
|
||||
should_draw_decorations: BoolProperty(
|
||||
name="Should Draw Decorations", description="Toggle system decorations", update=toggle_decorations
|
||||
)
|
||||
|
||||
|
||||
class BIMZoneProperties(PropertyGroup):
|
||||
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
||||
is_loaded: BoolProperty(name="Is Loaded", default=False)
|
||||
is_editing: IntProperty(name="Is Editing", default=0)
|
||||
zones: CollectionProperty(name="Zones", type=Zone)
|
||||
active_zone_index: IntProperty(name="Active Zone Index")
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
# 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/>.
|
||||
|
||||
from blenderbim.bim.helper import prop_with_search
|
||||
import blenderbim.bim.helper
|
||||
import blenderbim.tool as tool
|
||||
from blenderbim.bim.helper import prop_with_search
|
||||
from bpy.types import Panel, UIList
|
||||
from blenderbim.bim.ifc import IfcStore
|
||||
from blenderbim.bim.module.system.data import SystemData, ObjectSystemData, PortData
|
||||
from blenderbim.bim.module.system.data import SystemData, ZonesData, ActiveObjectZonesData, ObjectSystemData, PortData
|
||||
|
||||
|
||||
FLOW_DIRECTION_TO_ICON = {
|
||||
@@ -42,7 +42,7 @@ class BIM_PT_systems(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return IfcStore.get_file()
|
||||
return tool.Ifc.get()
|
||||
|
||||
def draw(self, context):
|
||||
if not SystemData.is_loaded:
|
||||
@@ -95,7 +95,7 @@ class BIM_PT_object_systems(Panel):
|
||||
def poll(cls, context):
|
||||
if not context.active_object:
|
||||
return False
|
||||
return IfcStore.get_file() and context.active_object.BIMObjectProperties.ifc_definition_id
|
||||
return tool.Ifc.get() and context.active_object.BIMObjectProperties.ifc_definition_id
|
||||
|
||||
def draw(self, context):
|
||||
if not ObjectSystemData.is_loaded:
|
||||
@@ -294,6 +294,78 @@ class BIM_PT_port(Panel):
|
||||
).direction = flow_direction
|
||||
|
||||
|
||||
class BIM_PT_zones(Panel):
|
||||
bl_label = "Zones"
|
||||
bl_idname = "BIM_PT_zones"
|
||||
bl_options = {"HIDE_HEADER"}
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "scene"
|
||||
bl_parent_id = "BIM_PT_tab_zones"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
def draw(self, context):
|
||||
if not ZonesData.is_loaded:
|
||||
ZonesData.load()
|
||||
self.props = context.scene.BIMZoneProperties
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="{} Zones Found".format(ZonesData.data["total_zones"]), icon="SEQ_STRIP_META")
|
||||
if not self.props.is_loaded:
|
||||
row.operator("bim.load_zones", text="", icon="GREASEPENCIL")
|
||||
return
|
||||
|
||||
row.operator("bim.add_zone", text="", icon="ADD")
|
||||
row.operator("bim.unload_zones", text="", icon="CANCEL")
|
||||
|
||||
if self.props.zones and self.props.active_zone_index < len(self.props.zones):
|
||||
row = self.layout.row(align=True)
|
||||
ifc_definition_id = self.props.zones[self.props.active_zone_index].ifc_definition_id
|
||||
row.operator("bim.enable_editing_zone", text="Edit Zone", icon="GREASEPENCIL").zone = ifc_definition_id
|
||||
row.operator("bim.select_system_products", text="", icon="RESTRICT_SELECT_OFF").system = ifc_definition_id
|
||||
row.operator("bim.assign_system", text="", icon="KEYFRAME_HLT").system = ifc_definition_id
|
||||
row.operator("bim.unassign_system", text="", icon="KEYFRAME").system = ifc_definition_id
|
||||
row.operator("bim.remove_zone", text="", icon="X").zone = ifc_definition_id
|
||||
|
||||
self.layout.template_list("BIM_UL_zones", "", self.props, "zones", self.props, "active_zone_index")
|
||||
|
||||
if self.props.is_editing:
|
||||
blenderbim.bim.helper.draw_attributes(self.props.attributes, self.layout)
|
||||
row = self.layout.row(align=True)
|
||||
row.operator("bim.edit_zone", icon="CHECKMARK")
|
||||
row.operator("bim.disable_editing_zone", icon="CANCEL", text="")
|
||||
|
||||
|
||||
class BIM_PT_active_object_zones(Panel):
|
||||
bl_label = "Active Object Zones"
|
||||
bl_idname = "BIM_PT_active_object_zones"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "scene"
|
||||
bl_parent_id = "BIM_PT_tab_zones"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get() and context.active_object and tool.Ifc.get_entity(context.active_object)
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
if not ActiveObjectZonesData.is_loaded:
|
||||
ActiveObjectZonesData.load()
|
||||
self.props = context.scene.BIMZoneProperties
|
||||
|
||||
for zone in ActiveObjectZonesData.data["zones"]:
|
||||
row = self.layout.row()
|
||||
row.label(text=zone, icon="SEQ_STRIP_META")
|
||||
|
||||
if not ActiveObjectZonesData.data["zones"]:
|
||||
row = self.layout.row()
|
||||
row.label(text="Active Object Has No Zones")
|
||||
|
||||
|
||||
class BIM_UL_systems(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
system_icons = {
|
||||
@@ -341,3 +413,10 @@ class BIM_UL_object_systems(UIList):
|
||||
row = layout.row(align=True)
|
||||
row.label(text=item.name, icon=system_icons[item.ifc_class])
|
||||
row.operator("bim.assign_system", text="", icon="ADD").system = item.ifc_definition_id
|
||||
|
||||
|
||||
class BIM_UL_zones(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||
if item:
|
||||
row = layout.row(align=True)
|
||||
row.label(text=item.name)
|
||||
|
||||
@@ -495,6 +495,20 @@ class BIM_PT_tab_services(Panel):
|
||||
pass
|
||||
|
||||
|
||||
class BIM_PT_tab_zones(Panel):
|
||||
bl_label = "Zones"
|
||||
bl_space_type = "PROPERTIES"
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "scene"
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Blender.is_tab(context, "SERVICES") and tool.Ifc.get()
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
|
||||
|
||||
class BIM_PT_tab_quality_control(Panel):
|
||||
bl_label = "Quality Control"
|
||||
bl_space_type = "PROPERTIES"
|
||||
|
||||
Reference in New Issue
Block a user