mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-27 18:57:17 +00:00
Add external SVG reference support to manual drawing reference tags
Extends manual drawing reference annotations (elevation and section) to also support external SVG references imported via bim.add_reference. - Add "Is a Reference" checkbox to the annotation tool sidebar, shown when Elevation or Section is the active type; checking it and pressing Add opens a dialog to optionally link the tag to a Bonsai drawing or an external SVG reference - The MANUAL_DRAWING_REFERENCE dropdown type is retained for backwards compatibility; selecting it shows a style picker (Elevation/Section) and the same linking dialog - External-reference annotations are flagged with IsDocumentReference in EPset_Annotation and linked to their IfcDocumentInformation via IfcRelAssociatesDocument; drawing-reference annotations continue to use IfcRelAssignsToProduct as before - SVG export resolves the correct reference/sheet IDs for both link types via get_reference_and_sheet_id_from_annotation - Add IsDocumentReference to the EPset_Annotation pset template
This commit is contained in:
@@ -5,7 +5,7 @@ FILE_NAME('Psets_BBIM_Annotation.ifc','2020-01-01T00:00:00',$,$,'Psets_BBIM_Anno
|
|||||||
FILE_SCHEMA(('IFC4'));
|
FILE_SCHEMA(('IFC4'));
|
||||||
ENDSEC;
|
ENDSEC;
|
||||||
DATA;
|
DATA;
|
||||||
#1=IFCPROPERTYSETTEMPLATE('3VuPUwdCD2Qx3XDDRs0R1N',$,'EPset_Annotation','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation,IfcTypeProduct',(#4,#33,#29,#32,#3,#2,#34));
|
#1=IFCPROPERTYSETTEMPLATE('3VuPUwdCD2Qx3XDDRs0R1N',$,'EPset_Annotation','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation,IfcTypeProduct',(#4,#33,#29,#32,#3,#2,#34,#35));
|
||||||
#2=IFCSIMPLEPROPERTYTEMPLATE('2P7JN79n96Q9pElZ83LKe4',$,'ZIndex','',.P_SINGLEVALUE.,'IfcInteger',$,$,$,$,$,.READWRITE.);
|
#2=IFCSIMPLEPROPERTYTEMPLATE('2P7JN79n96Q9pElZ83LKe4',$,'ZIndex','',.P_SINGLEVALUE.,'IfcInteger',$,$,$,$,$,.READWRITE.);
|
||||||
#3=IFCSIMPLEPROPERTYTEMPLATE('1Wpx_r2xj1_9w5JpI0QRJy',$,'Symbol','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
#3=IFCSIMPLEPROPERTYTEMPLATE('1Wpx_r2xj1_9w5JpI0QRJy',$,'Symbol','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||||
#4=IFCSIMPLEPROPERTYTEMPLATE('3q0oxMUKP47vZ4jnyG$dDb',$,'Classes','Classes separated by spaces that end up in classes for this element in svg. Can be used to specify the text font size: small - 1.8mm; regular - 2.5mm; large - 3.5mm; header - 5mm; title - 7mm. By default regular size is used.',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
#4=IFCSIMPLEPROPERTYTEMPLATE('3q0oxMUKP47vZ4jnyG$dDb',$,'Classes','Classes separated by spaces that end up in classes for this element in svg. Can be used to specify the text font size: small - 1.8mm; regular - 2.5mm; large - 3.5mm; header - 5mm; title - 7mm. By default regular size is used.',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||||
@@ -39,5 +39,6 @@ DATA;
|
|||||||
#32=IFCSIMPLEPROPERTYTEMPLATE('0gjJzDYBX8P85qn1xcAOOo',$,'Reverse_List','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
#32=IFCSIMPLEPROPERTYTEMPLATE('0gjJzDYBX8P85qn1xcAOOo',$,'Reverse_List','',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||||
#33=IFCSIMPLEPROPERTYTEMPLATE('22TrcxF8jFNB4buSmzjGEF',$,'List_Separator','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
#33=IFCSIMPLEPROPERTYTEMPLATE('22TrcxF8jFNB4buSmzjGEF',$,'List_Separator','',.P_SINGLEVALUE.,'IfcText',$,$,$,$,$,.READWRITE.);
|
||||||
#34=IFCSIMPLEPROPERTYTEMPLATE('0FauxIsAnnotFaux0001aB',$,'IsManualDrawingReference','Marks this annotation as a manually placed drawing reference, exempt from automatic drawing regeneration.',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
#34=IFCSIMPLEPROPERTYTEMPLATE('0FauxIsAnnotFaux0001aB',$,'IsManualDrawingReference','Marks this annotation as a manually placed drawing reference, exempt from automatic drawing regeneration.',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||||
|
#35=IFCSIMPLEPROPERTYTEMPLATE('0FauxIsDocRefFaux001aB',$,'IsDocumentReference','Marks this annotation as pointing to an external document reference (not a Bonsai drawing camera).',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||||
ENDSEC;
|
ENDSEC;
|
||||||
END-ISO-10303-21;
|
END-ISO-10303-21;
|
||||||
|
|||||||
@@ -55,6 +55,14 @@ class ProductAssignmentsData:
|
|||||||
element = tool.Ifc.get_entity(bpy.context.active_object)
|
element = tool.Ifc.get_entity(bpy.context.active_object)
|
||||||
if not element or not element.is_a("IfcAnnotation"):
|
if not element or not element.is_a("IfcAnnotation"):
|
||||||
return
|
return
|
||||||
|
# Document-reference annotations link to an IfcDocumentInformation, not a product.
|
||||||
|
if tool.Drawing.is_document_reference(element):
|
||||||
|
for rel in element.HasAssociations:
|
||||||
|
if rel.is_a("IfcRelAssociatesDocument"):
|
||||||
|
doc = rel.RelatingDocument
|
||||||
|
if doc.is_a("IfcDocumentInformation"):
|
||||||
|
return doc.Name or "Unnamed"
|
||||||
|
return None
|
||||||
for rel in element.HasAssignments:
|
for rel in element.HasAssignments:
|
||||||
if rel.is_a("IfcRelAssignsToProduct"):
|
if rel.is_a("IfcRelAssignsToProduct"):
|
||||||
name = rel.RelatingProduct.Name or "Unnamed"
|
name = rel.RelatingProduct.Name or "Unnamed"
|
||||||
|
|||||||
@@ -1737,20 +1737,32 @@ def _get_drawing_enum_items(self, context):
|
|||||||
return items
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
def _get_reference_doc_enum_items(self, context):
|
||||||
|
items = [("0", "None", "Clear the reference assignment")]
|
||||||
|
if ifc := tool.Ifc.get():
|
||||||
|
for d in ifc.by_type("IfcDocumentInformation"):
|
||||||
|
if d.Scope == "REFERENCE":
|
||||||
|
items.append((str(d.id()), d.Name or f"Reference {d.id()}", ""))
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
class AddAnnotation(bpy.types.Operator, tool.Ifc.Operator):
|
class AddAnnotation(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.add_annotation"
|
bl_idname = "bim.add_annotation"
|
||||||
bl_label = "Add Annotation"
|
bl_label = "Add Annotation"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
description: bpy.props.StringProperty()
|
description: bpy.props.StringProperty()
|
||||||
annotation_subtype: bpy.props.EnumProperty(
|
drawing_id: bpy.props.EnumProperty(name="Drawing", items=_get_drawing_enum_items)
|
||||||
name="Type",
|
reference_doc_id: bpy.props.EnumProperty(name="Reference", items=_get_reference_doc_enum_items)
|
||||||
|
is_document_reference: bpy.props.BoolProperty(name="External Reference", default=False)
|
||||||
|
# Used only when placing via the legacy MANUAL_DRAWING_REFERENCE dropdown type.
|
||||||
|
manual_style: bpy.props.EnumProperty(
|
||||||
|
name="Style",
|
||||||
items=[
|
items=[
|
||||||
("ELEVATION", "Elevation", "Place a manual elevation tag"),
|
("ELEVATION", "Elevation", "Use the elevation tag visual (circle with arrow)"),
|
||||||
("SECTION", "Section", "Place a manual section tag"),
|
("SECTION", "Section", "Use the section tag visual (line with end circles)"),
|
||||||
],
|
],
|
||||||
default="ELEVATION",
|
default="ELEVATION",
|
||||||
)
|
)
|
||||||
drawing_id: bpy.props.EnumProperty(name="Drawing", items=_get_drawing_enum_items)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
@@ -1761,14 +1773,27 @@ class AddAnnotation(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
return operator.description or ""
|
return operator.description or ""
|
||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
if tool.Drawing.get_annotation_props().object_type == "MANUAL_DRAWING_REFERENCE":
|
props = tool.Drawing.get_annotation_props()
|
||||||
|
needs_dialog = (
|
||||||
|
(props.is_manual_reference and props.object_type in ("ELEVATION", "SECTION"))
|
||||||
|
or props.object_type == "MANUAL_DRAWING_REFERENCE"
|
||||||
|
)
|
||||||
|
if needs_dialog:
|
||||||
self.drawing_id = "0"
|
self.drawing_id = "0"
|
||||||
|
self.reference_doc_id = "0"
|
||||||
|
self.is_document_reference = False
|
||||||
return context.window_manager.invoke_props_dialog(self)
|
return context.window_manager.invoke_props_dialog(self)
|
||||||
return self.execute(context)
|
return self.execute(context)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
self.layout.prop(self, "annotation_subtype", expand=True)
|
props = tool.Drawing.get_annotation_props()
|
||||||
prop_with_search(self.layout, self, "drawing_id", should_click_ok=True, search_threshold=0, original_operator_path=f"{__name__}.AddAnnotation")
|
if props.object_type == "MANUAL_DRAWING_REFERENCE":
|
||||||
|
self.layout.prop(self, "manual_style", expand=True)
|
||||||
|
self.layout.prop(self, "is_document_reference")
|
||||||
|
if self.is_document_reference:
|
||||||
|
prop_with_search(self.layout, self, "reference_doc_id", should_click_ok=True, search_threshold=0, original_operator_path=f"{__name__}.AddAnnotation")
|
||||||
|
else:
|
||||||
|
prop_with_search(self.layout, self, "drawing_id", should_click_ok=True, search_threshold=0, original_operator_path=f"{__name__}.AddAnnotation")
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = tool.Drawing.get_annotation_props()
|
props = tool.Drawing.get_annotation_props()
|
||||||
@@ -1777,7 +1802,15 @@ class AddAnnotation(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
self.report({"WARNING"}, "No active drawing.")
|
self.report({"WARNING"}, "No active drawing.")
|
||||||
return
|
return
|
||||||
|
|
||||||
object_type = self.annotation_subtype if props.object_type == "MANUAL_DRAWING_REFERENCE" else props.object_type
|
# MANUAL_DRAWING_REFERENCE is a legacy/convenience dropdown entry; resolve
|
||||||
|
# it to the chosen style so create_annotation_object knows what to build.
|
||||||
|
if props.object_type == "MANUAL_DRAWING_REFERENCE":
|
||||||
|
object_type = self.manual_style
|
||||||
|
is_manual = True
|
||||||
|
else:
|
||||||
|
object_type = props.object_type
|
||||||
|
is_manual = props.is_manual_reference and object_type in ("ELEVATION", "SECTION")
|
||||||
|
|
||||||
obj = core.add_annotation(
|
obj = core.add_annotation(
|
||||||
tool.Ifc,
|
tool.Ifc,
|
||||||
tool.Collector,
|
tool.Collector,
|
||||||
@@ -1790,12 +1823,18 @@ class AddAnnotation(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
# item edit mode for these types.
|
# item edit mode for these types.
|
||||||
enable_editing=object_type not in ("ELEVATION", "SECTION"),
|
enable_editing=object_type not in ("ELEVATION", "SECTION"),
|
||||||
)
|
)
|
||||||
if props.object_type == "IMAGE":
|
if object_type == "IMAGE":
|
||||||
bpy.ops.bim.add_reference_image("INVOKE_DEFAULT", existing_object_by_name=obj.name)
|
bpy.ops.bim.add_reference_image("INVOKE_DEFAULT", existing_object_by_name=obj.name)
|
||||||
if object_type in ("ELEVATION", "SECTION"):
|
if is_manual:
|
||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
tool.Drawing.set_manual_drawing_reference(element)
|
tool.Drawing.set_manual_drawing_reference(element)
|
||||||
if self.drawing_id != "0":
|
if self.is_document_reference:
|
||||||
|
tool.Drawing.set_document_reference_flag(element)
|
||||||
|
if self.reference_doc_id != "0":
|
||||||
|
core.assign_manual_reference_document(
|
||||||
|
tool.Drawing, element=element, document=tool.Ifc.get().by_id(int(self.reference_doc_id))
|
||||||
|
)
|
||||||
|
elif self.drawing_id != "0":
|
||||||
core.assign_manual_drawing_reference(
|
core.assign_manual_drawing_reference(
|
||||||
tool.Ifc, tool.Drawing, element=element, drawing=tool.Ifc.get().by_id(int(self.drawing_id))
|
tool.Ifc, tool.Drawing, element=element, drawing=tool.Ifc.get().by_id(int(self.drawing_id))
|
||||||
)
|
)
|
||||||
@@ -1804,9 +1843,10 @@ class AddAnnotation(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
class AssignManualDrawingReference(bpy.types.Operator, tool.Ifc.Operator):
|
class AssignManualDrawingReference(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.assign_manual_drawing_reference"
|
bl_idname = "bim.assign_manual_drawing_reference"
|
||||||
bl_label = "Assign Drawing"
|
bl_label = "Assign Drawing"
|
||||||
bl_description = "Assign a target drawing to this manual drawing reference tag"
|
bl_description = "Assign a target drawing or reference to this manual drawing reference tag"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
drawing_id: bpy.props.EnumProperty(name="Drawing", items=_get_drawing_enum_items)
|
drawing_id: bpy.props.EnumProperty(name="Drawing", items=_get_drawing_enum_items)
|
||||||
|
reference_doc_id: bpy.props.EnumProperty(name="Reference", items=_get_reference_doc_enum_items)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
@@ -1825,17 +1865,29 @@ class AssignManualDrawingReference(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def invoke(self, context, event):
|
def invoke(self, context, event):
|
||||||
element = tool.Ifc.get_entity(context.active_object)
|
element = tool.Ifc.get_entity(context.active_object)
|
||||||
current = tool.Drawing.get_annotation_element(element)
|
if tool.Drawing.is_document_reference(element):
|
||||||
self.drawing_id = str(current.id()) if current else "0"
|
doc = tool.Drawing.get_annotation_reference_doc(element)
|
||||||
|
self.reference_doc_id = str(doc.id()) if doc else "0"
|
||||||
|
else:
|
||||||
|
current = tool.Drawing.get_annotation_element(element)
|
||||||
|
self.drawing_id = str(current.id()) if current else "0"
|
||||||
return context.window_manager.invoke_props_dialog(self)
|
return context.window_manager.invoke_props_dialog(self)
|
||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
prop_with_search(self.layout, self, "drawing_id", search_threshold=0, original_operator_path=f"{__name__}.AssignManualDrawingReference")
|
element = tool.Ifc.get_entity(bpy.context.active_object)
|
||||||
|
if element and tool.Drawing.is_document_reference(element):
|
||||||
|
prop_with_search(self.layout, self, "reference_doc_id", search_threshold=0, original_operator_path=f"{__name__}.AssignManualDrawingReference")
|
||||||
|
else:
|
||||||
|
prop_with_search(self.layout, self, "drawing_id", search_threshold=0, original_operator_path=f"{__name__}.AssignManualDrawingReference")
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
element = tool.Ifc.get_entity(context.active_object)
|
element = tool.Ifc.get_entity(context.active_object)
|
||||||
drawing = tool.Ifc.get().by_id(int(self.drawing_id)) if self.drawing_id != "0" else None
|
if tool.Drawing.is_document_reference(element):
|
||||||
core.assign_manual_drawing_reference(tool.Ifc, tool.Drawing, element=element, drawing=drawing)
|
document = tool.Ifc.get().by_id(int(self.reference_doc_id)) if self.reference_doc_id != "0" else None
|
||||||
|
core.assign_manual_reference_document(tool.Drawing, element=element, document=document)
|
||||||
|
else:
|
||||||
|
drawing = tool.Ifc.get().by_id(int(self.drawing_id)) if self.drawing_id != "0" else None
|
||||||
|
core.assign_manual_drawing_reference(tool.Ifc, tool.Drawing, element=element, drawing=drawing)
|
||||||
for area in context.screen.areas:
|
for area in context.screen.areas:
|
||||||
if area.type == "PROPERTIES":
|
if area.type == "PROPERTIES":
|
||||||
area.tag_redraw()
|
area.tag_redraw()
|
||||||
|
|||||||
@@ -1000,6 +1000,12 @@ class BIMAnnotationProperties(PropertyGroup):
|
|||||||
)
|
)
|
||||||
is_adding_type: bpy.props.BoolProperty(default=False)
|
is_adding_type: bpy.props.BoolProperty(default=False)
|
||||||
type_name: bpy.props.StringProperty(name="Name", default="TYPEX")
|
type_name: bpy.props.StringProperty(name="Name", default="TYPEX")
|
||||||
|
is_manual_reference: bpy.props.BoolProperty(
|
||||||
|
name="Is a Reference",
|
||||||
|
default=False,
|
||||||
|
description="Place as a manual reference tag (IsManualDrawingReference). "
|
||||||
|
"Exempt from automatic drawing regeneration. Optionally link to a drawing or external reference.",
|
||||||
|
)
|
||||||
tag_rotation_mode: bpy.props.EnumProperty(
|
tag_rotation_mode: bpy.props.EnumProperty(
|
||||||
name="Tag Rotation Mode",
|
name="Tag Rotation Mode",
|
||||||
description="How to orient the tag relative to the tagged object",
|
description="How to orient the tag relative to the tagged object",
|
||||||
@@ -1020,3 +1026,4 @@ class BIMAnnotationProperties(PropertyGroup):
|
|||||||
create_representation_for_type: bool
|
create_representation_for_type: bool
|
||||||
is_adding_type: bool
|
is_adding_type: bool
|
||||||
type_name: str
|
type_name: str
|
||||||
|
is_manual_reference: bool
|
||||||
|
|||||||
@@ -896,8 +896,32 @@ class SvgWriter:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def get_reference_and_sheet_id_from_annotation(self, element: ifcopenshell.entity_instance) -> tuple[str, str]:
|
def get_reference_and_sheet_id_from_annotation(self, element: ifcopenshell.entity_instance) -> tuple[str, str]:
|
||||||
reference_id = "-"
|
is_ifc2x3 = tool.Ifc.get_schema() == "IFC2X3"
|
||||||
sheet_id = "-"
|
|
||||||
|
# Document-reference annotations link to an IfcDocumentInformation via
|
||||||
|
# IfcRelAssociatesDocument rather than to a drawing product.
|
||||||
|
if tool.Drawing.is_document_reference(element):
|
||||||
|
doc_info = tool.Drawing.get_annotation_reference_doc(element)
|
||||||
|
if not doc_info:
|
||||||
|
return ("-", "-")
|
||||||
|
ext_location = tool.Drawing.get_path_with_ext(
|
||||||
|
(doc_info.DocumentReferences[0].Location if is_ifc2x3 else doc_info.HasDocumentReferences[0].Location),
|
||||||
|
"svg",
|
||||||
|
) if (doc_info.DocumentReferences if is_ifc2x3 else doc_info.HasDocumentReferences) else None
|
||||||
|
if not ext_location:
|
||||||
|
return ("-", "-")
|
||||||
|
for sheet_reference in tool.Ifc.get().by_type("IfcDocumentReference"):
|
||||||
|
if tool.Drawing.get_reference_description(sheet_reference) != "REFERENCE":
|
||||||
|
continue
|
||||||
|
if sheet_reference.Location != ext_location:
|
||||||
|
continue
|
||||||
|
sheet = tool.Drawing.get_reference_document(sheet_reference)
|
||||||
|
if sheet:
|
||||||
|
if is_ifc2x3:
|
||||||
|
return (sheet_reference.ItemReference or "-", sheet.DocumentId or "-")
|
||||||
|
return (sheet_reference.Identification or "-", sheet.Identification or "-")
|
||||||
|
return ("-", "-")
|
||||||
|
|
||||||
drawing = tool.Drawing.get_annotation_element(element)
|
drawing = tool.Drawing.get_annotation_element(element)
|
||||||
if not drawing:
|
if not drawing:
|
||||||
return ("-", "-")
|
return ("-", "-")
|
||||||
@@ -909,13 +933,9 @@ class SvgWriter:
|
|||||||
continue
|
continue
|
||||||
sheet = tool.Drawing.get_reference_document(sheet_reference)
|
sheet = tool.Drawing.get_reference_document(sheet_reference)
|
||||||
if sheet:
|
if sheet:
|
||||||
if tool.Ifc.get_schema() == "IFC2X3":
|
if is_ifc2x3:
|
||||||
reference_id = sheet_reference.ItemReference or "-"
|
return (sheet_reference.ItemReference or "-", sheet.DocumentId or "-")
|
||||||
sheet_id = sheet.DocumentId or "-"
|
return (sheet_reference.Identification or "-", sheet.Identification or "-")
|
||||||
else:
|
|
||||||
reference_id = sheet_reference.Identification or "-"
|
|
||||||
sheet_id = sheet.Identification or "-"
|
|
||||||
return (reference_id, sheet_id)
|
|
||||||
break
|
break
|
||||||
return ("-", "-")
|
return ("-", "-")
|
||||||
|
|
||||||
|
|||||||
@@ -539,8 +539,9 @@ class BIM_PT_product_assignments(Panel):
|
|||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
if element and tool.Drawing.is_manual_drawing_reference(element):
|
if element and tool.Drawing.is_manual_drawing_reference(element):
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
|
fallback = "No Reference Assigned" if element.ObjectType == "REFERENCE" else "No Drawing Assigned"
|
||||||
row.label(
|
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="")
|
row.operator("bim.assign_manual_drawing_reference", icon="GREASEPENCIL", text="")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -249,6 +249,10 @@ class AnnotationToolUI:
|
|||||||
|
|
||||||
add_layout_hotkey_operator(cls.layout, "Add", "S_A", "Create a new annotation")
|
add_layout_hotkey_operator(cls.layout, "Add", "S_A", "Create a new annotation")
|
||||||
|
|
||||||
|
if object_type in ("ELEVATION", "SECTION"):
|
||||||
|
row = cls.layout.row(align=True)
|
||||||
|
row.prop(cls.props, "is_manual_reference")
|
||||||
|
|
||||||
if object_type in tool.Drawing.ANNOTATION_TYPES_SUPPORT_SETUP:
|
if object_type in tool.Drawing.ANNOTATION_TYPES_SUPPORT_SETUP:
|
||||||
row = cls.layout.row(align=True)
|
row = cls.layout.row(align=True)
|
||||||
row.label(text="", icon="DRIVER_ROTATIONAL_DIFFERENCE")
|
row.label(text="", icon="DRIVER_ROTATIONAL_DIFFERENCE")
|
||||||
|
|||||||
@@ -518,6 +518,14 @@ def assign_manual_drawing_reference(
|
|||||||
ifc.run("drawing.assign_product", relating_product=drawing, related_object=element)
|
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:
|
def build_schedule(drawing: type[tool.Drawing], schedule: ifcopenshell.entity_instance) -> None:
|
||||||
drawing.create_svg_schedule(schedule)
|
drawing.create_svg_schedule(schedule)
|
||||||
drawing.open_svg(drawing.get_path_with_ext(drawing.get_document_uri(schedule), "svg"))
|
drawing.open_svg(drawing.get_path_with_ext(drawing.get_document_uri(schedule), "svg"))
|
||||||
|
|||||||
@@ -1889,6 +1889,49 @@ class Drawing(bonsai.core.tool.Drawing):
|
|||||||
pset = ifcopenshell.api.pset.add_pset(ifc_file, product=element, name="EPset_Annotation")
|
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})
|
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
|
@classmethod
|
||||||
def regenerate_elevation_reference_annotation(
|
def regenerate_elevation_reference_annotation(
|
||||||
cls,
|
cls,
|
||||||
|
|||||||
Reference in New Issue
Block a user