mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
This commit is contained in:
@@ -61,6 +61,7 @@ classes = (
|
||||
operator.EnableEditingAssignedProduct,
|
||||
operator.EnableEditingElementFilter,
|
||||
operator.EnableEditingText,
|
||||
operator.ExcludeAnnotation,
|
||||
operator.ExpandSheet,
|
||||
operator.LoadDrawings,
|
||||
operator.LoadReferences,
|
||||
|
||||
@@ -3757,3 +3757,19 @@ class OpenDocumentationWebUi(bpy.types.Operator):
|
||||
else:
|
||||
bpy.ops.bim.open_web_browser(page="documentation")
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class ExcludeAnnotation(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.exclude_annotation"
|
||||
bl_label = "Exclude Annotation"
|
||||
bl_description = "Excludes the automatic annotation reference from the drawing"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
if not (obj := bpy.context.scene.camera) or not (drawing := tool.Ifc.get_entity(obj)):
|
||||
return
|
||||
for obj in tool.Blender.get_selected_objects(include_active=False):
|
||||
if (element := tool.Ifc.get_entity(obj)) and tool.Drawing.is_auto_annotation(element):
|
||||
if (referenced_element := tool.Drawing.get_annotation_element(element)):
|
||||
tool.Drawing.exclude_annotation_from_drawing(referenced_element, drawing)
|
||||
core.sync_references(tool.Ifc, tool.Collector, tool.Drawing, drawing=drawing)
|
||||
|
||||
@@ -194,6 +194,7 @@ class BIM_PT_element_filters(Panel):
|
||||
text = "Exclude Filter" if ElementFiltersData.data["has_exclude_filter"] else "No Exclude Filter Found"
|
||||
icon = "GREASEPENCIL" if ElementFiltersData.data["has_exclude_filter"] else "ADD"
|
||||
row.label(text=text, icon="FILTER")
|
||||
row.operator("bim.exclude_annotation", icon="REMOVE", text="")
|
||||
row.operator("bim.enable_editing_element_filter", icon=icon, text="").filter_mode = "EXCLUDE"
|
||||
|
||||
|
||||
|
||||
@@ -787,6 +787,7 @@ def calc_delete_is_batch(ifc_file: ifcopenshell.file, context: bpy.types.Context
|
||||
is_batch = total_elements > 500000 and total_polygons > 2000
|
||||
return is_batch
|
||||
|
||||
|
||||
class OverrideDelete(bpy.types.Operator):
|
||||
bl_idname = "bim.override_object_delete"
|
||||
bl_label = "IFC Delete"
|
||||
@@ -857,10 +858,10 @@ class OverrideDelete(bpy.types.Operator):
|
||||
objects_to_remove = context.selected_objects
|
||||
|
||||
self.process_arrays(context)
|
||||
|
||||
|
||||
# Track aggregates before deleting their parts
|
||||
aggregates_to_check = self.track_aggregates(objects_to_remove)
|
||||
|
||||
|
||||
clear_active_object = True
|
||||
|
||||
for i, obj in enumerate(objects_to_remove, 1):
|
||||
@@ -895,6 +896,9 @@ class OverrideDelete(bpy.types.Operator):
|
||||
{"INFO"}, "The last grid axis of a grid cannot be deleted. Delete the grid instead."
|
||||
)
|
||||
continue
|
||||
if tool.Drawing.is_auto_annotation(element):
|
||||
self.report({"INFO"}, "References cannot be deleted. Exclude the referenced element instead.")
|
||||
continue
|
||||
tool.Geometry.delete_ifc_object(obj)
|
||||
elif tool.Geometry.is_representation_item(obj):
|
||||
tool.Geometry.delete_ifc_item(obj)
|
||||
@@ -959,23 +963,25 @@ class OverrideDelete(bpy.types.Operator):
|
||||
aggregate.id()
|
||||
except:
|
||||
continue
|
||||
|
||||
|
||||
related_objects = ifcopenshell.util.element.get_parts(aggregate)
|
||||
if len(related_objects) == 0:
|
||||
aggregate_name = aggregate.Name or f"{aggregate.is_a()} #{aggregate.id()}"
|
||||
deleted_aggregates.append(aggregate_name)
|
||||
|
||||
|
||||
aggregate_obj = tool.Ifc.get_object(aggregate)
|
||||
if aggregate_obj and tool.Blender.is_valid_data_block(aggregate_obj):
|
||||
tool.Geometry.delete_ifc_object(aggregate_obj)
|
||||
|
||||
|
||||
# Show info message if aggregates were deleted
|
||||
if deleted_aggregates:
|
||||
if len(deleted_aggregates) == 1:
|
||||
self.report({'INFO'}, f"Aggregate '{deleted_aggregates[0]}' was deleted because it had no remaining parts")
|
||||
self.report(
|
||||
{"INFO"}, f"Aggregate '{deleted_aggregates[0]}' was deleted because it had no remaining parts"
|
||||
)
|
||||
else:
|
||||
aggregate_list = ", ".join(f"'{name}'" for name in deleted_aggregates)
|
||||
self.report({'INFO'}, f"Aggregates {aggregate_list} were deleted because they had no remaining parts")
|
||||
self.report({"INFO"}, f"Aggregates {aggregate_list} were deleted because they had no remaining parts")
|
||||
|
||||
def process_arrays(self, context: bpy.types.Context) -> None:
|
||||
ifc_file = tool.Ifc.get()
|
||||
@@ -1002,6 +1008,7 @@ class OverrideDelete(bpy.types.Operator):
|
||||
else:
|
||||
break # allows to remove only n last layers of an array
|
||||
|
||||
|
||||
class SelectedIdsData(NamedTuple):
|
||||
objects: set[bpy.types.Object]
|
||||
collections: set[bpy.types.Collection]
|
||||
|
||||
@@ -476,7 +476,17 @@ def sync_references(
|
||||
return
|
||||
|
||||
group = drawing_tool.get_drawing_group(drawing)
|
||||
for reference_element in drawing_tool.get_potential_reference_elements(drawing):
|
||||
potential_reference_elements = drawing_tool.get_potential_reference_elements(drawing)
|
||||
for element in drawing_tool.get_group_elements(group):
|
||||
if (
|
||||
drawing_tool.is_auto_annotation(element)
|
||||
and drawing_tool.get_assigned_product(element) not in potential_reference_elements
|
||||
):
|
||||
if obj := ifc.get_object(element):
|
||||
drawing_tool.delete_object(obj)
|
||||
ifc.run("root.remove_product", product=element)
|
||||
|
||||
for reference_element in potential_reference_elements:
|
||||
reference_obj = ifc.get_object(reference_element)
|
||||
annotation = drawing_tool.get_drawing_reference_annotation(drawing, reference_element)
|
||||
|
||||
|
||||
@@ -1488,13 +1488,19 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
for axis in element.UAxes + element.VAxes + (element.WAxes or tuple()):
|
||||
if axis in existing_references:
|
||||
continue
|
||||
elements.append(element)
|
||||
elements.append(axis)
|
||||
target_view = tool.Drawing.get_drawing_target_view(drawing)
|
||||
if target_view in ("SECTION_VIEW", "ELEVATION_VIEW"):
|
||||
for element in tool.Ifc.get().by_type("IfcBuildingStorey"):
|
||||
if element in existing_references:
|
||||
continue
|
||||
elements.append(element)
|
||||
return elements
|
||||
|
||||
@classmethod
|
||||
def is_auto_annotation(cls, element: ifcopenshell.entity_instance):
|
||||
return element.is_a("IfcAnnotation") and element.ObjectType in ("GRID", "SECTION", "ELEVATION", "SECTION_LEVEL")
|
||||
|
||||
@classmethod
|
||||
def get_drawing_reference_annotation(
|
||||
cls, drawing: ifcopenshell.entity_instance, reference_element: ifcopenshell.entity_instance
|
||||
@@ -2649,5 +2655,4 @@ class Drawing(bonsai.core.tool.Drawing):
|
||||
def hide_all_drawing_collections(cls) -> None:
|
||||
for element in tool.Ifc.get().by_type("IfcAnnotation"):
|
||||
if element.ObjectType == "DRAWING" and (obj := tool.Ifc.get_object(element)):
|
||||
print('found element', element)
|
||||
tool.Blender.get_layer_collection(obj.users_collection[0]).hide_viewport = True
|
||||
|
||||
@@ -236,8 +236,8 @@ class Geometry(bonsai.core.tool.Geometry):
|
||||
elif element.is_a("IfcAnnotation"):
|
||||
if element.ObjectType == "DRAWING":
|
||||
return bonsai.core.drawing.remove_drawing(tool.Ifc, tool.Drawing, drawing=element)
|
||||
elif (referenced_element := tool.Drawing.get_annotation_element(element)) and (drawing := tool.Drawing.get_annotation_drawing(element)):
|
||||
tool.Drawing.exclude_annotation_from_drawing(referenced_element, drawing)
|
||||
elif tool.Drawing.is_auto_annotation(element):
|
||||
return # For now, these are special referenced objects and cannot be deleted. Exclude instead.
|
||||
elif element.is_a("IfcRelSpaceBoundary"):
|
||||
ifcopenshell.api.boundary.remove_boundary(ifc_file, boundary=element)
|
||||
tool.Boundary.undecorate_boundary(obj)
|
||||
|
||||
Reference in New Issue
Block a user