mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 14:41:25 +00:00
This commit is contained in:
@@ -61,6 +61,7 @@ classes = (
|
|||||||
operator.EnableEditingAssignedProduct,
|
operator.EnableEditingAssignedProduct,
|
||||||
operator.EnableEditingElementFilter,
|
operator.EnableEditingElementFilter,
|
||||||
operator.EnableEditingText,
|
operator.EnableEditingText,
|
||||||
|
operator.ExcludeAnnotation,
|
||||||
operator.ExpandSheet,
|
operator.ExpandSheet,
|
||||||
operator.LoadDrawings,
|
operator.LoadDrawings,
|
||||||
operator.LoadReferences,
|
operator.LoadReferences,
|
||||||
|
|||||||
@@ -3757,3 +3757,19 @@ class OpenDocumentationWebUi(bpy.types.Operator):
|
|||||||
else:
|
else:
|
||||||
bpy.ops.bim.open_web_browser(page="documentation")
|
bpy.ops.bim.open_web_browser(page="documentation")
|
||||||
return {"FINISHED"}
|
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"
|
text = "Exclude Filter" if ElementFiltersData.data["has_exclude_filter"] else "No Exclude Filter Found"
|
||||||
icon = "GREASEPENCIL" if ElementFiltersData.data["has_exclude_filter"] else "ADD"
|
icon = "GREASEPENCIL" if ElementFiltersData.data["has_exclude_filter"] else "ADD"
|
||||||
row.label(text=text, icon="FILTER")
|
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"
|
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
|
is_batch = total_elements > 500000 and total_polygons > 2000
|
||||||
return is_batch
|
return is_batch
|
||||||
|
|
||||||
|
|
||||||
class OverrideDelete(bpy.types.Operator):
|
class OverrideDelete(bpy.types.Operator):
|
||||||
bl_idname = "bim.override_object_delete"
|
bl_idname = "bim.override_object_delete"
|
||||||
bl_label = "IFC Delete"
|
bl_label = "IFC Delete"
|
||||||
@@ -895,6 +896,9 @@ class OverrideDelete(bpy.types.Operator):
|
|||||||
{"INFO"}, "The last grid axis of a grid cannot be deleted. Delete the grid instead."
|
{"INFO"}, "The last grid axis of a grid cannot be deleted. Delete the grid instead."
|
||||||
)
|
)
|
||||||
continue
|
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)
|
tool.Geometry.delete_ifc_object(obj)
|
||||||
elif tool.Geometry.is_representation_item(obj):
|
elif tool.Geometry.is_representation_item(obj):
|
||||||
tool.Geometry.delete_ifc_item(obj)
|
tool.Geometry.delete_ifc_item(obj)
|
||||||
@@ -972,10 +976,12 @@ class OverrideDelete(bpy.types.Operator):
|
|||||||
# Show info message if aggregates were deleted
|
# Show info message if aggregates were deleted
|
||||||
if deleted_aggregates:
|
if deleted_aggregates:
|
||||||
if len(deleted_aggregates) == 1:
|
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:
|
else:
|
||||||
aggregate_list = ", ".join(f"'{name}'" for name in deleted_aggregates)
|
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:
|
def process_arrays(self, context: bpy.types.Context) -> None:
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
@@ -1002,6 +1008,7 @@ class OverrideDelete(bpy.types.Operator):
|
|||||||
else:
|
else:
|
||||||
break # allows to remove only n last layers of an array
|
break # allows to remove only n last layers of an array
|
||||||
|
|
||||||
|
|
||||||
class SelectedIdsData(NamedTuple):
|
class SelectedIdsData(NamedTuple):
|
||||||
objects: set[bpy.types.Object]
|
objects: set[bpy.types.Object]
|
||||||
collections: set[bpy.types.Collection]
|
collections: set[bpy.types.Collection]
|
||||||
|
|||||||
@@ -476,7 +476,17 @@ def sync_references(
|
|||||||
return
|
return
|
||||||
|
|
||||||
group = drawing_tool.get_drawing_group(drawing)
|
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)
|
reference_obj = ifc.get_object(reference_element)
|
||||||
annotation = drawing_tool.get_drawing_reference_annotation(drawing, 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()):
|
for axis in element.UAxes + element.VAxes + (element.WAxes or tuple()):
|
||||||
if axis in existing_references:
|
if axis in existing_references:
|
||||||
continue
|
continue
|
||||||
elements.append(element)
|
elements.append(axis)
|
||||||
target_view = tool.Drawing.get_drawing_target_view(drawing)
|
target_view = tool.Drawing.get_drawing_target_view(drawing)
|
||||||
if target_view in ("SECTION_VIEW", "ELEVATION_VIEW"):
|
if target_view in ("SECTION_VIEW", "ELEVATION_VIEW"):
|
||||||
for element in tool.Ifc.get().by_type("IfcBuildingStorey"):
|
for element in tool.Ifc.get().by_type("IfcBuildingStorey"):
|
||||||
|
if element in existing_references:
|
||||||
|
continue
|
||||||
elements.append(element)
|
elements.append(element)
|
||||||
return elements
|
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
|
@classmethod
|
||||||
def get_drawing_reference_annotation(
|
def get_drawing_reference_annotation(
|
||||||
cls, drawing: ifcopenshell.entity_instance, reference_element: ifcopenshell.entity_instance
|
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:
|
def hide_all_drawing_collections(cls) -> None:
|
||||||
for element in tool.Ifc.get().by_type("IfcAnnotation"):
|
for element in tool.Ifc.get().by_type("IfcAnnotation"):
|
||||||
if element.ObjectType == "DRAWING" and (obj := tool.Ifc.get_object(element)):
|
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
|
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"):
|
elif element.is_a("IfcAnnotation"):
|
||||||
if element.ObjectType == "DRAWING":
|
if element.ObjectType == "DRAWING":
|
||||||
return bonsai.core.drawing.remove_drawing(tool.Ifc, tool.Drawing, drawing=element)
|
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)):
|
elif tool.Drawing.is_auto_annotation(element):
|
||||||
tool.Drawing.exclude_annotation_from_drawing(referenced_element, drawing)
|
return # For now, these are special referenced objects and cannot be deleted. Exclude instead.
|
||||||
elif element.is_a("IfcRelSpaceBoundary"):
|
elif element.is_a("IfcRelSpaceBoundary"):
|
||||||
ifcopenshell.api.boundary.remove_boundary(ifc_file, boundary=element)
|
ifcopenshell.api.boundary.remove_boundary(ifc_file, boundary=element)
|
||||||
tool.Boundary.undecorate_boundary(obj)
|
tool.Boundary.undecorate_boundary(obj)
|
||||||
|
|||||||
Reference in New Issue
Block a user