diff --git a/src/bonsai/bonsai/bim/module/drawing/ui.py b/src/bonsai/bonsai/bim/module/drawing/ui.py index 8d769fecb9..3f580cabb0 100644 --- a/src/bonsai/bonsai/bim/module/drawing/ui.py +++ b/src/bonsai/bonsai/bim/module/drawing/ui.py @@ -559,8 +559,9 @@ class BIM_PT_product_assignments(Panel): element = tool.Ifc.get_entity(obj) if element and tool.Drawing.is_manual_drawing_reference(element): row = self.layout.row(align=True) + fallback = "No Reference Assigned" if element.ObjectType == "REFERENCE" else "No Drawing Assigned" row.label( - text=ProductAssignmentsData.data["relating_product"] or "No Drawing Assigned", icon="IMAGE_DATA" + text=ProductAssignmentsData.data["relating_product"] or fallback, icon="IMAGE_DATA" ) row.operator("bim.assign_manual_drawing_reference", icon="GREASEPENCIL", text="") return diff --git a/src/bonsai/bonsai/core/drawing.py b/src/bonsai/bonsai/core/drawing.py index cc11ff2833..b6e18cea43 100644 --- a/src/bonsai/bonsai/core/drawing.py +++ b/src/bonsai/bonsai/core/drawing.py @@ -562,6 +562,14 @@ def assign_manual_drawing_reference( ifc.run("drawing.assign_product", relating_product=drawing, related_object=element) +def assign_manual_reference_document( + drawing_tool: type[tool.Drawing], + element: ifcopenshell.entity_instance, + document: Optional[ifcopenshell.entity_instance], +) -> None: + drawing_tool.set_annotation_reference_doc(element, document) + + def build_schedule(drawing: type[tool.Drawing], schedule: ifcopenshell.entity_instance) -> None: drawing.create_svg_schedule(schedule) drawing.open_svg(drawing.get_path_with_ext(drawing.get_document_uri(schedule), "svg")) diff --git a/src/bonsai/bonsai/tool/drawing.py b/src/bonsai/bonsai/tool/drawing.py index 95e4603c38..a024eed769 100644 --- a/src/bonsai/bonsai/tool/drawing.py +++ b/src/bonsai/bonsai/tool/drawing.py @@ -2021,6 +2021,49 @@ class Drawing(bonsai.core.tool.Drawing): pset = ifcopenshell.api.pset.add_pset(ifc_file, product=element, name="EPset_Annotation") ifcopenshell.api.pset.edit_pset(ifc_file, pset=pset, properties={"IsManualDrawingReference": True}) + @classmethod + def is_document_reference(cls, element: ifcopenshell.entity_instance) -> bool: + """Return True if this annotation links to an external document (not a Bonsai drawing camera).""" + return bool(ifcopenshell.util.element.get_pset(element, "EPset_Annotation", "IsDocumentReference")) + + @classmethod + def set_document_reference_flag(cls, element: ifcopenshell.entity_instance) -> None: + """Mark this annotation as pointing to an external document reference.""" + ifc_file = tool.Ifc.get() + pset = tool.Pset.get_element_pset(element, "EPset_Annotation") + if not pset: + pset = ifcopenshell.api.pset.add_pset(ifc_file, product=element, name="EPset_Annotation") + ifcopenshell.api.pset.edit_pset(ifc_file, pset=pset, properties={"IsDocumentReference": True}) + + @classmethod + def get_annotation_reference_doc( + cls, element: ifcopenshell.entity_instance + ) -> Union[ifcopenshell.entity_instance, None]: + """Return the IfcDocumentInformation linked to a document-reference annotation.""" + for rel in element.HasAssociations: + if rel.is_a("IfcRelAssociatesDocument"): + doc = rel.RelatingDocument + if doc.is_a("IfcDocumentInformation"): + return doc + return None + + @classmethod + def set_annotation_reference_doc( + cls, + element: ifcopenshell.entity_instance, + document: Union[ifcopenshell.entity_instance, None], + ) -> None: + """Associate (or clear) an IfcDocumentInformation on a document-reference annotation.""" + ifc_file = tool.Ifc.get() + # Remove existing document associations on this annotation. + for rel in list(element.HasAssociations): + if rel.is_a("IfcRelAssociatesDocument"): + ifcopenshell.api.document.unassign_document( + ifc_file, products=[element], document=rel.RelatingDocument + ) + if document: + ifcopenshell.api.document.assign_document(ifc_file, products=[element], document=document) + @classmethod def regenerate_elevation_reference_annotation( cls,