import FreeCADGui as Gui import FreeCAD as App class AHB_View_Annotate_Detail: def GetResources(self): return {"MenuText": "Annotate sub-assembly", "ToolTip": "Annotates each part of selected sub-assembly balloons", "Pixmap": "" } def IsActive(self): return True def Activated(self): workbench = Gui.getWorkbench("AssemblyHandbookWorkbench") #: :type workbench: AssemblyHandbookWorkbench if len(Gui.Selection.getSelection()) == 0: raise Exception("Please select at least one annotation balloon") view = None for balloon in Gui.Selection.getSelection(): if balloon.TypeId != 'TechDraw::DrawViewBalloon' or "Assembly_handbook_Source" not in balloon.PropertiesList: raise Exception("All selected objects must be annotation balloons") if view is not None and view != balloon.SourceView or balloon.SourceView is None: raise Exception("Please only select balloons from the same view") view = balloon.SourceView overlay_view = workbench.techDrawExtensions.getOverlayView(view) doc = view.Document page = workbench.techDrawExtensions.getViewPage(view) if page is None: raise Exception("Can't find page in which the selected view is located") balloons_to_split = Gui.Selection.getSelection() for balloon in balloons_to_split: sub_assembly_link = workbench.techDrawExtensions.getBalloonSourcePart(balloon) sub_assembly = sub_assembly_link.LinkedObject if sub_assembly.TypeId != 'App::Part': continue def list_first_level_sub_parts(group): results = [] for obj in group.Group: if obj.TypeId == 'App::Link': results.append(obj) elif obj.TypeId == 'Part::FeaturePython' and hasattr(obj, 'LinkedObject'): # variant link results.append(obj) elif hasattr(obj, 'Group'): results.extend(list_first_level_sub_parts(obj)) return results parts = list_first_level_sub_parts(sub_assembly) for part in parts: workbench.techDrawExtensions.add_or_update_balloon(view, part, workbench.techDrawExtensions.getBalloonSourcePartPath(balloon)) from ahb_command import AHB_CommandWrapper AHB_CommandWrapper.addGuiCommand('AHB_view_annotate_detail', AHB_View_Annotate_Detail())