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 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 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 findSegment(self, path, A, B): #FIXME: not used for now... for seg in path: if seg.A == A and seg.B == B: return seg elif seg.A == B and seg.B == A: seg.invert() return seg else: return Segment(1, A, B)
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 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