def pocket(self, args, dbg=None): if dbg is None: dbg = self.dbg layer = args[1] cfg = self.cfg # dir = CCW # if cfg.dir is not None and cfg.dir == 'CW': # dir = CW stepOver = cfg.endMillSize * self.stepOver cfg.ncInit() segments = cfg.dxfInput.getPath(layer) pco = PyclipperOffset() mp = cfg.getMillPath() self.last = cfg.mill.last for seg in segments: self.pDir = pathDir(seg) pco.Clear() mainPath = [] for (i, l) in enumerate(seg): l.draw() if dbg: l.prt() if l.type == LINE: mainPath.append(intScale(l.p0)) elif l.type == ARC: self.arcLines(mainPath, l, dbg=dbg) if dbg: dprt() for (i, p) in enumerate(mainPath): (x, y) = floatScale(p) dprt("%3d (%7.4f %7.4f)" % (i, x, y)) dprt() pco.AddPath(mainPath, pyclipper.JT_ROUND, \ pyclipper.ET_CLOSEDPOLYGON) offset = cfg.endMillSize / 2.0 + cfg.finishAllowance step = 0 offsetPaths = [] while True: result = pco.Execute(-int(offset * SCALE)) if dbg: dprt("%2d offset %7.4f results %d" % \ (step, offset, len(result))) if len(result) == 0: break rData = [] for (rNum, r) in enumerate(result): # convert from list of points to lines if self.arcs: pLast = floatScale(r[-1]) index = 0 maxDist = -1 for (i, p) in enumerate(r): p = floatScale(p) dist = xyDist(p, pLast) if dbg: dprt("%3d (%7.4f %7.4f) dist %9.6f" % \ (i, p[0], p[1], dist)) if dist > maxDist: maxDist = dist index = i r[i] = p pLast = p r = r[index:] + r[:index] if dbg: dprt("index %d maxDist %7.4f" % (index, maxDist)) pLast = r[-1] dprt("pLast (%7.4f %7.4f)" % (pLast[0], pLast[1])) for (i, p) in enumerate(r): dprt("%3d (%7.4f %7.4f) dist %9.6f" % \ (i, p[0], p[1], xyDist(p, pLast))) pLast = p dprt() path = self.makePath(r, step, rNum, dbg) else: pLast = floatScale(r[-1]) path = [] for (i, p) in enumerate(r): p = floatScale(p) if dbg: dprt("%3d (%7.4f %7.4f)" % (i, p[0], p[1])) l = Line(pLast, p, i) txt = "s %d r %d i %d" % (step, rNum, i) l.label(txt) path.append(l) pLast = p result[rNum] = path if dbg: dprt() for l in path: l.prt() dprt() # find shortest distance to each path oData = [] for (oNum, oPath) in enumerate(offsetPaths): lEnd = oPath[-1] pEnd = lEnd.p1 minDist = MAX_VALUE index = None for (i, l) in enumerate(path): dist = xyDist(pEnd, l.p0) if dist < minDist: minDist = dist index = i oData.append((index, minDist)) rData.append(oData) # connect to nearest path if dbg and len(result) > 1: dprt("multiple results") oConnect = [False] * len(offsetPaths) while True: minDist = MAX_VALUE index = None rPath = None for (rNum, oData) in enumerate(rData): if oData == None: continue rPath = rNum for (oNum, (i, dist)) in enumerate(oData): if dbg: dprt("step %d rNum %d Onum %d index %3d "\ "dist %9.6f" % \ (step, rNum, oNum, i, dist)) if not oConnect[oNum] and dist < minDist: minDist = dist index = i rIndex = rNum oIndex = oNum if rPath is None: break if index is not None: # connect path if dbg: dprt("connect rIndex %d index %3d to "\ "oIndex %d dist %9.6f" % \ (rIndex, index, oIndex, minDist)) path = result[rIndex] rData[rIndex] = None oConnect[oIndex] = True oPath = offsetPaths[oIndex] oPath.append(Line(oPath[-1].p1, path[index].p0)) oPath += path[index:] + path[:index] else: # add new path if dbg: dprt("add rPath %d oNum %d" % \ (rPath, len(offsetPaths))) rData[rPath] = None path = result[rPath] path = self.closest(path) offsetPaths.append(path) offset += stepOver step += 1 if step > 99: break for path in offsetPaths: mp.millPath(path, closed=False, minDist=False)
def makePath(self, points, step, rNum, dbg=False): if False: r = 1 for i in range(4): a0 = float(i) * pi / 2 + pi / 4 a = a0 p0 = (r * cos(a), r * sin(a)) for j in range(2): tmp = (pi, -pi)[j] a = a0 + tmp / 2 p1 = (r * cos(a), r * sin(a)) a = a0 + tmp / 1 p2 = (r * cos(a), r * sin(a)) self.pointsArc(p0, p1, p2) dprt() sys.exit() numPoints = len(points) pLast = points[-1] i = 0 path = [] # points.append(points[0]) o0 = orientation(pLast, points[0], points[1]) if dbg: dprt("path orientation %s" % oStr(o0)) while i < numPoints: p0 = points[i] if dbg: dprt("i %3d (%7.4f %7.4f)" % (i, p0[0], p0[1])) d0 = xyDist(p0, pLast) j = i + 1 pa = p0 while j < numPoints - 1: pj = points[j] dist = xyDist(pa, pj) if abs(dist - d0) > 0.001: if dbg: dprt("dist %9.6f d0 %9.6f" % (dist, d0)) break j += 1 pa = pj delta = j - i if delta < 4: l = Line(pLast, p0, i) txt = "s %d r %d i %d" % (step, rNum, i) l.label(txt) i += 1 pLast = p0 else: p1 = points[i + delta / 2] (c, r) = self.pointsArc(pLast, p1, pa) o = orientation(pLast, p1, pa) if o != o0: (pLast, pa) = (pa, pLast) a0 = degAtan2(pLast[1] - c[1], pLast[0] - c[0]) a1 = degAtan2(pa[1] - c[1], pa[0] - c[0]) l = Arc(c, r, a0, a1, direction=o) if dbg: dprt("arc %s %2d i %d (%7.4f %7.4f) %8.3f "\ " %d (%7.4f %7.4f) %8.3f" % \ (oStr(o), delta, i, pLast[0], pLast[1], a0, \ j, pa[0], pa[1], a1)) i = j pLast = pa if dbg: l.prt() path.append(l) return(path)