Implement show / hide / isolate in spatial decomposition panel

This commit is contained in:
Dion Moult
2024-07-16 14:23:30 +10:00
parent 83085ba3c1
commit 483516a902
3 changed files with 59 additions and 4 deletions
@@ -37,6 +37,7 @@ classes = (
operator.SelectDecomposedElements,
operator.SelectProduct,
operator.SelectSimilarContainer,
operator.SetContainerVisibility,
operator.SetDefaultContainer,
prop.SpatialElement,
prop.Element,
@@ -17,6 +17,7 @@
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
import bpy
import ifcopenshell.util.element
import blenderbim.tool as tool
import blenderbim.core.spatial as core
import blenderbim.core.geometry
@@ -251,8 +252,55 @@ class SetDefaultContainer(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.set_default_container"
bl_label = "Set Default Container"
bl_options = {"REGISTER", "UNDO"}
container: bpy.props.IntProperty()
bl_description = "Set this as the default container that all new elements will be contained in"
container: bpy.props.IntProperty()
def _execute(self, context):
core.set_default_container(tool.Spatial, container=tool.Ifc.get().by_id(self.container))
class SetContainerVisibility(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.set_container_visibility"
bl_label = "Set Container Visibility"
bl_options = {"REGISTER", "UNDO"}
container: bpy.props.IntProperty()
should_include_children: bpy.props.BoolProperty(name="Should Include Children", default=True, options={"SKIP_SAVE"})
mode: bpy.props.StringProperty(name="Mode")
@classmethod
def description(cls, context, operator):
if operator.mode == "HIDE":
return "Hides the selected container and all children.\n" + "ALT+CLICK to ignore children"
elif operator.mode == "SHOW":
return "Shows the selected container and all children.\n" + "ALT+CLICK to ignore children"
return "Isolate the selected container and all children.\n" + "ALT+CLICK to ignore children"
def invoke(self, context, event):
if event.type == "LEFTMOUSE" and event.alt:
self.should_include_children = False
return self.execute(context)
def _execute(self, context):
if self.mode == "ISOLATE":
if tool.Ifc.get_schema() == "IFC2X3":
containers = tool.Ifc.get().by_type("IfcSpatialStructureElement")
elif tool.Ifc.get_schema() != "IFC2X3":
containers = set(tool.Ifc.get().by_type("IfcSpatialElement"))
containers -= set(tool.Ifc.get().by_type("IfcSpatialZone"))
for container in containers:
if obj := tool.Ifc.get_object(container):
if collection := obj.BIMObjectProperties.collection:
collection.hide_viewport = True
should_hide = False
else:
should_hide = self.mode == "HIDE"
container = tool.Ifc.get().by_id(self.container)
queue = [container]
while queue:
container = queue.pop()
if obj := tool.Ifc.get_object(container):
if collection := obj.BIMObjectProperties.collection:
collection.hide_viewport = should_hide
if self.should_include_children:
queue.extend(ifcopenshell.util.element.get_parts(container))
@@ -133,9 +133,15 @@ class BIM_PT_spatial_decomposition(Panel):
row.enabled = False
op = row.operator("bim.set_default_container", icon="OUTLINER_COLLECTION", text="Set Default")
op.container = ifc_definition_id
row.operator("bim.select_decomposed_elements", icon="FULLSCREEN_EXIT", text="Isolate")
row.operator("bim.select_decomposed_elements", icon="HIDE_OFF", text="")
row.operator("bim.select_decomposed_elements", icon="HIDE_ON", text="")
op = row.operator("bim.set_container_visibility", icon="FULLSCREEN_EXIT", text="Isolate")
op.mode = "ISOLATE"
op.container = ifc_definition_id
op = row.operator("bim.set_container_visibility", icon="HIDE_OFF", text="")
op.mode = "SHOW"
op.container = ifc_definition_id
op = row.operator("bim.set_container_visibility", icon="HIDE_ON", text="")
op.mode = "HIDE"
op.container = ifc_definition_id
row.operator("bim.select_container", icon="OBJECT_DATA", text="").container = ifc_definition_id
op = row.operator("bim.delete_container", icon="X", text="")
op.container = ifc_definition_id