def __init__(self,pathlist,allowG1,diameter,stepover,depth,islandslist=[]): self.outpaths = pathlist self.islands = islandslist self.diameter = diameter self.stepover = stepover self.childrenIslands = [] self.childrenOutpath = [] self.children = [] self.fullpath = [] self.depth = depth self.islandG1SegList = Path("islandG1SegList") self.outPathG1SegList = Path("outPathG1SegList") self.allowG1 = allowG1 maxdepth=100 import sys sys.setrecursionlimit(max(sys.getrecursionlimit(),maxdepth+100)) if depth>maxdepth: return None self.eliminateOutsideIslands() self.inoutprofile() self.interesect() self.removeOutOfProfile() self.removeInsideIslands() self.getNewPathAndIslands() self.getPaths() if len (self.CleanPath)>0: self.recurse()
def pathBoolIntersection(self, basepath, islandpath): #basepath = deepcopy(basepath) #islandpath = deepcopy(islandpath) #find first intersecting segment first = None for i,segment in enumerate(islandpath): if basepath.isInside(segment.midPoint()): first = i if first is None: print("not intersecting paths") return None #generate intersected path newisland = Path("new") A = None for i in xrange(first,2*len(islandpath)+first): j = i%len(islandpath) segment = islandpath[j] if segment.length()<EPS: continue #ignore zero length segments if not basepath.isInside(segment.midPoint()): if A is None: A = segment.A else: if A is not None: newisland.extend(self.findSubpath(basepath,A,segment.A)) print("new",newisland) A = None newisland.append(segment) #for i,seg in enumerate(newisland): # newisland[i].correct(); print("new2",newisland) return newisland
def __init__(self, pathlist, RecursiveDepth, ProfileDir, CutDir, AdditionalCut, Overcuts, CustomRecursiveDepth, ignoreIslands, allowG1, diameter, stepover, depth, islandslist=[]): self.outpaths = pathlist self.islands = islandslist self.diameter = diameter self.stepover = stepover self.RecursiveDepth = RecursiveDepth self.ProfileDir = ProfileDir self.CutDir = CutDir self.AdditionalCut = float(AdditionalCut) self.Overcuts = bool(Overcuts) self.CustomRecursiveDepth = CustomRecursiveDepth self.childrenIslands = [] self.childrenOutpath = [] self.fullpath = [] self.depth = depth self.islandG1SegList = Path("islandG1SegList") self.outPathG1SegList = Path("outPathG1SegList") self.ignoreIslands = ignoreIslands self.allowG1 = allowG1 maxdepthchoice = { "Single profile": 0, "Custom recursive depth": int(self.CustomRecursiveDepth - 1), "Full pocket": 100 } profileDirChoice = {"inside": 1., "outside": -1.} cutDirChoice = {"conventional milling": 1., "climbing milling": -1.} self.selectCutDir = cutDirChoice.get(self.CutDir, 1.) self.profiledir = profileDirChoice.get(self.ProfileDir, 1.) if self.RecursiveDepth == "Full pocket": self.profiledir = 1. #to avoid making full pockets, with full recursive depth, outside the path maxdepth = maxdepthchoice.get(self.RecursiveDepth, 0) maxdepth = min(maxdepth, 999) import sys sys.setrecursionlimit(max(sys.getrecursionlimit(), maxdepth + 1)) if depth > maxdepth: return None self.eliminateOutsideIslands() self.inoutprofile() self.removeOutofProfileLinkingSegs() self.interesect() self.removeOutOfProfile() self.removeInsideIslands() self.getNewPathAndIslands() self.getPaths() if len(self.CleanPath) > 0: self.recurse()
def toPath(self, bid): """convert a block to path""" block = OCV.blocks[bid] paths = [] path = Path(block.name()) self.initPath(bid) start = bmath.Vector(self.cnc.x, self.cnc.y) # get only first path that enters the surface # ignore the deeper ones passno = 0 for line in block: # flatten helical paths line = re.sub(r"\s?z-?[0-9\.]+", "", line) # break after first depth pass if line == "( ---------- cut-here ---------- )": passno = 0 if path: paths.append(path) path = Path(block.name()) if line[:5] == "(pass": passno += 1 if passno > 1: continue cmds = Heuristic.parse_line(line) if cmds is None: continue self.cnc.motionStart(cmds) end = bmath.Vector(self.cnc.xval, self.cnc.yval) if self.cnc.gcode == 0: # rapid move (new block) if path: paths.append(path) path = Path(block.name()) elif self.cnc.gcode == 1: # line if self.cnc.dx != 0.0 or self.cnc.dy != 0.0: path.append(Segment(1, start, end)) elif self.cnc.gcode in (2, 3): # arc xc, yc = self.cnc.motionCenter() center = bmath.Vector(xc, yc) path.append(Segment(self.cnc.gcode, start, end, center)) self.cnc.motionEnd() start = end if path: paths.append(path) return paths
def _findSubpath(self, path, A, B): print("finding", A, B) sub = None for i in xrange(0, len(path) * 2): #iterate twice with wrap around j = i % len(path) seg = path[j] if eq(seg.A, A): sub = Path("subp") print("seg", sub is None, seg) if sub is not None: sub.append(seg) if eq(seg.B, B): break print("found", sub) return sub
def _findSubpath(self, path,A,B): print("finding", A, B) sub = None for i in xrange(0,len(path)*2): #iterate twice with wrap around j = i%len(path) seg = path[j] if eq(seg.A,A): sub = Path("subp") print("seg", sub is None, seg) if sub is not None: sub.append(seg) if eq(seg.B,B): break print("found", sub) return sub
def removeInsideIslands(self): self.CleanPath = [] cleanpath = Path("Path") for path in self.NewPaths : for seg in path : inside = False for island in self.IntersectedIslands : issegin = island.isSegInside(seg)==1 if issegin: if not seg in island: inside = True break if not inside: cleanpath.append(seg) cleanpath = cleanpath.split2contours() self.CleanPath.extend(cleanpath)
def getPaths(self): if len (self.CleanPath)>0: if len(self.islandG1SegList) >0 : self.outPathG1SegList.extend(self.islandG1SegList) if self.allowG1 and len(self.outPathG1SegList)>0: for seg in self.outPathG1SegList : path = Path("SegPath") path.append(seg) self.CleanPath.append(path) self.fullpath.extend(self.CleanPath) return self.CleanPath
def pathBoolIntersection(self, basepath, islandpath): #basepath = deepcopy(basepath) #islandpath = deepcopy(islandpath) #find first intersecting segment first = None for i, segment in enumerate(islandpath): if basepath.isInside(segment.midPoint()): first = i if first is None: print("not intersecting paths") return None #generate intersected path newisland = Path("new") A = None for i in xrange(first, 2 * len(islandpath) + first): j = i % len(islandpath) segment = islandpath[j] if segment.length() < EPS: continue #ignore zero length segments if not basepath.isInside(segment.midPoint()): if A is None: A = segment.A else: if A is not None: newisland.extend(self.findSubpath(basepath, A, segment.A)) print("new", newisland) A = None newisland.append(segment) #for i,seg in enumerate(newisland): # newisland[i].correct(); print("new2", newisland) return newisland
def execute(self, app): #print("go!") blocks = [] paths_base = [] paths_isl = [] for bid in app.editor.getSelectedBlocks(): if app.gcode[bid].operationTest('island'): paths_isl.extend(app.gcode.toPath(bid)) else: paths_base.extend(app.gcode.toPath(bid)) for island in paths_isl: paths_newbase = [] while len(paths_base) > 0: base = paths_base.pop() base.intersectPath(island) island.intersectPath(base) newbase = Path("diff") #Add segments from outside of islands: for i, seg in enumerate(base): if not island.isInside(seg.midPoint()): newbase.append(seg) #Add segments from islands to base for i, seg in enumerate(island): if base.isInside(seg.midPoint( )): #and base.isInside(seg.A) and base.isInside(seg.B): newbase.append(seg) #Eulerize paths_newbase.extend(newbase.eulerize()) #paths_newbase.extend(newbase.split2contours()) paths_base = paths_newbase for base in paths_base: print(base) #base = base.eulerize(True) block = Block("diff") block.extend(app.gcode.fromPath(base)) blocks.append(block) #active = app.activeBlock() app.gcode.insBlocks( -1, blocks, "Diff") #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Diff")) #<<< feed back result
def removeOutOfProfile(self): self.NewPaths = [] newoutpath = Path("path") for path in self.OutOffsetPathList: for seg in path: newoutpath.append(seg) for OutoffsetPath in self.OutOffsetPathList: for path in self.IntersectedIslands : for seg in path : inside = not OutoffsetPath.isSegInside(seg)==-1 if inside: newoutpath.append(seg) purgednewoutpath= newoutpath.split2contours()#list of paths self.NewPaths.extend(purgednewoutpath)
def execute(self, app): #print("go!") blocks = [] paths_base = [] paths_isl = [] for bid in app.editor.getSelectedBlocks(): if app.gcode[bid].operationTest('island'): paths_isl.extend(app.gcode.toPath(bid)) else: paths_base.extend(app.gcode.toPath(bid)) for island in paths_isl: paths_newbase = [] while len(paths_base) > 0: base = paths_base.pop() base.intersectPath(island) island.intersectPath(base) newbase = Path("diff") #Add segments from outside of islands: for i,seg in enumerate(base): if not island.isInside(seg.midPoint()): newbase.append(seg) #Add segments from islands to base for i,seg in enumerate(island): if base.isInside(seg.midPoint()): #and base.isInside(seg.A) and base.isInside(seg.B): newbase.append(seg) #Eulerize paths_newbase.extend(newbase.eulerize()) #paths_newbase.extend(newbase.split2contours()) paths_base = paths_newbase for base in paths_base: print(base) #base = base.eulerize(True) block = Block("diff") block.extend(app.gcode.fromPath(base)) blocks.append(block) #active = app.activeBlock() app.gcode.insBlocks(-1, blocks, "Diff") #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Diff")) #<<< feed back result
def execute(self, app): dragoff = self.fromMm("offset") angleth = self["angle"] swivelz = self.fromMm("swivelz") initdir = self["initdir"] CNC.vars["cutfeed"] = self.fromMm("feed") simulate = self["simulate"] simpreci = self["simpreci"] def initPoint(P, dir, offset): P = Vector(P[0], P[1]) if dir == 'X+': P[0] += offset elif dir == 'X-': P[0] -= offset elif dir == 'Y+': P[1] += offset elif dir == 'Y-': P[1] -= offset return P blocks = [] for bid in app.editor.getSelectedBlocks(): if len(app.gcode.toPath(bid)) < 1: continue opath = app.gcode.toPath(bid)[0] npath = Path("dragknife %s: %s" % (dragoff, app.gcode[bid].name())) if not simulate: #Entry vector ventry = Segment(Segment.LINE, initPoint(opath[0].A, initdir, -dragoff), opath[0].A) #Exit vector vexit = Segment(Segment.LINE, opath[-1].B, initPoint(opath[-1].B, initdir, dragoff)) opath.append(vexit) prevseg = ventry #Generate path with tangential lag for dragknife operation for i, seg in enumerate(opath): #Get adjacent tangential vectors in this point TA = prevseg.tangentEnd() TB = seg.tangentStart() #Compute difference between tangential vectors of two neighbor segments angle = degrees(acos(TA.dot(TB))) #Compute swivel direction arcdir = (TA[0] * TB[1]) - (TA[1] * TB[0]) if arcdir < 0: arcdir = Segment.CW else: arcdir = Segment.CCW #Append swivel if needed (also always do entry/exit) if abs(angle) > angleth or (abs(angle) > 1 and (i == 0 or i == len(opath) - 1)): arca = Segment(arcdir, prevseg.tangentialOffset(dragoff).B, seg.tangentialOffset(dragoff).A, prevseg.B) if swivelz != 0: arca._inside = [swivelz] npath.append(arca) #Append segment with tangential offset if i < len(opath) - 1: npath.append(seg.tangentialOffset(dragoff)) prevseg = seg elif simulate: opath = opath.linearize(simpreci, True) prevknife = initPoint(opath[0].A, initdir, -dragoff) for seg in opath: dist = sqrt((seg.B[0] - prevknife[0])**2 + (seg.B[1] - prevknife[1])**2) move = (seg.B - prevknife).unit() * (dist - dragoff) newknife = prevknife + move if not eq(newknife, prevknife): npath.append(Segment(Segment.LINE, prevknife, newknife)) prevknife = newknife eblock = app.gcode.fromPath(npath) blocks.append(eblock) #active = app.activeBlock() #if active == 0: active+=1 active = -1 #add to end app.gcode.insBlocks( active, blocks, "Dragknife") #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Dragknife")) #<<< feed back result
def pocket(blocks, allowG1, diameter, stepover, name,gcode,items): undoinfo = [] msg = "" newblocks = [] islandslist = [] for bid,block in enumerate(gcode.blocks): if block.operationTest('island'): for islandPath in gcode.toPath(bid): islandslist.append(islandPath) for bid in reversed(blocks): if gcode.blocks[bid].name() in ("Header", "Footer"): continue newpath = [] for path in gcode.toPath(bid): if not path.isClosed(): m = "Path: '%s' is OPEN"%(path.name) if m not in msg: if msg: msg += "\n" msg += m path.close() # Remove tiny segments path.removeZeroLength(abs(diameter)/100.) # Convert very small arcs to lines path.convert2Lines(abs(diameter)/10.) path.directionSet(1) #turn path to CW (conventional when milling inside) D = path.direction() if D==0: D=1 remove = ["cut","reverse","climb","conventional","cw","ccw","pocket"] if name is None: path.name = Block.operationName(path.name, "pocket,conventional,cw", remove) else: path.name = Block.operationName(path.name, name, remove) MyPocket = PocketIsland([path],allowG1,diameter,stepover,0,islandslist) newpathList = MyPocket.getfullpath() #concatenate newpath in a single list and split2contours if allowG1 : MyFullPath = Path("Pocket") for path in newpathList : for seg in path: MyFullPath.append(seg) newpathList = MyFullPath.split2contours() if newpathList: # remember length to shift all new blocks # the are inserted before before = len(newblocks) undoinfo.extend(gcode.importPath(bid+1, newpathList, newblocks, True, False)) new = len(newblocks)-before for i in range(before): newblocks[i] += new gcode.blocks[bid].enable = False gcode.addUndo(undoinfo) # return new blocks inside the blocks list del blocks[:] blocks.extend(newblocks) return msg
class PocketIsland: def __init__(self,pathlist,allowG1,diameter,stepover,depth,islandslist=[]): self.outpaths = pathlist self.islands = islandslist self.diameter = diameter self.stepover = stepover self.childrenIslands = [] self.childrenOutpath = [] self.children = [] self.fullpath = [] self.depth = depth self.islandG1SegList = Path("islandG1SegList") self.outPathG1SegList = Path("outPathG1SegList") self.allowG1 = allowG1 maxdepth=100 import sys sys.setrecursionlimit(max(sys.getrecursionlimit(),maxdepth+100)) if depth>maxdepth: return None self.eliminateOutsideIslands() self.inoutprofile() self.interesect() self.removeOutOfProfile() self.removeInsideIslands() self.getNewPathAndIslands() self.getPaths() if len (self.CleanPath)>0: self.recurse() def eliminateOutsideIslands(self): self.insideIslandList = [] for island in self.islands: for path in self.outpaths : if island.isPathInside(path)>=0: self.insideIslandList.append(island) def inoutprofile(self): if self.depth == 0: offset = -self.diameter / 2.0 else: offset = -self.diameter*self.stepover self.OutOffsetPathList = [] for path in self.outpaths : p1=p2=None if len(path)>0: p1 = path[0].A dir = path.direction() opath = path.offset(offset*float(dir)) opath.intersectSelf() opath.removeExcluded(path, abs(offset)) if len(opath)>0: p2 = opath[0].A self.OutOffsetPathList.append(opath) if self.depth >0 and p1 is not None: self.outPathG1SegList.append(Segment(Segment.LINE,p1,p2)) self.islandOffPaths = [] for island in self.insideIslandList : p3=p4=None if len(island)>0: p3 = island[0].A dir = island.direction() offIsl = island.offset(-offset*float(dir)) if len(offIsl)>0: p4 = offIsl[0].A if self.depth >0 and p3 is not None and p4 is not None : self.islandG1SegList.append(Segment(Segment.LINE,p3,p4)) offIsl.intersectSelf() offIsl.removeExcluded(island, abs(offset)) self.islandOffPaths.append(offIsl) def interesect(self): self.IntersectedIslands = [] for island in self.islandOffPaths : for path in self.OutOffsetPathList : path.intersectPath(island) island.intersectPath(path) for island2 in self.islandOffPaths : island.intersectPath(island2) self.IntersectedIslands.append(island) def removeOutOfProfile(self): self.NewPaths = [] newoutpath = Path("path") for path in self.OutOffsetPathList: for seg in path: newoutpath.append(seg) for OutoffsetPath in self.OutOffsetPathList: for path in self.IntersectedIslands : for seg in path : inside = not OutoffsetPath.isSegInside(seg)==-1 if inside: newoutpath.append(seg) purgednewoutpath= newoutpath.split2contours()#list of paths self.NewPaths.extend(purgednewoutpath) def removeInsideIslands(self): self.CleanPath = [] cleanpath = Path("Path") for path in self.NewPaths : for seg in path : inside = False for island in self.IntersectedIslands : issegin = island.isSegInside(seg)==1 if issegin: if not seg in island: inside = True break if not inside: cleanpath.append(seg) cleanpath = cleanpath.split2contours() self.CleanPath.extend(cleanpath) def getNewPathAndIslands(self): if len(self.CleanPath)==1: self.childrenOutpath = self.CleanPath else : for elt in self.CleanPath: #List of paths for elt2 in self.CleanPath : ins = elt2.isPathInside(elt)==1 ident = elt2.isidentical(elt) addedelt2 = elt2 in self.childrenIslands if ins and not ident and not addedelt2 : self.childrenIslands.append(elt2) for elt in self.CleanPath: #List of paths for elt2 in self.CleanPath: if not elt2 in self.childrenIslands and not elt2 in self.childrenOutpath: self.childrenOutpath.append(elt2) def getPaths(self): if len (self.CleanPath)>0: if len(self.islandG1SegList) >0 : self.outPathG1SegList.extend(self.islandG1SegList) if self.allowG1 and len(self.outPathG1SegList)>0: self.CleanPath.append(self.outPathG1SegList) self.fullpath.extend(self.CleanPath) return self.CleanPath def recurse(self): pcket = PocketIsland(self.childrenOutpath,self.allowG1,self.diameter,self.stepover,self.depth+1,self.childrenIslands) self.fullpath.extend(pcket.getfullpath()) def getfullpath(self) : return self.fullpath
def pocket(selectedblocks, RecursiveDepth,ProfileDir,CutDir,AdditionalCut,Overcuts, CustomRecursiveDepth, ignoreIslands, allowG1, diameter, stepover, name,gcode,app): undoinfo = [] msg = "" newblocks = [] allblocks = gcode.blocks islandslist = [] outpathslist= [] ignoreIslandschoicedict = { "Regard all islands except tabs":0, "Ignore all islands":1, "Regard only selected islands":2, } ignoreIslandschoice = ignoreIslandschoicedict.get(ignoreIslands,0) for bid,block in enumerate(allblocks):#all blocks if block.operationTest('island')and not block.operationTest('tab'): if ignoreIslandschoice==0: for islandPath in gcode.toPath(bid): islandslist.append(islandPath) for bid in reversed(selectedblocks):#selected blocks if allblocks[bid].name() in ("Header", "Footer"): continue newpath = [] block = allblocks[bid] if block.operationTest('island')and not block.operationTest('tab') and ignoreIslandschoice==2: for islandPath in gcode.toPath(bid): islandslist.append(islandPath) for path in gcode.toPath(bid): if not path.isClosed(): m = "Path: '%s' is OPEN"%(path.name) if m not in msg: if msg: msg += "\n" msg += m path.close() # Remove tiny segments path.removeZeroLength(abs(diameter)/100.) # Convert very small arcs to lines path.convert2Lines(abs(diameter)/10.) if not block.operationTest('island'): outpathslist.append(path) MyPocket = PocketIsland(outpathslist,RecursiveDepth,ProfileDir,CutDir,AdditionalCut, Overcuts,CustomRecursiveDepth, ignoreIslands, allowG1,diameter,stepover,0,app,islandslist) newpathList = MyPocket.getfullpath() #concatenate newpath in a single list and split2contours if allowG1 : MyFullPath = Path("Pocket") for path in newpathList : for seg in path: MyFullPath.append(seg) newpathList = MyFullPath.split2contours() if newpathList: # remember length to shift all new blocks # the are inserted before before = len(newblocks) undoinfo.extend(gcode.importPath(bid+1, newpathList, newblocks, True, False)) new = len(newblocks)-before for i in range(before): newblocks[i] += new allblocks[bid].enable = False gcode.addUndo(undoinfo) # return new blocks inside the blocks list del selectedblocks[:] selectedblocks.extend(newblocks) return msg
def execute(self, app): dragoff = self.fromMm("offset") angleth = self["angle"] swivelz = self.fromMm("swivelz") initdir = self["initdir"] CNC.vars["cutfeed"] = self.fromMm("feed") simulate = self["simulate"] simpreci = self["simpreci"] def initPoint(P, dir, offset): P = Vector(P[0], P[1]) if dir == 'X+': P[0]+=offset elif dir == 'X-': P[0]-=offset elif dir == 'Y+': P[1]+=offset elif dir == 'Y-': P[1]-=offset return P blocks = [] for bid in app.editor.getSelectedBlocks(): if len(app.gcode.toPath(bid)) < 1: continue opath = app.gcode.toPath(bid)[0] npath = Path("dragknife %s: %s"%(dragoff,app.gcode[bid].name())) if not simulate: #Entry vector ventry = Segment(Segment.LINE, initPoint(opath[0].A, initdir, -dragoff), opath[0].A) #Exit vector vexit = Segment(Segment.LINE, opath[-1].B, initPoint(opath[-1].B, initdir, dragoff)) opath.append(vexit) prevseg = ventry #Generate path with tangential lag for dragknife operation for i,seg in enumerate(opath): #Get adjacent tangential vectors in this point TA = prevseg.tangentEnd() TB = seg.tangentStart() #Compute difference between tangential vectors of two neighbor segments angle = degrees(acos(TA.dot(TB))) #Compute swivel direction arcdir = ( TA[0] * TB[1] ) - ( TA[1] * TB[0] ) if arcdir < 0: arcdir = Segment.CW else: arcdir = Segment.CCW #Append swivel if needed (also always do entry/exit) if abs(angle) > angleth or (abs(angle) > 1 and ( i == 0 or i == len(opath)-1 )): arca = Segment(arcdir, prevseg.tangentialOffset(dragoff).B, seg.tangentialOffset(dragoff).A, prevseg.B) if swivelz !=0: arca._inside = [swivelz] npath.append(arca) #Append segment with tangential offset if i < len(opath)-1: npath.append(seg.tangentialOffset(dragoff)) prevseg = seg elif simulate: opath = opath.linearize(simpreci, True) prevknife = initPoint(opath[0].A, initdir, -dragoff) for seg in opath: dist = sqrt((seg.B[0]-prevknife[0])**2+(seg.B[1]-prevknife[1])**2) move = ( seg.B - prevknife ).unit() * ( dist - dragoff ) newknife = prevknife + move if not eq(newknife, prevknife): npath.append(Segment(Segment.LINE, prevknife, newknife)) prevknife = newknife eblock = app.gcode.fromPath(npath) blocks.append(eblock) #active = app.activeBlock() #if active == 0: active+=1 active=-1 #add to end app.gcode.insBlocks(active, blocks, "Dragknife") #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Dragknife")) #<<< feed back result
class PocketIsland: def __init__(self,pathlist,RecursiveDepth,ProfileDir,CutDir,AdditionalCut, Overcuts,CustomRecursiveDepth, ignoreIslands, allowG1,diameter,stepover,depth,app,islandslist=[]): self.outpaths = pathlist self.islands = islandslist self.diameter = diameter self.stepover = stepover self.RecursiveDepth=RecursiveDepth self.ProfileDir=ProfileDir self.CutDir=CutDir self.AdditionalCut=float(AdditionalCut) self.Overcuts = bool(Overcuts) self.CustomRecursiveDepth=CustomRecursiveDepth self.childrenIslands = [] self.childrenOutpath = [] self.fullpath = [] self.depth = depth self.islandG1SegList = Path("islandG1SegList") self.outPathG1SegList = Path("outPathG1SegList") self.ignoreIslands = ignoreIslands self.allowG1 = allowG1 self.app = app maxdepthchoice = {"Single profile":0, "Custom offset count":int(self.CustomRecursiveDepth-1), "Full pocket":100} profileDirChoice = {"inside":1.,"outside":-1.} cutDirChoice = {False:1.,True:-1.} self.selectCutDir = cutDirChoice.get(self.CutDir,1.) self.profiledir = profileDirChoice.get(self.ProfileDir,1.) if self.RecursiveDepth=="Full pocket" : self.profiledir=1.#to avoid making full pockets, with full recursive depth, outside the path maxdepth=maxdepthchoice.get(self.RecursiveDepth,0) maxdepth = min(maxdepth,999) sys.setrecursionlimit(max(sys.getrecursionlimit(),maxdepth+1)) if depth>maxdepth: return None self.app.setStatus(_("Generate pocket path")+" - depth:"+str(self.depth+1)+" -> eliminateOutsideIslands",True) self.eliminateOutsideIslands() self.app.setStatus(_("Generate pocket path")+" - depth:"+str(self.depth+1)+" -> inoutprofile",True) self.inoutprofile() self.app.setStatus(_("Generate pocket path")+" - depth:"+str(self.depth+1)+" -> removeOutofProfileLinkingSegs",True) self.removeOutofProfileLinkingSegs() self.app.setStatus(_("Generate pocket path")+" - depth:"+str(self.depth+1)+" -> interesect",True) self.interesect() self.app.setStatus(_("Generate pocket path")+" - depth:"+str(self.depth+1)+" -> removeOutOfProfile",True) self.removeOutOfProfile() self.app.setStatus(_("Generate pocket path")+" - depth:"+str(self.depth+1)+" -> removeInsideIslands",True) self.removeInsideIslands() self.app.setStatus(_("Generate pocket path")+" - depth:"+str(self.depth+1)+" -> getNewPathAndIslands",True) self.getNewPathAndIslands() self.getPaths() if len (self.CleanPath)>0: self.recurse() def eliminateOutsideIslands(self): self.insideIslandList = [] for island in self.islands: for path in self.outpaths : if island.isPathInside(path)>=0: self.insideIslandList.append(island) def inoutprofile(self): if self.depth == 0: self.offset = -self.diameter / 2.0 +self.AdditionalCut self.offsetLastPass = self.offset else: self.offset = -self.diameter*self.stepover self.offsetLastPass = -min(self.diameter*self.stepover/2.,self.diameter*0.49) self.OutOffsetPathList = [] for path in self.outpaths : p1=p2=None if len(path)>0: p1 = path[0].A if self.depth == 0 : path.directionSet(self.selectCutDir*float(self.profiledir)) direct = path.direction() opathCopy = path.offset(self.profiledir*self.offset*float(direct)) points = opathCopy.intersectSelf() opathCopy.removeExcluded(path, abs(self.offset)) if len(opathCopy)>0: #there remains some path after full offset : not the last pass opath = path.offset(self.profiledir*self.offset*float(direct)) offset = self.offset else:# nothing remaining after the last pass => apply offsetLastPass opath = path.offset(self.profiledir*self.offsetLastPass*float(direct)) offset = self.offsetLastPass opath.intersectSelf() if len (opath)>0 : opath.removeExcluded(path, abs(offset)) opath.removeZeroLength(abs(self.diameter)/100.) # opath.removeZeroLength(abs(EPS*10.)) opath.convert2Lines(abs(self.diameter)/10.) if self.depth == 0 and self.Overcuts : opath.overcut(self.profiledir*self.offset*float(direct)) if len(opath)>0: p2 = opath[0].A self.OutOffsetPathList.append(opath) if self.depth >0 and p1 is not None: self.outPathG1SegList.append(Segment(Segment.LINE,p1,p2)) self.islandOffPaths = [] for island in self.insideIslandList : p3=p4=None if len(island)>0: p3 = island[0].A if self.depth == 0 : island.directionSet(-self.selectCutDir*float(self.profiledir)) direct = island.direction() offIsl = island.offset(-self.profiledir*self.offset*float(direct)) offIsl.intersectSelf() if len(offIsl)>0 : offIsl.removeExcluded(island, abs(self.offset)) offIsl.removeZeroLength(abs(self.diameter)/100.) # offIsl.removeZeroLength(abs(EPS*10.)) offIsl.convert2Lines(abs(self.diameter)/10.) if len(offIsl)>0: p4 = offIsl[0].A if self.depth >0 and p3 is not None and p4 is not None : self.islandG1SegList.append(Segment(Segment.LINE,p3,p4)) if self.depth == 0 and self.Overcuts : offIsl.overcut(-self.profiledir*self.offset*float(direct)) self.islandOffPaths.append(offIsl) def removeOutofProfileLinkingSegs(self): self.tmpoutG1 = deepcopy(self.outPathG1SegList) self.tmpinG1 = deepcopy(self.islandG1SegList) for i,seg in enumerate(self.outPathG1SegList) : for path in self.islandOffPaths : inside =path.isSegInside(seg)==1#outseg inside offsetislands =>pop if inside and seg in self.tmpoutG1: self.tmpoutG1.remove(seg) for i,seg in enumerate(self.islandG1SegList): for path in self.OutOffsetPathList : outside = path.isSegInside(seg)<1#inseg outside offsetOutpaths => pop if outside and seg in self.tmpinG1 : self.tmpinG1.remove(seg) self.outPathG1SegList = self.tmpoutG1 self.islandG1SegList = self.tmpinG1 def interesect(self): self.IntersectedIslands = [] for island in self.islandOffPaths : for path in self.OutOffsetPathList : path.intersectPath(island) island.intersectPath(path) for island2 in self.islandOffPaths : island.intersectPath(island2) self.IntersectedIslands.append(island) def removeOutOfProfile(self): self.NewPaths = [] newoutpath = Path("path") for path in self.OutOffsetPathList: for seg in path: newoutpath.append(seg) for OutoffsetPath in self.OutOffsetPathList: for path in self.IntersectedIslands : for seg in path : inside = not OutoffsetPath.isSegInside(seg)==-1 if inside: newoutpath.append(seg) purgednewoutpath= newoutpath.split2contours()#list of paths self.NewPaths.extend(purgednewoutpath) def removeInsideIslands(self): self.CleanPath = [] cleanpath = Path("Path") for path in self.NewPaths : for seg in path : inside = False for island in self.IntersectedIslands : issegin = island.isSegInside(seg)==1 if issegin: if not seg in island: inside = True break if not inside: cleanpath.append(seg) cleanpath = cleanpath.split2contours() self.CleanPath.extend(cleanpath) def getNewPathAndIslands(self): if len(self.CleanPath)==1: self.childrenOutpath = self.CleanPath else : for elt in self.CleanPath: #List of paths for elt2 in self.CleanPath : ins = elt2.isPathInside(elt)==1 ident = elt2.isidentical(elt) addedelt2 = elt2 in self.childrenIslands if ins and not ident and not addedelt2 : self.childrenIslands.append(elt2) for elt in self.CleanPath: #List of paths for elt2 in self.CleanPath: if not elt2 in self.childrenIslands and not elt2 in self.childrenOutpath: self.childrenOutpath.append(elt2) def getPaths(self): if len (self.CleanPath)>0: if len(self.islandG1SegList) >0 : self.outPathG1SegList.extend(self.islandG1SegList) if self.allowG1 and len(self.outPathG1SegList)>0: for seg in self.outPathG1SegList : path = Path("SegPath") path.append(seg) self.CleanPath.append(path) self.fullpath.extend(self.CleanPath) return self.CleanPath def recurse(self): pcket = PocketIsland(self.childrenOutpath,self.RecursiveDepth,self.ProfileDir, self.CutDir,self.AdditionalCut,self.Overcuts, self.CustomRecursiveDepth, self.ignoreIslands, self.allowG1,self.diameter,self.stepover,self.depth+1,self.app,self.childrenIslands) self.fullpath.extend(pcket.getfullpath()) def getfullpath(self) : return self.fullpath