mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-29 00:03:17 +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
|
# Services and systems
|
||||||
ui.BIM_PT_tab_services,
|
ui.BIM_PT_tab_services,
|
||||||
ui.BIM_PT_tab_services_object,
|
ui.BIM_PT_tab_services_object,
|
||||||
|
ui.BIM_PT_tab_zones,
|
||||||
# Structural analysis
|
# Structural analysis
|
||||||
ui.BIM_PT_tab_structural,
|
ui.BIM_PT_tab_structural,
|
||||||
# Construction scheduling
|
# Construction scheduling
|
||||||
|
|||||||
@@ -22,38 +22,52 @@ from . import ui, prop, operator, decorator
|
|||||||
classes = (
|
classes = (
|
||||||
operator.AddPort,
|
operator.AddPort,
|
||||||
operator.AddSystem,
|
operator.AddSystem,
|
||||||
|
operator.AddZone,
|
||||||
operator.AssignSystem,
|
operator.AssignSystem,
|
||||||
operator.ConnectPort,
|
operator.ConnectPort,
|
||||||
operator.DisableEditingSystem,
|
operator.DisableEditingSystem,
|
||||||
|
operator.DisableEditingZone,
|
||||||
operator.DisableSystemEditingUI,
|
operator.DisableSystemEditingUI,
|
||||||
operator.DisconnectPort,
|
operator.DisconnectPort,
|
||||||
operator.EditSystem,
|
operator.EditSystem,
|
||||||
|
operator.EditZone,
|
||||||
operator.EnableEditingSystem,
|
operator.EnableEditingSystem,
|
||||||
|
operator.EnableEditingZone,
|
||||||
operator.HidePorts,
|
operator.HidePorts,
|
||||||
operator.LoadSystems,
|
operator.LoadSystems,
|
||||||
|
operator.LoadZones,
|
||||||
|
operator.MEPConnectElements,
|
||||||
operator.RemovePort,
|
operator.RemovePort,
|
||||||
operator.RemoveSystem,
|
operator.RemoveSystem,
|
||||||
|
operator.RemoveZone,
|
||||||
operator.SelectSystemProducts,
|
operator.SelectSystemProducts,
|
||||||
operator.MEPConnectElements,
|
|
||||||
operator.SetFlowDirection,
|
operator.SetFlowDirection,
|
||||||
operator.ShowPorts,
|
operator.ShowPorts,
|
||||||
operator.UnassignSystem,
|
operator.UnassignSystem,
|
||||||
|
operator.UnloadZones,
|
||||||
prop.System,
|
prop.System,
|
||||||
|
prop.Zone,
|
||||||
prop.BIMSystemProperties,
|
prop.BIMSystemProperties,
|
||||||
|
prop.BIMZoneProperties,
|
||||||
ui.BIM_PT_systems,
|
ui.BIM_PT_systems,
|
||||||
ui.BIM_PT_object_systems,
|
ui.BIM_PT_object_systems,
|
||||||
|
ui.BIM_PT_zones,
|
||||||
|
ui.BIM_PT_active_object_zones,
|
||||||
ui.BIM_PT_ports,
|
ui.BIM_PT_ports,
|
||||||
ui.BIM_PT_port,
|
ui.BIM_PT_port,
|
||||||
ui.BIM_UL_systems,
|
ui.BIM_UL_systems,
|
||||||
ui.BIM_UL_object_systems,
|
ui.BIM_UL_object_systems,
|
||||||
|
ui.BIM_UL_zones,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
bpy.types.Scene.BIMSystemProperties = bpy.props.PointerProperty(type=prop.BIMSystemProperties)
|
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)
|
bpy.app.handlers.load_post.append(decorator.toggle_decorations_on_load)
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
del bpy.types.Scene.BIMSystemProperties
|
del bpy.types.Scene.BIMSystemProperties
|
||||||
|
del bpy.types.Scene.BIMZoneProperties
|
||||||
bpy.app.handlers.load_post.remove(decorator.toggle_decorations_on_load)
|
bpy.app.handlers.load_post.remove(decorator.toggle_decorations_on_load)
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import blenderbim.tool as tool
|
|||||||
|
|
||||||
def refresh():
|
def refresh():
|
||||||
SystemData.is_loaded = False
|
SystemData.is_loaded = False
|
||||||
|
ZonesData.is_loaded = False
|
||||||
|
ActiveObjectZonesData.is_loaded = False
|
||||||
ObjectSystemData.is_loaded = False
|
ObjectSystemData.is_loaded = False
|
||||||
PortData.is_loaded = False
|
PortData.is_loaded = False
|
||||||
SystemDecorationData.is_loaded = False
|
SystemDecorationData.is_loaded = False
|
||||||
@@ -47,8 +49,6 @@ class SystemData:
|
|||||||
declaration = tool.Ifc.schema().declaration_by_name("IfcSystem")
|
declaration = tool.Ifc.schema().declaration_by_name("IfcSystem")
|
||||||
declarations = ifcopenshell.util.schema.get_subtypes(declaration)
|
declarations = ifcopenshell.util.schema.get_subtypes(declaration)
|
||||||
version = tool.Ifc.get_schema()
|
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.
|
# We're only interested in systems for services. Not sure why IFC groups these together.
|
||||||
return [
|
return [
|
||||||
@@ -193,3 +193,32 @@ class SystemDecorationData:
|
|||||||
ports_data.append(port_data)
|
ports_data.append(port_data)
|
||||||
cls.elements_ports_positions[element] = ports_data
|
cls.elements_ports_positions[element] = ports_data
|
||||||
return cls.elements_ports_positions[element]
|
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.tool as tool
|
||||||
import blenderbim.core.system as core
|
import blenderbim.core.system as core
|
||||||
import blenderbim.bim.handler
|
import blenderbim.bim.handler
|
||||||
|
import blenderbim.bim.helper
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from blenderbim.bim.module.system.data import PortData
|
from blenderbim.bim.module.system.data import PortData
|
||||||
from mathutils import Matrix
|
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")
|
self.report({"ERROR"}, "Selected elements are not connected to set the flow direction")
|
||||||
return {"CANCELLED"}
|
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")
|
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):
|
def toggle_decorations(self, context):
|
||||||
toggle = self.should_draw_decorations
|
toggle = self.should_draw_decorations
|
||||||
if toggle:
|
if toggle:
|
||||||
@@ -64,3 +69,11 @@ class BIMSystemProperties(PropertyGroup):
|
|||||||
should_draw_decorations: BoolProperty(
|
should_draw_decorations: BoolProperty(
|
||||||
name="Should Draw Decorations", description="Toggle system decorations", update=toggle_decorations
|
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
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from blenderbim.bim.helper import prop_with_search
|
import blenderbim.bim.helper
|
||||||
import blenderbim.tool as tool
|
import blenderbim.tool as tool
|
||||||
|
from blenderbim.bim.helper import prop_with_search
|
||||||
from bpy.types import Panel, UIList
|
from bpy.types import Panel, UIList
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.module.system.data import SystemData, ZonesData, ActiveObjectZonesData, ObjectSystemData, PortData
|
||||||
from blenderbim.bim.module.system.data import SystemData, ObjectSystemData, PortData
|
|
||||||
|
|
||||||
|
|
||||||
FLOW_DIRECTION_TO_ICON = {
|
FLOW_DIRECTION_TO_ICON = {
|
||||||
@@ -42,7 +42,7 @@ class BIM_PT_systems(Panel):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
return IfcStore.get_file()
|
return tool.Ifc.get()
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
if not SystemData.is_loaded:
|
if not SystemData.is_loaded:
|
||||||
@@ -95,7 +95,7 @@ class BIM_PT_object_systems(Panel):
|
|||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
if not context.active_object:
|
if not context.active_object:
|
||||||
return False
|
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):
|
def draw(self, context):
|
||||||
if not ObjectSystemData.is_loaded:
|
if not ObjectSystemData.is_loaded:
|
||||||
@@ -294,6 +294,78 @@ class BIM_PT_port(Panel):
|
|||||||
).direction = flow_direction
|
).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):
|
class BIM_UL_systems(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||||
system_icons = {
|
system_icons = {
|
||||||
@@ -341,3 +413,10 @@ class BIM_UL_object_systems(UIList):
|
|||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
row.label(text=item.name, icon=system_icons[item.ifc_class])
|
row.label(text=item.name, icon=system_icons[item.ifc_class])
|
||||||
row.operator("bim.assign_system", text="", icon="ADD").system = item.ifc_definition_id
|
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
|
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):
|
class BIM_PT_tab_quality_control(Panel):
|
||||||
bl_label = "Quality Control"
|
bl_label = "Quality Control"
|
||||||
bl_space_type = "PROPERTIES"
|
bl_space_type = "PROPERTIES"
|
||||||
|
|||||||
Reference in New Issue
Block a user