mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Add tool for 'group' module
This commit is contained in:
@@ -23,7 +23,6 @@ import ifcopenshell.util.element
|
||||
import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
import json
|
||||
from natsort import natsorted
|
||||
|
||||
|
||||
class LoadGroups(bpy.types.Operator, tool.Ifc.Operator):
|
||||
@@ -31,48 +30,12 @@ class LoadGroups(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_label = "Load Groups"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
expanded_groups: list[int]
|
||||
|
||||
def _execute(self, context):
|
||||
self.props = tool.Blender.get_group_props()
|
||||
self.expanded_groups = json.loads(self.props.expanded_groups_json)
|
||||
self.props.groups.clear()
|
||||
|
||||
groups = [
|
||||
group for group in tool.Ifc.get().by_type("IfcGroup", include_subtypes=False) if not group.HasAssignments
|
||||
]
|
||||
sorted_groups = natsorted(groups, key=lambda group: group.Name or "Unnamed")
|
||||
|
||||
for group in sorted_groups:
|
||||
self.load_group(group)
|
||||
|
||||
self.props.is_editing = True
|
||||
bpy.ops.bim.disable_editing_group()
|
||||
tool.Group.import_groups()
|
||||
tool.Group.enable_group_editing_ui()
|
||||
tool.Group.disable_editing_group()
|
||||
return {"FINISHED"}
|
||||
|
||||
def load_group(self, group: ifcopenshell.entity_instance, tree_depth: int = 0) -> None:
|
||||
new = self.props.groups.add()
|
||||
new.ifc_definition_id = group.id()
|
||||
new["name"] = group.Name or "Unnamed"
|
||||
new.tree_depth = tree_depth
|
||||
new.has_children = False
|
||||
new.is_expanded = group.id() in self.expanded_groups
|
||||
|
||||
related_groups: list[ifcopenshell.entity_instance]
|
||||
related_groups = [
|
||||
related_object
|
||||
for rel in group.IsGroupedBy or []
|
||||
for related_object in rel.RelatedObjects
|
||||
if related_object.is_a("IfcGroup")
|
||||
]
|
||||
sorted_related_groups = natsorted(related_groups, key=lambda group: group.Name or "Unnamed")
|
||||
|
||||
if sorted_related_groups:
|
||||
new.has_children = True
|
||||
if new.is_expanded:
|
||||
for related_group in sorted_related_groups:
|
||||
self.load_group(related_group, tree_depth=tree_depth + 1)
|
||||
|
||||
|
||||
class ToggleGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.toggle_group"
|
||||
@@ -83,7 +46,7 @@ class ToggleGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
option: bpy.props.StringProperty(name="Expand or Collapse")
|
||||
|
||||
def _execute(self, context):
|
||||
props = tool.Blender.get_group_props()
|
||||
props = tool.Group.get_group_props()
|
||||
expanded_groups: set[int]
|
||||
expanded_groups = set(json.loads(props.expanded_groups_json))
|
||||
if self.option == "Expand":
|
||||
@@ -101,9 +64,8 @@ class DisableGroupEditingUI(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = tool.Blender.get_group_props()
|
||||
props.is_editing = False
|
||||
props.active_group_id = 0
|
||||
tool.Group.disable_group_editing_ui()
|
||||
tool.Group.disable_editing_group()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -125,7 +87,7 @@ class AddGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
ifcopenshell.api.group.assign_group(
|
||||
tool.Ifc.get(), products=[result], group=tool.Ifc.get().by_id(self.group)
|
||||
)
|
||||
bpy.ops.bim.load_groups()
|
||||
tool.Group.import_groups("IfcGroup")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -135,11 +97,11 @@ class EditGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = tool.Blender.get_group_props()
|
||||
props = tool.Group.get_group_props()
|
||||
attributes = bonsai.bim.helper.export_attributes(props.group_attributes)
|
||||
ifc_file = tool.Ifc.get()
|
||||
ifcopenshell.api.group.edit_group(ifc_file, group=ifc_file.by_id(props.active_group_id), attributes=attributes)
|
||||
bpy.ops.bim.load_groups()
|
||||
tool.Group.import_groups("IfcGroup")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -152,7 +114,7 @@ class RemoveGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
def _execute(self, context):
|
||||
self.file = tool.Ifc.get()
|
||||
ifcopenshell.api.group.remove_group(self.file, group=self.file.by_id(self.group))
|
||||
bpy.ops.bim.load_groups()
|
||||
tool.Group.import_groups("IfcGroup")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -163,10 +125,11 @@ class EnableEditingGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
group: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
props = tool.Blender.get_group_props()
|
||||
props = tool.Group.get_group_props()
|
||||
props.group_attributes.clear()
|
||||
bonsai.bim.helper.import_attributes(tool.Ifc.get().by_id(self.group), props.group_attributes)
|
||||
props.active_group_id = self.group
|
||||
ifc_file = tool.Ifc.get()
|
||||
tool.Group.set_active_group_to_edit(ifc_file.by_id(self.group))
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -176,8 +139,7 @@ class DisableEditingGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = tool.Blender.get_group_props()
|
||||
props.active_group_id = 0
|
||||
tool.Group.disable_editing_group()
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class BIM_PT_groups(Panel):
|
||||
def draw(self, context):
|
||||
if not GroupsData.is_loaded:
|
||||
GroupsData.load()
|
||||
self.props = tool.Blender.get_group_props()
|
||||
self.props = tool.Group.get_group_props()
|
||||
assert self.layout
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
@@ -106,7 +106,7 @@ class BIM_PT_object_groups(Panel):
|
||||
if not ObjectGroupsData.is_loaded:
|
||||
ObjectGroupsData.load()
|
||||
assert self.layout
|
||||
self.props = tool.Blender.get_group_props()
|
||||
self.props = tool.Group.get_group_props()
|
||||
|
||||
for group in ObjectGroupsData.data["groups"]:
|
||||
row = self.layout.row(align=True)
|
||||
|
||||
@@ -269,7 +269,7 @@ class GroupQtosData(Data):
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
props = tool.Blender.get_group_props()
|
||||
props = tool.Group.get_group_props()
|
||||
assert (active_group := props.active_group)
|
||||
ifc_definition_id = active_group.ifc_definition_id
|
||||
cls.data = {"qtos": cls.psetqtos(tool.Ifc.get_entity_by_id(ifc_definition_id), qtos_only=True)}
|
||||
@@ -282,7 +282,7 @@ class GroupPsetData(Data):
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
props = tool.Blender.get_group_props()
|
||||
props = tool.Group.get_group_props()
|
||||
assert (active_group := props.active_group)
|
||||
ifc_definition_id = active_group.ifc_definition_id
|
||||
cls.data = {"psets": cls.psetqtos(tool.Ifc.get_entity_by_id(ifc_definition_id), psets_only=True)}
|
||||
|
||||
@@ -667,7 +667,7 @@ class BIM_PT_group_qtos(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = tool.Blender.get_group_props()
|
||||
props = tool.Group.get_group_props()
|
||||
return bool(props.active_group)
|
||||
|
||||
def draw(self, context):
|
||||
@@ -699,7 +699,7 @@ class BIM_PT_group_psets(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = tool.Blender.get_group_props()
|
||||
props = tool.Group.get_group_props()
|
||||
return bool(props.active_group)
|
||||
|
||||
def draw(self, context):
|
||||
|
||||
@@ -37,6 +37,7 @@ from bonsai.tool.drawing import Drawing
|
||||
from bonsai.tool.feature import Feature
|
||||
from bonsai.tool.geometry import Geometry
|
||||
from bonsai.tool.georeference import Georeference
|
||||
from bonsai.tool.group import Group
|
||||
from bonsai.tool.ifc import Ifc
|
||||
from bonsai.tool.ifcgit import IfcGit
|
||||
from bonsai.tool.ifcgit import IfcGitRepo
|
||||
|
||||
@@ -63,7 +63,6 @@ if TYPE_CHECKING:
|
||||
from bonsai.bim.module.csv.prop import CsvProperties
|
||||
from bonsai.bim.module.diff.prop import DiffProperties
|
||||
from bonsai.bim.module.fm.prop import BIMFMProperties
|
||||
from bonsai.bim.module.group.prop import BIMGroupProperties
|
||||
from bonsai.bim.module.light.prop import BIMSolarProperties, RadianceExporterProperties
|
||||
|
||||
T = TypeVar("T")
|
||||
@@ -260,7 +259,7 @@ class Blender(bonsai.core.tool.Blender):
|
||||
wsprops = tool.Sequence.get_work_schedule_props()
|
||||
return wsprops.active_work_schedule_id
|
||||
elif obj_type == "Group":
|
||||
props = tool.Blender.get_group_props()
|
||||
props = tool.Group.get_group_props()
|
||||
assert (active_group := props.active_group)
|
||||
return active_group.ifc_definition_id
|
||||
elif obj_type == "Zone":
|
||||
@@ -1778,11 +1777,6 @@ class Blender(bonsai.core.tool.Blender):
|
||||
assert (scene := bpy.context.scene)
|
||||
return scene.DiffProperties # pyright: ignore[reportAttributeAccessIssue]
|
||||
|
||||
@classmethod
|
||||
def get_group_props(cls) -> BIMGroupProperties:
|
||||
assert (scene := bpy.context.scene)
|
||||
return scene.BIMGroupProperties # pyright: ignore[reportAttributeAccessIssue]
|
||||
|
||||
@classmethod
|
||||
def get_bim_props(cls, scene: Optional[bpy.types.Scene] = None) -> BIMProperties:
|
||||
if scene is None:
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
# Bonsai - OpenBIM Blender Add-on
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of Bonsai.
|
||||
#
|
||||
# Bonsai 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.
|
||||
#
|
||||
# Bonsai 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 Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import json
|
||||
import bpy
|
||||
import ifcopenshell
|
||||
import bonsai.bim.helper
|
||||
import bonsai.core.tool
|
||||
import bonsai.tool as tool
|
||||
from typing import TYPE_CHECKING
|
||||
from natsort import natsorted
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.group.prop import BIMGroupProperties
|
||||
|
||||
|
||||
class Group(bonsai.core.tool.System):
|
||||
@classmethod
|
||||
def get_group_props(cls) -> BIMGroupProperties:
|
||||
assert (scene := bpy.context.scene)
|
||||
return scene.BIMGroupProperties # pyright: ignore[reportAttributeAccessIssue]
|
||||
|
||||
@classmethod
|
||||
def import_groups(cls) -> None:
|
||||
props = tool.Group.get_group_props()
|
||||
expanded_groups: list[int] = json.loads(props.expanded_groups_json)
|
||||
props.groups.clear()
|
||||
|
||||
groups = [
|
||||
group for group in tool.Ifc.get().by_type("IfcGroup", include_subtypes=False) if not group.HasAssignments
|
||||
]
|
||||
sorted_groups = natsorted(groups, key=lambda group: group.Name or "Unnamed")
|
||||
|
||||
def load_group(group: ifcopenshell.entity_instance, tree_depth: int = 0) -> None:
|
||||
new = props.groups.add()
|
||||
new.ifc_definition_id = group.id()
|
||||
new["name"] = group.Name or "Unnamed"
|
||||
new.tree_depth = tree_depth
|
||||
new.has_children = False
|
||||
new.is_expanded = group.id() in expanded_groups
|
||||
|
||||
related_groups: list[ifcopenshell.entity_instance]
|
||||
related_groups = [
|
||||
related_object
|
||||
for rel in group.IsGroupedBy or []
|
||||
for related_object in rel.RelatedObjects
|
||||
if related_object.is_a("IfcGroup")
|
||||
]
|
||||
sorted_related_groups = natsorted(related_groups, key=lambda group: group.Name or "Unnamed")
|
||||
|
||||
if sorted_related_groups:
|
||||
new.has_children = True
|
||||
if new.is_expanded:
|
||||
for related_group in sorted_related_groups:
|
||||
load_group(related_group, tree_depth=tree_depth + 1)
|
||||
|
||||
for group in sorted_groups:
|
||||
load_group(group)
|
||||
|
||||
@classmethod
|
||||
def enable_group_editing_ui(cls) -> None:
|
||||
props = cls.get_group_props()
|
||||
props.is_editing = True
|
||||
|
||||
@classmethod
|
||||
def disable_group_editing_ui(cls) -> None:
|
||||
props = cls.get_group_props()
|
||||
props.is_editing = False
|
||||
|
||||
@classmethod
|
||||
def disable_editing_group(cls) -> None:
|
||||
props = cls.get_group_props()
|
||||
props.active_group_id = 0
|
||||
|
||||
@classmethod
|
||||
def set_active_group_to_edit(cls, group: ifcopenshell.entity_instance) -> None:
|
||||
props = cls.get_group_props()
|
||||
props.active_group_id = group.id()
|
||||
Reference in New Issue
Block a user