try: del App.Flatpack except: pass ad = Gui.ActiveDocument.Document def selectionContainsAssembly(): sel = Gui.Selection.getSelection() if not sel or not hasattr(sel[0], 'Type') or sel[0].Type != 'Assembly': return False return sel[0] class FlatpackGroupViewProvider(): def __init__(self, group): self.Proxy = group class FlatpackWBTools(): def createDatumPlaneOnLink(self, part, link): plane = part.newObject('PartDesign::Plane', 'DatumPlane') return plane def createGroup(self, asm): pack = ad.addObject('App::Part', 'Flatpack') pack.Type = 'Flatpack' FlatpackGroupViewProvider(pack) #asm.Visibility = False self.links = self.findLinks(asm) for link in self.links: attached_to = ad.getObject(link.AttachedTo.split('#')[1]) # not much to do when attached to the root if attached_to.Name == 'LCS_Origin': print('Skipping LCS_Origin') continue print(link.Name, link.Placement) # find all the App::Links that are on the same Plane as this one coplaner_links = [] for i in [ l for l in link.OutList if l.TypeId == 'PartDesign::CoordinateSystem' ]: if l not in coplaner_links and abs(link.Placement.Base.z - l.Placement.Base.z) < 0.000001: print(link.Label, l.Label, abs(link.Placement.Base.z- l.Placement.Base.z), link.Placement.Base.z==l.Placement.Base.z) coplaner_links.append(l) print('coplaner_links', coplaner_links) for cp_link in coplaner_links: base = cp_link.Placement.Base # create DatumPlane for Sketch Support # TODO track planes per Z offset plane = self.createDatumPlaneOnLink(link.LinkedObject, link) plane.Visibility = False plane.Placement.Base.z = base.z # create Sketch for drawing attachment features sketch = self.createSketch(link.LinkedObject, plane) sketch.Visibility = False # TODO needs input parameters from 1) the Flatpack object 2) the depth of the LinkedObject sketch.addGeometry(Part.LineSegment(App.Vector(base.x-10, base.y, 0), App.Vector(base.x+10, base.y, 0)), False) sketch.addGeometry(Part.LineSegment(App.Vector(base.x+10, base.y, 0), App.Vector(base.x+10, base.y + 5, 0)), False) sketch.addGeometry(Part.LineSegment(App.Vector(base.x+10, base.y + 5, 0), App.Vector(base.x-10, base.y + 5, 0)), False) sketch.addGeometry(Part.LineSegment(App.Vector(base.x-10, base.y + 5, 0), App.Vector(base.x-10, base.y, 0)), False) # TODO determine if Feature should be Pad or Pocket, based on inside/outside of BoundingBox pad = link.LinkedObject.newObject('PartDesign::Pad', 'Pad') pad.Profile = sketch # TODO get value from elsewhere pad.Length = 10 pad.Midplane = 1 pad.Refine = 1 def createSketch(self, part, attached_to): sketch = part.newObject('Sketcher::SketchObject', 'Sketch') # determine face orientation.... sketch.Support = (attached_to, ['Face001']) sketch.MapMode = 'FlatFace' return sketch def findAssembly(self): sel = selectionContainsAssembly() if not sel: return False return sel def findLinks(self, asm, discard_origin = False): return [] if not asm else [el for el in asm.OutList if el.TypeId == 'App::Link'] def getLinkOwner(self, link): return link.LinkedObject FP = App.Flatpack = FlatpackWBTools() asm = Gui.ActiveDocument.Document.getObject('Model') asm = FP.findAssembly() if asm: FP.createGroup(asm) else: print('No Assembly selected.') ad.recompute()