mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Allow selecting a container object when changing spatial container
This commit is contained in:
@@ -83,7 +83,8 @@ class AssignContainer(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
if container := tool.Root.get_default_container():
|
||||
props = context.active_object.BIMObjectSpatialProperties
|
||||
if (container_obj := props.container_obj) and (container := tool.Ifc.get_entity(container_obj)):
|
||||
for element_obj in context.selected_objects:
|
||||
core.assign_container(
|
||||
tool.Ifc, tool.Collector, tool.Spatial, container=container, element_obj=element_obj
|
||||
|
||||
@@ -64,34 +64,32 @@ def update_should_include_children(self, context):
|
||||
tool.Spatial.load_contained_elements()
|
||||
|
||||
|
||||
def update_relating_container_from_object(self, context):
|
||||
if self.relating_container_object is None or context.active_object is None:
|
||||
def update_container_obj(self, context):
|
||||
if self.container_obj is None or not (obj := context.active_object):
|
||||
return
|
||||
element = tool.Ifc.get_entity(self.relating_container_object)
|
||||
if not element:
|
||||
if not (element := tool.Ifc.get_entity(self.container_obj)):
|
||||
self.container_obj = None
|
||||
return
|
||||
container = ifcopenshell.util.element.get_container(element)
|
||||
if container:
|
||||
# TODO: currently broken and relating_container_object is not used in UI.
|
||||
bpy.ops.bim.assign_container(structure=container.id())
|
||||
else:
|
||||
bpy.ops.bim.disable_editing_container()
|
||||
bpy.ops.bim.remove_container()
|
||||
if tool.Spatial.can_contain(element, obj):
|
||||
return
|
||||
if (
|
||||
(container := ifcopenshell.util.element.get_container(element))
|
||||
and (container_obj := tool.Ifc.get_object(container))
|
||||
and tool.Spatial.can_contain(container, obj)
|
||||
):
|
||||
self.container_obj = container_obj
|
||||
return
|
||||
self.container_obj = None
|
||||
|
||||
|
||||
def is_object_applicable(self, obj):
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
return bool(element)
|
||||
def poll_container_obj(self, obj):
|
||||
return obj is None or tool.Ifc.get_entity(obj)
|
||||
|
||||
|
||||
class BIMObjectSpatialProperties(PropertyGroup):
|
||||
is_editing: BoolProperty(name="Is Editing")
|
||||
relating_container_object: PointerProperty(
|
||||
type=bpy.types.Object,
|
||||
name="Copy Container",
|
||||
update=update_relating_container_from_object,
|
||||
poll=is_object_applicable,
|
||||
description="Copy the target object's container to the active object",
|
||||
container_obj: PointerProperty(
|
||||
type=bpy.types.Object, name="Container", update=update_container_obj, poll=poll_container_obj
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -36,10 +36,6 @@ class BIM_PT_spatial(Panel):
|
||||
return SpatialData.data["poll"]
|
||||
|
||||
def draw(self, context):
|
||||
# TODO: expose relating_container_object so users could
|
||||
# assign container without switching default container back and forth
|
||||
# just for 1 operation.
|
||||
|
||||
if not SpatialData.is_loaded:
|
||||
SpatialData.load()
|
||||
|
||||
@@ -48,8 +44,8 @@ class BIM_PT_spatial(Panel):
|
||||
if osprops.is_editing:
|
||||
if SpatialData.data["default_container"]:
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=f"Target: {SpatialData.data['default_container']}", icon="OUTLINER_COLLECTION")
|
||||
row.operator("bim.assign_container", icon="CHECKMARK", text="Reassign Container")
|
||||
row.prop(osprops, "container_obj", text="", icon="OUTLINER_COLLECTION")
|
||||
row.operator("bim.assign_container", icon="CHECKMARK", text="")
|
||||
row.operator("bim.disable_editing_container", icon="CANCEL", text="")
|
||||
|
||||
if SpatialData.data["selected_containers"]:
|
||||
@@ -82,14 +78,14 @@ class BIM_PT_spatial(Panel):
|
||||
row.label(text="No Spatial Container")
|
||||
row.operator("bim.enable_editing_container", icon="GREASEPENCIL", text="")
|
||||
|
||||
references = SpatialData.data["references"]
|
||||
if references:
|
||||
self.layout.label(text="Referenced In Structures:")
|
||||
if references := SpatialData.data["references"]:
|
||||
self.layout.label(text=f"{len(references)} References:")
|
||||
else:
|
||||
self.layout.label(text="No References Found")
|
||||
|
||||
for reference in references:
|
||||
row = self.layout.row()
|
||||
row.label(text=reference, icon="LINKED")
|
||||
else:
|
||||
self.layout.label(text="No References In Structures")
|
||||
|
||||
|
||||
class BIM_PT_spatial_decomposition(Panel):
|
||||
|
||||
@@ -62,6 +62,7 @@ def assign_container(
|
||||
|
||||
|
||||
def enable_editing_container(spatial: tool.Spatial, obj: bpy.types.Object) -> None:
|
||||
spatial.set_target_container_as_default()
|
||||
spatial.enable_editing(obj)
|
||||
|
||||
|
||||
|
||||
@@ -887,3 +887,13 @@ class Spatial(blenderbim.core.tool.Spatial):
|
||||
if (element := tool.Ifc.get_entity(obj)) and not tool.Root.is_spatial_element(element):
|
||||
results.append(obj)
|
||||
return results
|
||||
|
||||
@classmethod
|
||||
def set_target_container_as_default(cls) -> None:
|
||||
if (
|
||||
(container := tool.Root.get_default_container())
|
||||
and (obj := tool.Ifc.get_object(container))
|
||||
and bpy.context.active_object
|
||||
):
|
||||
props = bpy.context.active_object.BIMObjectSpatialProperties
|
||||
props.container_obj = obj
|
||||
|
||||
Reference in New Issue
Block a user