mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
You can now lock and unlock spatial / grid elements, which affects your ability to delete or move them
This commit is contained in:
@@ -612,10 +612,11 @@ class OverrideDelete(bpy.types.Operator):
|
||||
return self.execute(context)
|
||||
|
||||
def draw(self, context):
|
||||
row = self.layout.row()
|
||||
row.label(text="Warning: Faster deletion will use more memory.", icon="ERROR")
|
||||
row = self.layout.row()
|
||||
row.prop(self, "is_batch", text="Enable Faster Deletion")
|
||||
if self.is_batch:
|
||||
row = self.layout.row()
|
||||
row.label(text="Warning: Faster deletion will use more memory.", icon="ERROR")
|
||||
|
||||
def _execute(self, context):
|
||||
start_time = time()
|
||||
@@ -627,7 +628,7 @@ class OverrideDelete(bpy.types.Operator):
|
||||
for obj in context.selected_objects:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if element:
|
||||
if tool.Geometry.is_lockable(element):
|
||||
if tool.Geometry.is_locked(element):
|
||||
continue
|
||||
if ifcopenshell.util.element.get_pset(element, "BBIM_Array"):
|
||||
self.report({"INFO"}, "Elements that are part of an array cannot be deleted.")
|
||||
@@ -736,10 +737,11 @@ class OverrideOutlinerDelete(bpy.types.Operator):
|
||||
return self.execute(context)
|
||||
|
||||
def draw(self, context):
|
||||
row = self.layout.row()
|
||||
row.label(text="Warning: Faster deletion will use more memory.", icon="ERROR")
|
||||
row = self.layout.row()
|
||||
row.prop(self, "is_batch", text="Enable Faster Deletion")
|
||||
if self.is_batch:
|
||||
row = self.layout.row()
|
||||
row.label(text="Warning: Faster deletion will use more memory.", icon="ERROR")
|
||||
|
||||
def _execute(self, context):
|
||||
if self.is_batch:
|
||||
@@ -757,7 +759,7 @@ class OverrideOutlinerDelete(bpy.types.Operator):
|
||||
objects_to_delete.add(bpy.data.objects.get(item.name))
|
||||
for obj in objects_to_delete:
|
||||
if element := tool.Ifc.get_entity(obj):
|
||||
if tool.Geometry.is_lockable(element):
|
||||
if tool.Geometry.is_locked(element):
|
||||
if collection := obj.BIMObjectProperties.collection:
|
||||
collections_to_delete.discard(collection)
|
||||
continue
|
||||
|
||||
@@ -86,6 +86,35 @@ def update_container_obj(self, context):
|
||||
self.container_obj = None
|
||||
|
||||
|
||||
def update_grid_is_locked(self, context):
|
||||
if not tool.Ifc.get():
|
||||
return
|
||||
if tool.Ifc.get().schema in ("IFC2X3", "IFC4"):
|
||||
elements = tool.Ifc.get().by_type("IfcGrid") + tool.Ifc.get().by_type("IfcGridAxis")
|
||||
else:
|
||||
elements = tool.Ifc.get().by_type("IfcPositioningElement")
|
||||
for element in elements:
|
||||
if obj := tool.Ifc.get_object(element):
|
||||
if self.is_locked:
|
||||
tool.Geometry.lock_object(obj)
|
||||
else:
|
||||
tool.Geometry.unlock_object(obj)
|
||||
|
||||
|
||||
def update_spatial_is_locked(self, context):
|
||||
if not tool.Ifc.get():
|
||||
return
|
||||
if tool.Ifc.get().schema == "IFC2X3":
|
||||
elements = tool.Ifc.get().by_type("IfcSpatialStructureElement")
|
||||
else:
|
||||
elements = tool.Ifc.get().by_type("IfcSpatialElement")
|
||||
for element in elements:
|
||||
if obj := tool.Ifc.get_object(element):
|
||||
if self.is_locked:
|
||||
tool.Geometry.lock_object(obj)
|
||||
else:
|
||||
tool.Geometry.unlock_object(obj)
|
||||
|
||||
def poll_container_obj(self, obj):
|
||||
return obj is None or tool.Ifc.get_entity(obj)
|
||||
|
||||
@@ -133,6 +162,7 @@ class Element(PropertyGroup):
|
||||
|
||||
|
||||
class BIMSpatialDecompositionProperties(PropertyGroup):
|
||||
is_locked: BoolProperty(name="Is Locked", default=True, update=update_spatial_is_locked)
|
||||
container_filter: StringProperty(name="Container Filter", default="", options={"TEXTEDIT_UPDATE"})
|
||||
containers: CollectionProperty(name="Containers", type=BIMContainer)
|
||||
contracted_containers: StringProperty(name="Contracted containers", default="[]")
|
||||
@@ -169,4 +199,5 @@ class BIMSpatialDecompositionProperties(PropertyGroup):
|
||||
|
||||
|
||||
class BIMGridProperties(PropertyGroup):
|
||||
is_locked: BoolProperty(name="Is Locked", default=True, update=update_grid_is_locked)
|
||||
grid_axes: CollectionProperty(name="Grid Axes", type=ObjProperty)
|
||||
|
||||
@@ -96,11 +96,19 @@ class BIM_PT_spatial_decomposition(Panel):
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "scene"
|
||||
bl_parent_id = "BIM_PT_tab_spatial"
|
||||
bl_options = {"HEADER_LAYOUT_EXPAND"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return tool.Ifc.get()
|
||||
|
||||
def draw_header(self, context):
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="") # empty text occupies the left of the row
|
||||
icon = "VIEW_LOCKED" if context.scene.BIMSpatialDecompositionProperties.is_locked else "VIEW_UNLOCKED"
|
||||
row.prop(context.scene.BIMSpatialDecompositionProperties, "is_locked", text="", icon=icon)
|
||||
|
||||
|
||||
def draw(self, context):
|
||||
if not SpatialDecompositionData.is_loaded:
|
||||
SpatialDecompositionData.load()
|
||||
@@ -203,10 +211,17 @@ class BIM_PT_grids(Panel):
|
||||
bl_region_type = "WINDOW"
|
||||
bl_context = "scene"
|
||||
bl_parent_id = "BIM_PT_tab_spatial"
|
||||
bl_options = {"HEADER_LAYOUT_EXPAND"}
|
||||
|
||||
def draw(self, context):
|
||||
self.layout.row().operator("mesh.add_grid", icon="ADD", text="Add Grids")
|
||||
|
||||
def draw_header(self, context):
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text="") # empty text occupies the left of the row
|
||||
icon = "VIEW_LOCKED" if context.scene.BIMGridProperties.is_locked else "VIEW_UNLOCKED"
|
||||
row.prop(context.scene.BIMGridProperties, "is_locked", text="", icon=icon)
|
||||
|
||||
|
||||
class BIM_UL_containers_manager(UIList):
|
||||
def __init__(self):
|
||||
|
||||
@@ -41,7 +41,7 @@ class Collector(bonsai.core.tool.Collector):
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
assert element
|
||||
|
||||
if tool.Geometry.is_lockable(element):
|
||||
if tool.Geometry.is_locked(element):
|
||||
tool.Geometry.lock_object(obj)
|
||||
|
||||
if element.is_a("IfcGridAxis"):
|
||||
|
||||
@@ -92,14 +92,14 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
bpy.data.meshes.remove(data)
|
||||
|
||||
@classmethod
|
||||
def is_lockable(cls, element: ifcopenshell.entity_instance) -> bool:
|
||||
if (
|
||||
element.is_a("IfcProject")
|
||||
or tool.Root.is_spatial_element(element)
|
||||
or element.is_a("IfcPositioningElement")
|
||||
or element.is_a("IfcGrid")
|
||||
or element.is_a("IfcGridAxis")
|
||||
):
|
||||
def is_locked(cls, element: ifcopenshell.entity_instance) -> bool:
|
||||
if element.is_a("IfcProject"):
|
||||
return True
|
||||
elif tool.Root.is_spatial_element(element) and bpy.context.scene.BIMSpatialDecompositionProperties.is_locked:
|
||||
return True
|
||||
elif (
|
||||
element.is_a("IfcPositioningElement") or element.is_a("IfcGrid") or element.is_a("IfcGridAxis")
|
||||
) and bpy.context.scene.BIMGridProperties.is_locked:
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -108,6 +108,11 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
obj.lock_location = (True, True, True)
|
||||
obj.lock_rotation = (True, True, True)
|
||||
|
||||
@classmethod
|
||||
def unlock_object(cls, obj: bpy.types.Object) -> None:
|
||||
obj.lock_location = (False, False, False)
|
||||
obj.lock_rotation = (False, False, False)
|
||||
|
||||
@classmethod
|
||||
def delete_ifc_object(cls, obj: bpy.types.Object) -> None:
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
|
||||
Reference in New Issue
Block a user