From 93d0ffd459dea5bbbdb099ef69875d29d07bdb81 Mon Sep 17 00:00:00 2001 From: Dion Moult Date: Wed, 8 Feb 2023 21:16:54 +1100 Subject: [PATCH] Fix #2520. You can now duplicate drawings with or without annotations. --- .../blenderbim/bim/module/drawing/operator.py | 15 ++++++++++++- src/blenderbim/blenderbim/core/drawing.py | 21 +++++++++++++------ src/blenderbim/blenderbim/core/tool.py | 2 +- src/blenderbim/blenderbim/tool/drawing.py | 9 ++++---- src/blenderbim/test/core/test_drawing.py | 9 ++++++-- src/blenderbim/test/tool/test_drawing.py | 4 ++-- 6 files changed, 44 insertions(+), 16 deletions(-) diff --git a/src/blenderbim/blenderbim/bim/module/drawing/operator.py b/src/blenderbim/blenderbim/bim/module/drawing/operator.py index 3757f55784..914bee3bd1 100644 --- a/src/blenderbim/blenderbim/bim/module/drawing/operator.py +++ b/src/blenderbim/blenderbim/bim/module/drawing/operator.py @@ -108,10 +108,23 @@ class DuplicateDrawing(bpy.types.Operator, Operator): bl_label = "Duplicate Drawing" bl_options = {"REGISTER", "UNDO"} drawing: bpy.props.IntProperty() + should_duplicate_annotations: bpy.props.BoolProperty(name="Should Duplicate Annotations", default=False) + + def invoke(self, context, event): + return context.window_manager.invoke_props_dialog(self) + + def draw(self, context): + row = self.layout + row.prop(self, "should_duplicate_annotations") def _execute(self, context): self.props = context.scene.DocProperties - core.duplicate_drawing(tool.Ifc, tool.Drawing, drawing=tool.Ifc.get().by_id(self.drawing)) + core.duplicate_drawing( + tool.Ifc, + tool.Drawing, + drawing=tool.Ifc.get().by_id(self.drawing), + should_duplicate_annotations=self.should_duplicate_annotations, + ) try: drawing = tool.Ifc.get().by_id(self.props.active_drawing_id) core.sync_references(tool.Ifc, tool.Collector, tool.Drawing, drawing=drawing) diff --git a/src/blenderbim/blenderbim/core/drawing.py b/src/blenderbim/blenderbim/core/drawing.py index 06b904cf9d..d1d839b974 100644 --- a/src/blenderbim/blenderbim/core/drawing.py +++ b/src/blenderbim/blenderbim/core/drawing.py @@ -167,15 +167,24 @@ def add_drawing(ifc, collector, drawing, target_view=None, location_hint=None): drawing.import_drawings() -def duplicate_drawing(ifc, drawing_tool, drawing=None): +def duplicate_drawing(ifc, drawing_tool, drawing=None, should_duplicate_annotations=False): drawing_name = drawing_tool.ensure_unique_drawing_name(drawing_tool.get_name(drawing)) new_drawing = ifc.run("root.copy_class", product=drawing) - drawing_tool.copy_drawing_representation(drawing, new_drawing) + drawing_tool.copy_representation(drawing, new_drawing) drawing_tool.set_name(new_drawing, drawing_name) - ifc.run("group.unassign_group", group=drawing_tool.get_drawing_group(new_drawing), product=new_drawing) - group = ifc.run("group.add_group") - ifc.run("group.edit_group", group=group, attributes={"Name": drawing_name, "ObjectType": "DRAWING"}) - ifc.run("group.assign_group", group=group, products=[new_drawing]) + group = drawing_tool.get_drawing_group(new_drawing) + ifc.run("group.unassign_group", group=group, product=new_drawing) + new_group = ifc.run("group.add_group") + 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: + for annotation in drawing_tool.get_group_elements(group): + if annotation == drawing: + continue + new_annotation = ifc.run("root.copy_class", product=annotation) + drawing_tool.copy_representation(annotation, new_annotation) + ifc.run("group.unassign_group", group=group, product=new_annotation) + ifc.run("group.assign_group", group=new_group, products=[new_annotation]) drawing_tool.import_drawings() return new_drawing diff --git a/src/blenderbim/blenderbim/core/tool.py b/src/blenderbim/blenderbim/core/tool.py index 9f40ce2388..f06b36fc86 100644 --- a/src/blenderbim/blenderbim/core/tool.py +++ b/src/blenderbim/blenderbim/core/tool.py @@ -155,7 +155,7 @@ class Document: @interface class Drawing: def activate_view(cls, camera): pass - def copy_drawing_representation(cls, source, dest): pass + def copy_representation(cls, source, dest): pass def create_annotation_object(cls, drawing, object_type): pass def create_camera(cls, name, matrix): pass def create_svg_schedule(cls, schedule): pass diff --git a/src/blenderbim/blenderbim/tool/drawing.py b/src/blenderbim/blenderbim/tool/drawing.py index aa3199b841..c625bbffd1 100644 --- a/src/blenderbim/blenderbim/tool/drawing.py +++ b/src/blenderbim/blenderbim/tool/drawing.py @@ -39,10 +39,11 @@ from blenderbim.bim.module.drawing.prop import get_diagram_scales class Drawing(blenderbim.core.tool.Drawing): @classmethod - def copy_drawing_representation(cls, source, dest): - dest.Representation = ifcopenshell.util.element.copy_deep( - tool.Ifc.get(), source.Representation, exclude=["IfcGeometricRepresentationContext"] - ) + def copy_representation(cls, source, dest): + if source.Representation: + dest.Representation = ifcopenshell.util.element.copy_deep( + tool.Ifc.get(), source.Representation, exclude=["IfcGeometricRepresentationContext"] + ) @classmethod def create_annotation_object(cls, drawing, object_type): diff --git a/src/blenderbim/test/core/test_drawing.py b/src/blenderbim/test/core/test_drawing.py index 3ec2f61d8c..782a423017 100644 --- a/src/blenderbim/test/core/test_drawing.py +++ b/src/blenderbim/test/core/test_drawing.py @@ -248,7 +248,7 @@ class TestDuplicateDrawing: drawing.get_name("drawing").should_be_called().will_return("name") drawing.ensure_unique_drawing_name("name").should_be_called().will_return("unique_name") ifc.run("root.copy_class", product="drawing").should_be_called().will_return("new_drawing") - drawing.copy_drawing_representation("drawing", "new_drawing").should_be_called() + drawing.copy_representation("drawing", "new_drawing").should_be_called() drawing.set_name("new_drawing", "unique_name").should_be_called() drawing.get_drawing_group("new_drawing").should_be_called().will_return("group") ifc.run("group.unassign_group", group="group", product="new_drawing").should_be_called() @@ -257,8 +257,13 @@ class TestDuplicateDrawing: "group.edit_group", group="new_group", attributes={"Name": "unique_name", "ObjectType": "DRAWING"} ).should_be_called() ifc.run("group.assign_group", group="new_group", products=["new_drawing"]).should_be_called() + drawing.get_group_elements("group").should_be_called().will_return(["drawing", "annotation"]) + ifc.run("root.copy_class", product="annotation").should_be_called().will_return("new_annotation") + drawing.copy_representation("annotation", "new_annotation").should_be_called() + ifc.run("group.unassign_group", group="group", product="new_annotation").should_be_called() + ifc.run("group.assign_group", group="new_group", products=["new_annotation"]).should_be_called() drawing.import_drawings().should_be_called() - subject.duplicate_drawing(ifc, drawing, drawing="drawing") + subject.duplicate_drawing(ifc, drawing, drawing="drawing", should_duplicate_annotations=True) class TestRemoveDrawing: diff --git a/src/blenderbim/test/tool/test_drawing.py b/src/blenderbim/test/tool/test_drawing.py index a2ffabc918..a7d3c3960b 100644 --- a/src/blenderbim/test/tool/test_drawing.py +++ b/src/blenderbim/test/tool/test_drawing.py @@ -32,13 +32,13 @@ class TestImplementsTool(NewFile): assert isinstance(subject(), blenderbim.core.tool.Drawing) -class TestCopyDrawingRepresentation(NewFile): +class TestCopyRepresentation(NewFile): def test_run(self): ifc = ifcopenshell.file() tool.Ifc.set(ifc) source = ifc.createIfcAnnotation(Representation=ifc.createIfcProductDefinitionShape()) dest = ifc.createIfcAnnotation() - subject.copy_drawing_representation(source, dest) + subject.copy_representation(source, dest) assert dest.Representation.is_a("IfcProductDefinitionShape")