diff --git a/src/bonsai/bonsai/bim/data/pset/EPset_Drawing.ifc b/src/bonsai/bonsai/bim/data/pset/EPset_Drawing.ifc index a516b9765d..70d6049ad7 100644 --- a/src/bonsai/bonsai/bim/data/pset/EPset_Drawing.ifc +++ b/src/bonsai/bonsai/bim/data/pset/EPset_Drawing.ifc @@ -13,10 +13,10 @@ DATA; #6=IFCSIMPLEPROPERTYTEMPLATE('0AK5C2UpL4$eaac2LszAx$',$,'HasUnderlay','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.); #7=IFCSIMPLEPROPERTYTEMPLATE('2j2ZEZR8X5tONm7kli5hM6',$,'HasLinework','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.); #8=IFCSIMPLEPROPERTYTEMPLATE('1ttChRysH9UuEX2FeMj5Hu',$,'HasAnnotation','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.); -#9=IFCSIMPLEPROPERTYTEMPLATE('2NPPxuABv1huDTVh32TFgw',$,'GlobalReferencing','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.); +#9=IFCSIMPLEPROPERTYTEMPLATE('2NPPxuABv1huDTVh32TFgw',$,'GlobalReferencing','Whether or not this drawing can be referenced in other drawings.',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.); #10=IFCSIMPLEPROPERTYTEMPLATE('10hT_1zrzEbRRKMXYAWvtD',$,'Metadata','Comma separated list of selector expressions to evaluate for each drawing elementand add results to their ''class'' attribute.\X2\000A\X0\E.g. ''Name, id'' would add to ''class'' value similar to ''Name-Wall id-1220''.\X2\000A\X0\Then it can be used to applied css styles based on the resulting class.\X2\000A\X0\If attribute is not present on the element, then it won''t be added to it''s ''class''.',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); -#11=IFCSIMPLEPROPERTYTEMPLATE('3Z0BXPSG5CWgtI33ioV7aj',$,'Include','Selector expression to include ifc elements in the drawing',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); -#12=IFCSIMPLEPROPERTYTEMPLATE('1RVts_g3PAw98PJA2yL3bO',$,'Exclude','Selector expression to exclude ifc elements in the drawing',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); +#11=IFCSIMPLEPROPERTYTEMPLATE('3Z0BXPSG5CWgtI33ioV7aj',$,'Include','Selector expression to include elements in the drawing',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); +#12=IFCSIMPLEPROPERTYTEMPLATE('1RVts_g3PAw98PJA2yL3bO',$,'Exclude','Selector expression to exclude elements in the drawing',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); #13=IFCSIMPLEPROPERTYTEMPLATE('0c1$8NpYDEaBiJrj16jHIo',$,'Stylesheet','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); #14=IFCSIMPLEPROPERTYTEMPLATE('3mRF52q81FQB$h4oTh7M45',$,'Markers','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); #15=IFCSIMPLEPROPERTYTEMPLATE('1rhr_0N3LDtuORcEJP0KXM',$,'Symbols','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.); diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index 336b3fd0dd..ad650eb4cc 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -208,6 +208,25 @@ class Drawing(bonsai.core.tool.Drawing): return obj + @classmethod + def get_annotation_drawing(cls, element: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance | None: + for rel in element.HasAssignments: + if rel.is_a("IfcRelAssignsToGroup") and rel.RelatingGroup.ObjectType == "DRAWING": + for e in rel.RelatedObjects: + if e.ObjectType == "DRAWING": + return e + + @classmethod + def exclude_annotation_from_drawing(cls, element: ifcopenshell.entity_instance, drawing: ifcopenshell.entity_instance) -> None: + pset = tool.Pset.get_element_pset(drawing, "EPset_Drawing") + if not pset: + 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 += element.GlobalId + ifcopenshell.api.pset.edit_pset(tool.Ifc.get(), pset=pset, properties={"Exclude": exclude}) + @classmethod def ensure_annotation_in_drawing_plane( cls, obj: bpy.types.Object, camera: Optional[bpy.types.Object] = None @@ -218,11 +237,7 @@ class Drawing(bonsai.core.tool.Drawing): entity = tool.Ifc.get_entity(obj) if not entity: return - for rel in entity.HasAssignments: - if rel.is_a("IfcRelAssignsToGroup"): - for e in rel.RelatedObjects: - if e.ObjectType == "DRAWING": - return tool.Ifc.get_object(e) + return tool.Ifc.get_object(cls.get_annotation_drawing(entity)) if not camera: camera = get_camera_from_annotation_object(obj) or bpy.context.scene.camera @@ -1401,7 +1416,10 @@ class Drawing(bonsai.core.tool.Drawing): cls, drawing: ifcopenshell.entity_instance ) -> list[ifcopenshell.entity_instance]: elements = [] - existing_references = cls.get_group_elements(cls.get_drawing_group(drawing)) + existing_references = set(cls.get_group_elements(cls.get_drawing_group(drawing))) + if exclude := ifcopenshell.util.element.get_pset(drawing, "EPset_Drawing", "Exclude"): + existing_references.update(ifcopenshell.util.selector.filter_elements(tool.Ifc.get(), exclude)) + for element in tool.Ifc.get().by_type("IfcAnnotation"): if element in existing_references or element == drawing: continue @@ -1411,8 +1429,13 @@ class Drawing(bonsai.core.tool.Drawing): "GlobalReferencing", False ): elements.append(element) - for element in tool.Ifc.get().by_type("IfcGridAxis"): - elements.append(element) + for element in tool.Ifc.get().by_type("IfcGrid"): + if element in existing_references: + continue + for axis in element.UAxes + element.VAxes + (element.WAxes or tuple()): + if axis in existing_references: + continue + elements.append(element) 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"): diff --git a/src/bonsai/bonsai/tool/geometry.py b/src/bonsai/bonsai/tool/geometry.py index 8db4264783..a5625de761 100644 --- a/src/bonsai/bonsai/tool/geometry.py +++ b/src/bonsai/bonsai/tool/geometry.py @@ -233,8 +233,11 @@ class Geometry(bonsai.core.tool.Geometry): element = tool.Ifc.get_entity(obj) if not element: return - elif element.is_a("IfcAnnotation") and element.ObjectType == "DRAWING": - return bonsai.core.drawing.remove_drawing(tool.Ifc, tool.Drawing, drawing=element) + 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 element.is_a("IfcRelSpaceBoundary"): ifcopenshell.api.boundary.remove_boundary(ifc_file, boundary=element) tool.Boundary.undecorate_boundary(obj)