mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 14:33:28 +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"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
drawing: bpy.props.IntProperty()
|
drawing: bpy.props.IntProperty()
|
||||||
should_duplicate_annotations: bpy.props.BoolProperty(name="Should Duplicate Annotations", default=False)
|
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
|
@classmethod
|
||||||
def poll(cls, context):
|
def poll(cls, context):
|
||||||
@@ -216,8 +224,11 @@ class DuplicateDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
assert self.layout
|
assert self.layout
|
||||||
row = self.layout
|
layout = self.layout
|
||||||
row.prop(self, "should_duplicate_annotations")
|
layout.prop(self, "should_duplicate_annotations")
|
||||||
|
row = layout.row()
|
||||||
|
row.enabled = self.should_duplicate_annotations
|
||||||
|
row.prop(self, "share_annotations")
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = tool.Drawing.get_document_props()
|
props = tool.Drawing.get_document_props()
|
||||||
@@ -228,6 +239,7 @@ class DuplicateDrawing(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
tool.Geometry,
|
tool.Geometry,
|
||||||
drawing=tool.Ifc.get().by_id(self.drawing),
|
drawing=tool.Ifc.get().by_id(self.drawing),
|
||||||
should_duplicate_annotations=self.should_duplicate_annotations,
|
should_duplicate_annotations=self.should_duplicate_annotations,
|
||||||
|
share_annotations=self.share_annotations,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -355,6 +355,7 @@ def duplicate_drawing(
|
|||||||
geometry: type[tool.Geometry],
|
geometry: type[tool.Geometry],
|
||||||
drawing: ifcopenshell.entity_instance,
|
drawing: ifcopenshell.entity_instance,
|
||||||
should_duplicate_annotations: bool = False,
|
should_duplicate_annotations: bool = False,
|
||||||
|
share_annotations: bool = False,
|
||||||
) -> ifcopenshell.entity_instance:
|
) -> ifcopenshell.entity_instance:
|
||||||
drawing_name = drawing_tool.ensure_unique_drawing_name(drawing_tool.get_name(drawing))
|
drawing_name = drawing_tool.ensure_unique_drawing_name(drawing_tool.get_name(drawing))
|
||||||
new_drawing = ifc.run("root.copy_class", product=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.edit_group", group=new_group, attributes={"Name": drawing_name, "ObjectType": "DRAWING"})
|
||||||
ifc.run("group.assign_group", group=new_group, products=[new_drawing])
|
ifc.run("group.assign_group", group=new_group, products=[new_drawing])
|
||||||
if should_duplicate_annotations:
|
if should_duplicate_annotations:
|
||||||
new_annotations: list[ifcopenshell.entity_instance] = []
|
source_annotations = [a for a in drawing_tool.get_group_elements(group) if a != drawing]
|
||||||
annotation_objs = [ifc.get_object(a) for a in drawing_tool.get_group_elements(group) if a != drawing]
|
if share_annotations:
|
||||||
old_to_new, _ = geometry.duplicate_ifc_objects(annotation_objs)
|
# Share manual annotations with the new drawing (multi-group membership):
|
||||||
for new_elements in old_to_new.values():
|
# the same entity now belongs to both drawings' groups, so edits propagate.
|
||||||
# Remove the Blender object, since we haven't actually activated the duplicated drawing
|
# Auto-generated tags (grid/section/storey) can't be shared - they are
|
||||||
for new_element in new_elements:
|
# regenerated per drawing - so they are still duplicated.
|
||||||
blender.remove_object(ifc.get_object(new_element))
|
to_share = [a for a in source_annotations if not drawing_tool.is_auto_annotation(a)]
|
||||||
new_annotations.extend(new_elements)
|
to_duplicate = [a for a in source_annotations if drawing_tool.is_auto_annotation(a)]
|
||||||
ifc.run("group.unassign_group", group=group, products=new_annotations)
|
if to_share:
|
||||||
ifc.run("group.assign_group", group=new_group, products=new_annotations)
|
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)
|
old_reference = drawing_tool.get_drawing_document(new_drawing)
|
||||||
ifc.run("document.unassign_document", products=[new_drawing], document=old_reference)
|
ifc.run("document.unassign_document", products=[new_drawing], document=old_reference)
|
||||||
|
|||||||
Reference in New Issue
Block a user