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 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
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
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