mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-28 07:49:59 +00:00
Bonsai: add "Share Annotations" option to Duplicate Drawing
When duplicating a drawing with "Should Duplicate Annotations" enabled, a new "Share Annotations" toggle lets the manual annotations be shared with the new drawing (multi-group membership - editing one updates both) instead of being copied into independent entities. Auto-generated tags (grid/section/storey) are always copied, since they are regenerated per drawing and cannot be shared. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -202,6 +202,14 @@ class DuplicateDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
drawing: bpy.props.IntProperty()
|
||||
should_duplicate_annotations: bpy.props.BoolProperty(name="Should Duplicate Annotations", default=False)
|
||||
share_annotations: bpy.props.BoolProperty(
|
||||
name="Share Annotations",
|
||||
description=(
|
||||
"Assign the same annotations to the new drawing (shared - editing one updates both) "
|
||||
"instead of creating independent copies. Auto-generated tags are always copied"
|
||||
),
|
||||
default=False,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
@@ -216,8 +224,11 @@ class DuplicateDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
def draw(self, context):
|
||||
assert self.layout
|
||||
row = self.layout
|
||||
row.prop(self, "should_duplicate_annotations")
|
||||
layout = self.layout
|
||||
layout.prop(self, "should_duplicate_annotations")
|
||||
row = layout.row()
|
||||
row.enabled = self.should_duplicate_annotations
|
||||
row.prop(self, "share_annotations")
|
||||
|
||||
def _execute(self, context):
|
||||
props = tool.Drawing.get_document_props()
|
||||
@@ -228,6 +239,7 @@ class DuplicateDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
||||
tool.Geometry,
|
||||
drawing=tool.Ifc.get().by_id(self.drawing),
|
||||
should_duplicate_annotations=self.should_duplicate_annotations,
|
||||
share_annotations=self.share_annotations,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -355,6 +355,7 @@ def duplicate_drawing(
|
||||
geometry: type[tool.Geometry],
|
||||
drawing: ifcopenshell.entity_instance,
|
||||
should_duplicate_annotations: bool = False,
|
||||
share_annotations: bool = False,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
drawing_name = drawing_tool.ensure_unique_drawing_name(drawing_tool.get_name(drawing))
|
||||
new_drawing = ifc.run("root.copy_class", product=drawing)
|
||||
@@ -367,16 +368,29 @@ def duplicate_drawing(
|
||||
ifc.run("group.edit_group", group=new_group, attributes={"Name": drawing_name, "ObjectType": "DRAWING"})
|
||||
ifc.run("group.assign_group", group=new_group, products=[new_drawing])
|
||||
if should_duplicate_annotations:
|
||||
new_annotations: list[ifcopenshell.entity_instance] = []
|
||||
annotation_objs = [ifc.get_object(a) for a in drawing_tool.get_group_elements(group) if a != drawing]
|
||||
old_to_new, _ = geometry.duplicate_ifc_objects(annotation_objs)
|
||||
for new_elements in old_to_new.values():
|
||||
# Remove the Blender object, since we haven't actually activated the duplicated drawing
|
||||
for new_element in new_elements:
|
||||
blender.remove_object(ifc.get_object(new_element))
|
||||
new_annotations.extend(new_elements)
|
||||
ifc.run("group.unassign_group", group=group, products=new_annotations)
|
||||
ifc.run("group.assign_group", group=new_group, products=new_annotations)
|
||||
source_annotations = [a for a in drawing_tool.get_group_elements(group) if a != drawing]
|
||||
if share_annotations:
|
||||
# Share manual annotations with the new drawing (multi-group membership):
|
||||
# the same entity now belongs to both drawings' groups, so edits propagate.
|
||||
# Auto-generated tags (grid/section/storey) can't be shared - they are
|
||||
# regenerated per drawing - so they are still duplicated.
|
||||
to_share = [a for a in source_annotations if not drawing_tool.is_auto_annotation(a)]
|
||||
to_duplicate = [a for a in source_annotations if drawing_tool.is_auto_annotation(a)]
|
||||
if to_share:
|
||||
ifc.run("group.assign_group", group=new_group, products=to_share)
|
||||
else:
|
||||
to_duplicate = source_annotations
|
||||
if to_duplicate:
|
||||
new_annotations: list[ifcopenshell.entity_instance] = []
|
||||
annotation_objs = [ifc.get_object(a) for a in to_duplicate]
|
||||
old_to_new, _ = geometry.duplicate_ifc_objects(annotation_objs)
|
||||
for new_elements in old_to_new.values():
|
||||
# Remove the Blender object, since we haven't actually activated the duplicated drawing
|
||||
for new_element in new_elements:
|
||||
blender.remove_object(ifc.get_object(new_element))
|
||||
new_annotations.extend(new_elements)
|
||||
ifc.run("group.unassign_group", group=group, products=new_annotations)
|
||||
ifc.run("group.assign_group", group=new_group, products=new_annotations)
|
||||
|
||||
old_reference = drawing_tool.get_drawing_document(new_drawing)
|
||||
ifc.run("document.unassign_document", products=[new_drawing], document=old_reference)
|
||||
|
||||
Reference in New Issue
Block a user