Compare commits

...

2 Commits

Author SHA1 Message Date
Ryan Schultz 8634569de7 Fix #7998: Fix ExcludeFromDrawing filter corruption
In exclude_element_from_drawing, use " + " instead of "+" when
appending a GlobalId. Lark's unquoted_string regex
(/[^,.=><*!\s]+/) does not exclude '"' or '+', so
'"DEMOLISH"+GlobalId' was greedily matched as one token,
causing wrap_value to double-quote and escape the inner quotes
on the next round-trip through edit_element_filter.
Adding a space forces unquoted_string to stop at whitespace,
letting ESCAPED_STRING win the length tie on priority.

Also replace the enable_editing_element_filter +
edit_element_filter calls in ExcludeFromDrawing._execute with
a direct activate_drawing call; edit_element_filter was
unnecessarily re-exporting the pset and triggering the bug.

Generated with the assistance of an AI coding tool.
2026-04-24 20:33:05 -05:00
Ryan Schultz 02ddedd3e6 Generalize ExcludeAnnotation to any IFC element
Rename ExcludeAnnotation to ExcludeFromDrawing and update
bl_idname to bim.exclude_from_drawing. The operator now
excludes any selected IFC element, not just auto-annotations.
For auto-annotations the referenced product is still resolved
first. Also rename exclude_annotation_from_drawing to
exclude_element_from_drawing in tool.Drawing.

Generated with the assistance of an AI coding tool.
2026-02-24 10:21:00 -06:00
4 changed files with 14 additions and 11 deletions
@@ -66,7 +66,7 @@ classes = (
operator.EnableEditingAssignedProduct,
operator.EnableEditingElementFilter,
operator.EnableEditingText,
operator.ExcludeAnnotation,
operator.ExcludeFromDrawing,
operator.ExpandSheet,
operator.ToggleElementValuesPanel,
operator.ToggleElementValuesCategory,
@@ -4023,20 +4023,23 @@ class OpenDocumentationWebUi(bpy.types.Operator):
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"
class ExcludeFromDrawing(bpy.types.Operator, tool.Ifc.Operator):
bl_idname = "bim.exclude_from_drawing"
bl_label = "Exclude From Drawing"
bl_description = "Excludes the selected IFC elements 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)
if element := tool.Ifc.get_entity(obj):
if tool.Drawing.is_auto_annotation(element):
element = tool.Drawing.get_annotation_element(element)
if element:
tool.Drawing.exclude_element_from_drawing(element, drawing)
core.sync_references(tool.Ifc, tool.Collector, tool.Drawing, drawing=drawing)
bpy.ops.bim.activate_drawing(drawing=drawing.id(), should_view_from_camera=False)
class ActivateDrawingByAnnotation(bpy.types.Operator, tool.Ifc.Operator):
+1 -1
View File
@@ -198,7 +198,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.exclude_from_drawing", icon="REMOVE", text="")
row.operator("bim.enable_editing_element_filter", icon=icon, text="").filter_mode = "EXCLUDE"
+2 -2
View File
@@ -223,7 +223,7 @@ class Drawing(bonsai.core.tool.Drawing):
return e
@classmethod
def exclude_annotation_from_drawing(
def exclude_element_from_drawing(
cls, element: ifcopenshell.entity_instance, drawing: ifcopenshell.entity_instance
) -> None:
ifc_file = tool.Ifc.get()
@@ -232,7 +232,7 @@ class Drawing(bonsai.core.tool.Drawing):
pset = ifcopenshell.api.pset.add_pset(ifc_file, product=drawing, name="EPset_Drawing")
exclude = ifcopenshell.util.element.get_property_definition(pset, prop="Exclude") or ""
if exclude:
exclude += "+"
exclude += " + "
exclude += element.GlobalId
ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Exclude": exclude})