def generate(self, board_width, board_height, number_of_pieces, random_seed=0, tap_shape='basic', threshold=3.0): blocks = [] block = Block(self.name) random.seed(random_seed) Arc.reset_used_arcs() Arc.set_diff_threshold(threshold) puzzle_cuts = self.__class__.make_puzzle_cuts(board_width, board_height, number_of_pieces, tap_shape, threshold) # Draw puzzle cuts x = 0 y = 0 for i in range(0, int(self.thickness / self.step_z)): for cut in puzzle_cuts: block.append(CNC.zsafe()) block.append(CNC.grapid(x + cut[0].x, y + cut[0].y)) block.append(CNC.zenter(0.0)) block.append(CNC.fmt("f", self.cut_feed)) block.append(CNC.zenter(-(i + 1) * self.step_z)) for arc in cut: if arc.r: block.append( CNC.garc(arc.direction, x + arc.x, y + arc.y, r=arc.r)) blocks.append(block) # Draw border block = Block(self.name + "_border") block.append(CNC.zsafe()) block.append(CNC.grapid(x, y)) for i in range(0, int(self.thickness / self.step_z)): block.append(CNC.fmt("f", self.cut_feed)) block.append(CNC.zenter(-(i + 1) * self.step_z)) block.append(CNC.gline(x + board_width, y)) block.append(CNC.gline(x + board_width, y + board_height)) block.append(CNC.gline(x, y + board_height)) block.append(CNC.gline(x, y)) block.append(CNC.zsafe()) blocks.append(block) return blocks
def slice(self, verts, faces, z, zout=None): block = Block("slice %f" % (float(z))) #FIXME: slice along different axes plane_orig = (0, 0, z) #z height to slice plane_norm = (0, 0, 1) #Crosscut contours = meshcut.cross_section(verts, faces, plane_orig, plane_norm) #Flatten contours if zout is not None: for contour in contours: for segment in contour: segment[2] = zout #Contours to G-code for contour in contours: #print(contour) first = contour[0] block.append("g0 x%f y%f z%f" % (first[0], first[1], first[2])) for segment in contour: block.append("g1 x%f y%f z%f" % (segment[0], segment[1], segment[2])) block.append("g1 x%f y%f z%f" % (first[0], first[1], segment[2])) block.append("( ---------- cut-here ---------- )") if block: del block[-1] if not block: block = None return block
def execute(self, app): maxseg = self.fromMm("maxseg") splitlines = self["splitlines"] #print("go!") blocks = [] for bid in app.editor.getSelectedBlocks(): if len(app.gcode.toPath(bid)) < 1: continue #nblock = Block("flat "+app.gcode[bid].name()) #for i in app.gcode[bid]: # nblock.append(re.sub(r"\s?z-?[0-9\.]+","",i)) #blocks.append(nblock) eblock = Block("lin "+app.gcode[bid].name()) opath = app.gcode.toPath(bid)[0] npath = opath.linearize(maxseg, splitlines) eblock = app.gcode.fromPath(npath,eblock) blocks.append(eblock) #active = app.activeBlock() #if active == 0: active+=1 active=-1 #add to end app.gcode.insBlocks(active, blocks, "Linearized") #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Linearize")) #<<< feed back result
def calc(self,x,y,depth,peck,dwell,drillFeed,safeZforG0): self.safeZforG0 =float(abs(safeZforG0)) peck=abs(float(peck)) currentz=0.0 self.blocks = [] self.block = Block(self.name) self.block.append(CNC.grapid(x=x,y=y)) self.block.append(CNC.grapid(z=CNC.vars["safe"])) self.accelerateIfNeeded(0.0,drillFeed) self.block.append("(entered)") while(currentz>depth): currentz-=peck if currentz < depth: currentz = depth kwargs={"f":float(drillFeed)} self.block.append(CNC.gline(None,None,float(currentz),**kwargs)) if self.safeZforG0 >0: self.block.append(CNC.grapid(z=0.0+self.safeZforG0)) else : self.block.append(CNC.grapid(z=CNC.vars["safe"])) self.block.append("g4 %s"%(CNC.fmt("p",float(dwell)))) if currentz > depth: self.accelerateIfNeeded(currentz,drillFeed) self.block.append("(exiting)") self.block.append(CNC.grapid(z=CNC.vars["safe"])) self.blocks.append(self.block) return self.blocks
def execute(self, app): preci = self.fromMm("preci") linpreci = self.fromMm("linpreci") numseg = self["numseg"] #print("go!") blocks = [] for bid in app.editor.getSelectedBlocks(): if len(app.gcode.toPath(bid)) < 1: continue #nblock = Block("flat "+app.gcode[bid].name()) #for i in app.gcode[bid]: # nblock.append(re.sub(r"\s?z-?[0-9\.]+","",i)) #blocks.append(nblock) eblock = Block("fit " + app.gcode[bid].name()) npath = app.gcode.toPath(bid)[0] npath = npath.mergeLines(linpreci) npath = npath.arcFit(preci, numseg) if npath.length() <= 0: #FIXME: not sure how this could happen print("Warning: ignoring zero length path!") continue eblock = app.gcode.fromPath(npath, eblock) blocks.append(eblock) #active = app.activeBlock() #if active == 0: active+=1 active = -1 #add to end app.gcode.insBlocks( active, blocks, "Arc fit") #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Arc fit")) #<<< feed back result
def insertBlock(self, event=None): active = self.index(ACTIVE) if self._items: bid, lid = self._items[active] bid += 1 else: bid = 0 block = Block() block.expand = True block.append("g0 x0 y0") block.append("g1 z0") block.append(CNC.zsafe()) self.gcode.addUndo(self.gcode.addBlockUndo(bid,block)) self.selection_clear(0,END) self.fill() # find location of new block while active < self.size(): if self._items[active][0] == bid: break active += 1 self.selection_set(active) self.see(active) self.activate(active) self.edit() self.winfo_toplevel().event_generate("<<Modified>>")
def execute(self, app): rdoc = self["rdoc"] radius = self["dia"] / 2 cw = self["cw"] #print("go!") blocks = [] for bid in app.editor.getSelectedBlocks(): #print(blocks[bid]) path = app.gcode.toPath(bid)[0] #print(path) block = Block("trochoid") for segment in path: #print(segment.A) #block.append("g0 x0 y0") #block.append("g1 x10 y10") #block.append("g1 x20 y10") #block.append("g0 x0 y0") block.extend(self.trochoid(segment, rdoc, radius, cw)) blocks.append(block) active = app.activeBlock() app.gcode.insBlocks( active, blocks, "Trochoidal created" ) #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Trochoidal")) #<<< feed back result
def make(self, n=2, size=100, depth=0): self.n = n self.size = size self.depth = depth blocks = [] block = Block(self.name) xi, yi = zip(*(self.hilbert(0.0, 0.0, size, 0.0, 0.0, size, n))) block.append(CNC.zsafe()) block.append(CNC.grapid(xi[0], yi[0])) currDepth = 0. stepz = CNC.vars['stepz'] if stepz == 0: stepz = 0.001 #avoid infinite while loop while True: currDepth -= stepz if currDepth < self.depth: currDepth = self.depth block.append(CNC.zenter(currDepth)) block.append(CNC.gcode(1, [("f", CNC.vars["cutfeed"])])) for x, y in zip(xi, yi): block.append(CNC.gline(x, y)) if currDepth <= self.depth: break block.append(CNC.zsafe()) blocks.append(block) return blocks
def make(self, Nlines, LineLen, StartEndLen, Step, CornerRes, Depth): blocks = [] block = Block(self.name) points = self.zigzag(Nlines, LineLen, StartEndLen, Step, CornerRes) block.append(CNC.zsafe()) block.append(CNC.grapid(points[0][0],points[0][1])) currDepth = 0. stepz = CNC.vars['stepz'] if stepz==0 : stepz=0.001 #avoid infinite while loop while True: currDepth -= stepz if currDepth < Depth : currDepth = Depth block.append(CNC.zenter(currDepth)) block.append(CNC.gcode(1, [("f",CNC.vars["cutfeed"])])) for (x,y) in points: block.append(CNC.gline(x,y)) if currDepth <= Depth : break block.append(CNC.zsafe()) blocks.append(block) return blocks
def execute(self, app): feed = self["feed"] zfeed = CNC.vars["cutfeedz"] rpm = self["rpm"] if self["zfeed"]: zfeed = self["zfeed"] zup = self["zup"] surface = CNC.vars["surface"] # zbeforecontact=surface+CNC.vars["zretract"] # hardcrust = surface - CNC.vars["hardcrust"] # feedbeforecontact = CNC.vars["feedbeforecontact"]/100.0 # hardcrustfeed = CNC.vars["hardcrustfeed"]/100.0 # Get selected blocks from editor selBlocks = app.editor.getSelectedBlocks() if not selBlocks: app.setStatus(_("Scaling abort: Please select some path")) return #Get all segments from gcode allSegments = self.extractAllSegments(app, selBlocks) #Create holes locations # allHoles=[] for bidSegment in allSegments: if len(bidSegment) == 0: continue blocks = [] n = self["name"] # if not n or n=="default": n="Trochoidal_3D" n = "Scaling" scal_block = Block(n) for idx, segm in enumerate(bidSegment): if idx >= 0: if idx == 0: scal_block.append("M03") scal_block.append("S " + str(rpm)) scal_block.append(CNC.zsafe()) scal_block.append("F " + str(feed)) scal_block.append( "(--------------------------------------------------)") B = self.scaling(segm) if segm[0][2] > surface and segm[1][2] >= surface: scal_block.append("g0 x " + str(B[0]) + " y " + str(B[1]) + " z " + str(B[2])) else: scal_block.append("g1 x " + str(B[0]) + " y " + str(B[1]) + " z " + str(B[2])) scal_block.append(CNC.zsafe( )) #<<< Move rapid Z axis to the safe height in Stock Material blocks.append(scal_block) self.finish_blocks(app, blocks)
def create_block(self, holes, name): targetDepth = self.fromMm("TargetDepth") peck = self.fromMm("Peck") dwell = self["Dwell"] block = Block(name) holesCount = 0 if self.useCustom: block.append("M3 S0") else: block.append(CNC.zsafe()) for bid in holes: for xH, yH, zH in bid: holesCount += 1 if self.useCustom: block.append( CNC.grapid(x=xH, y=yH) + CNC.fmt(' F', self.rFeed)) else: #block.append(CNC.zsafe()) # Moved up block.append(CNC.grapid(xH, yH)) if peck != 0: z = 0 while z > targetDepth: z = max(z - peck, targetDepth) if self.useCustom: block.append( "( --- WARNING! Peck is not setup for laser mode --- )" ) break else: block.append(CNC.zenter(zH + z)) block.append(CNC.zsafe()) if self.useCustom: block.append("G1 S%s" % (self.spinMax)) block.append(CNC.gline(x=xH, y=yH)) else: block.append(CNC.zenter(zH + targetDepth)) # Dwell time only on last pass if dwell != 0: block.append(CNC.gcode(4, [("P", dwell)])) if self.useCustom: block.append("G1 S%s" % (self.spinMin)) else: block.append(CNC.zsafe()) # Gcode Zsafe on finish if self.useCustom: block.append("M5") else: block.append(CNC.zsafe()) return (block, holesCount)
def calc(self, xstart, ystart, xend, yend, radius, cw): self.Points = [] self.corners = [ min(float(xstart), float(xend)), min(float(ystart), float(yend)), max(float(xstart), float(xend)), max(float(ystart), float(yend)), ] xmin, ymin, xmax, ymax = self.corners[0], self.corners[ 1], self.corners[2], self.corners[3] r = min(radius, (xmax - xmin) / 2, (ymax - ymin) / 2) blocks = [] block = Block(self.name) block.append(CNC.grapid(x=xmin, y=ymin + r)) block.append(CNC.grapid(z=0.0)) block.append("(entered)") if cw: block.append(CNC.gline(x=xmin, y=ymax - r)) if r > 0: block.append(CNC.garc(2, x=xmin + r, y=ymax, i=r, j=0)) if (xmax - xmin) > 2 * r: block.append(CNC.gline(x=xmax - r, y=ymax)) if r > 0: block.append(CNC.garc(2, x=xmax, y=ymax - r, i=0, j=-r)) if (ymax - ymin) > 2 * r: block.append(CNC.gline(x=xmax, y=ymin + r)) if r > 0: block.append(CNC.garc(2, x=xmax - r, y=ymin, i=-r, j=0)) if (xmax - xmin) > 2 * r: block.append(CNC.gline(x=xmin + r, y=ymin)) if r > 0: block.append(CNC.garc(2, x=xmin, y=ymin + r, i=0, j=r)) else: if r > 0: block.append(CNC.garc(3, x=xmin + r, y=ymin, i=r, j=0)) if (xmax - xmin) > 2 * r: block.append(CNC.gline(x=xmax - r, y=ymin)) if r > 0: block.append(CNC.garc(3, x=xmax, y=ymin + r, i=0, j=r)) if (ymax - ymin) > 2 * r: block.append(CNC.gline(x=xmax, y=ymax - r)) if r > 0: block.append(CNC.garc(3, x=xmax - r, y=ymax, i=-r, j=0)) if (xmax - xmin) > 2 * r: block.append(CNC.gline(x=xmin + r, y=ymax)) if r > 0: block.append(CNC.garc(3, x=xmin, y=ymax - r, i=0, j=-r)) if (ymax - ymin) > 2 * r: block.append(CNC.gline(x=xmin, y=ymin + r)) block.append("(exiting)") block.append(CNC.grapid(z=CNC.vars["safe"])) blocks.append(block) return blocks
def execute(self, app): rdoc = self["rdoc"] radius = self["dia"]/2 cw = self["cw"] circ = self["circ"] #print("go!") blocks = [] for bid in app.editor.getSelectedBlocks(): #print(blocks[bid]) path = app.gcode.toPath(bid)[0] #print(path) block = Block("trochoid") entry = self["entry"] for segment in path: #print(segment.A) #block.append("g0 x0 y0") #block.append("g1 x10 y10") #block.append("g1 x20 y10") #block.append("g0 x0 y0") if entry: eblock = Block("trochoid-in") eblock.append("G0 Z0") eblock.append("G0 x"+str(segment.A[0])+" y"+str(segment.A[1]-radius)) eblock.append("G2 x"+str(segment.A[0])+" y"+str(segment.A[1]-radius)+" i"+str(0)+" j"+str(radius)) blocks.append(eblock) entry = False block.append("G0 Z0") block.extend(self.trochoid(segment, rdoc, radius, cw, circ)) blocks.append(block) active = app.activeBlock() app.gcode.insBlocks(active, blocks, "Trochoidal created") #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Trochoidal")) #<<< feed back result
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 splitBlocks(self, event=None): if not self._items: return all_items = self._items sel_items = list(map(int,self.curselection())) change = True newblocks = [] for bid in sel_items: bl = Block(self.gcode[bid].name()) for line in self.gcode[bid]: if line == "( ---------- cut-here ---------- )": #newblocks.append(bl) #self.insertBlock(bl) self.gcode.addUndo(self.gcode.addBlockUndo(bid+1,bl)) bl = Block(self.gcode[bid].name()) else: bl.append(line) self.gcode.addUndo(self.gcode.addBlockUndo(bid+1,bl)) #newblocks.append(bl) #self.gcode.extend(newblocks) if change: self.fill() self.deleteBlock() self.winfo_toplevel().event_generate("<<Modified>>")
def execute(self, app): name = self["name"] if not name or name == "default": name = "Spiral" #Retrive data from user imput Size = self.fromMm("Size") Rotation = self["Rot"] CW = self["CW"] #grwoth per arc if Rotation <= 0: Rotation = 1 grow = Size / Rotation / 4 #Clockwise g = 2 if CW else 3 #Initialize blocks that will contain our gCode blocks = [] block = Block(name) #use some useful bCNC functions to generate gCode movement, see CNC.py for more block.append( "G0 Z3" ) #<<< Move rapid Z axis to the safe height in Stock Material block.append("G0 X0 Y0") #<<< Move rapid to X and Y coordinate block.append( "G1 Z0 F100" ) #<<< Enter in the material with Plunge Feed for current material block.append("F600") #<<< Feedrate x, y = 0, 0 while abs(x) < Size / 2: lx = x #<<< Save last x value x = abs(x) + grow #<<< Add the growing value if lx >= 0: x = -x #<<< Alternate sign dx = x - lx #<<< Calculate delta X (r = i = dx/2) block.append(CNC.garc(g=g, x=x, i=dx / 2)) #Circle with final Size block.append(CNC.garc(g=g, x=-x, i=-x)) block.append(CNC.garc(g=g, x=x, i=x)) blocks.append(block) active = app.activeBlock() app.gcode.insBlocks( active, blocks, "MyPlugins inserted" ) #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Spiral")) #<<< feed back result
def joinBlocks(self, event=None): if not self._items: return all_items = self._items sel_items = list(map(int,self.curselection())) change = True bl = Block(self.gcode[sel_items[0]].name()) for bid in sel_items: for line in self.gcode[bid]: bl.append(line) bl.append("( ---------- cut-here ---------- )") del bl[-1] self.gcode.addUndo(self.gcode.addBlockUndo(bid+1,bl)) if change: self.fill() self.deleteBlock() self.winfo_toplevel().event_generate("<<Modified>>")
def calc(self, xstart, ystart, xend, yend): points = [] points.append(Vector(xstart, ystart)) points.append(Vector(xend, yend)) first = points[0] last = points[1] blocks = [] block = Block(self.name) block.append(CNC.grapid(first.x(), first.y())) block.append(CNC.grapid(z=0.0)) block.append("(entered)") block.append(CNC.gline(last.x(), last.y())) block.append("(exiting)") block.append(CNC.grapid(z=CNC.vars["safe"])) blocks.append(block) return blocks
def execute(self, app): blocks = [] for bid in app.editor.getSelectedBlocks(): if len(app.gcode.toPath(bid)) < 1: continue eblock = Block("closed " + app.gcode[bid].name()) for path in app.gcode.toPath(bid): if not path.isClosed(): path.append(Segment(Segment.LINE, path[-1].B, path[0].A)) eblock = app.gcode.fromPath(path, eblock) #blocks.append(eblock) app.gcode[bid] = eblock #active=-1 #add to end #app.gcode.insBlocks(active, blocks, "Path closed") #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Closepath")) #<<< feed back result
def addLines(lines): for line in lines.splitlines(): # Create a new block if self.__lid is None: self.__bid += 1 self.__lid = MAXINT block = Block() undoinfo.append(self.gcode.addBlockUndo(self.__bid,block)) selitems.append((self.__bid, None)) else: block = self.gcode.blocks[self.__bid] if self.__lid == MAXINT: selitems.append((self.__bid, len(block))) else: self.__lid += 1 selitems.append((self.__bid, self.__lid)) undoinfo.append(self.gcode.insLineUndo(self.__bid, self.__lid, line))
def execute(self, app): name = self["name"] if not name or name == "default": name = "Drillmark" marksize = self["Mark size"] x0 = self.fromMm("PosX") y0 = self.fromMm("PosY") marktype = self["Mark type"] block = Block(name + " %s diameter %s" % (marktype, CNC.fmt("", marksize))) self.appendBurn(app, block) self.appendMark(app, block) active = app.activeBlock() if active == 0: active = 1 blocks = [block] app.gcode.insBlocks(active, blocks, _("Manual drill mark")) app.refresh() # <<< refresh editor app.setStatus(_("Generated: MyPlugin Result"))
def make(self, RExt=50., RInt=33., ROff=13., Depth=0): self.RExt = RExt self.RInt = RInt self.ROff = ROff if RExt > RInt: self.Spins = self.lcm(RExt, RInt) / max(RExt, RInt) else: self.Spins = self.lcm(RExt, RInt) / min(RExt, RInt) self.Depth = Depth self.PI = math.pi self.theta = 0.0 blocks = [] block = Block(self.name) block.append("(External Radius = %g)" % (self.RExt)) block.append("(Internal Radius = %g)" % (self.RInt)) block.append("(Offset Radius = %g)" % (self.ROff)) xi, yi = zip(*(self.calc_dots())) block.append(CNC.zsafe()) block.append(CNC.grapid(xi[0], yi[0])) currDepth = 0. stepz = CNC.vars['stepz'] if stepz == 0: stepz = 0.001 #avoid infinite while loop while True: currDepth -= stepz if currDepth < self.Depth: currDepth = self.Depth block.append(CNC.zenter(currDepth)) block.append(CNC.gcode(1, [("f", CNC.vars["cutfeed"])])) for x, y in zip(xi, yi): block.append(CNC.gline(x, y)) block.append(CNC.gline(xi[0], yi[0])) if currDepth <= self.Depth: break block.append(CNC.zsafe()) blocks.append(block) return blocks
def make(self): d = self.thick # Convert to external dimensions if self.dx < 0: dx = -self.dx - d * 2 # external to internal else: dx = self.dx if self.dy < 0: dy = -self.dy - d * 2 # external to internal else: dy = self.dy if self.dz < 0: dz = -self.dz - d * 2 # external to internal else: dz = self.dz blocks = [] block = Block("%s-Bottom" % (self.name)) block.append("(Box: %g x %g x %g)" % (self.dx, self.dy, self.dz)) block.append("(Fingers: %d x %d x %d)" % (self.nx, self.ny, self.nz)) self._rectangle(block, 0., -d, dx, dy, self.nx, -self.ny, 0, d) blocks.append(block) block = Block("%s-Left" % (self.name)) self._rectangle(block, -(dz + 5 * d), -d, dz, dy, self.nz, self.ny, d, d) blocks.append(block) block = Block("%s-Right" % (self.name)) self._rectangle(block, dx + 3 * d, -d, dz, dy, self.nz, self.ny, d, d) blocks.append(block) block = Block("%s-Front" % (self.name)) self._rectangle(block, 0, -(dz + 4 * d), dx, dz, -self.nx, -self.nz, 0, 0) blocks.append(block) block = Block("%s-Back" % (self.name)) self._rectangle(block, 0, dy + 4 * d, dx, dz, -self.nx, -self.nz, 0, 0) blocks.append(block) block = Block("%s-Top" % (self.name)) self._rectangle(block, dx + dz + 8 * d, -d, dx, dy, self.nx, -self.ny, 0, d) blocks.append(block) return blocks
def execute(self, app): #print("go!") blocks = [] for bid in app.editor.getSelectedBlocks(): if len(app.gcode.toPath(bid)) < 1: continue path = app.gcode.toPath(bid)[0] x,y = path.center() eblock = Block("center of "+app.gcode[bid].name()) eblock.append("G0 x"+str(x)+" y"+str(y)) eblock.append("G1 Z0 F200") eblock.append("G0 Z10") blocks.append(eblock) #active = app.activeBlock() #if active == 0: active+=1 active=-1 #add to end app.gcode.insBlocks(active, blocks, "Center created") #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Center")) #<<< feed back result
def slice(self, verts, faces, z, zout=None, axis='z'): tags = '[slice]' if axis == 'z': tags = '[slice,minz:%f]' % (float(z)) block = Block("slice %s%f %s" % (axis, float(z), tags)) #FIXME: slice along different axes if axis == 'x': plane_orig = (z, 0, 0) plane_norm = (1, 0, 0) elif axis == 'y': plane_orig = (0, z, 0) plane_norm = (0, 1, 0) else: plane_orig = (0, 0, z) #z height to slice plane_norm = (0, 0, 1) #Crosscut contours = meshcut.cross_section(verts, faces, plane_orig, plane_norm) #Flatten contours if zout is not None: for contour in contours: for segment in contour: segment[2] = zout #Contours to G-code for contour in contours: #print(contour) gtype = 0 for segment in contour: block.append("g%s x%f y%f z%f" % (gtype, segment[0], segment[1], segment[2])) gtype = 1 block.append( "g1 x%f y%f z%f" % (contour[0][0], contour[0][1], contour[0][2])) #Close shape block.append("( ---------- cut-here ---------- )") if block: del block[-1] if not block: block = None return block
def execute(self, app): #print("go!") blocks = [] for bid in app.editor.getSelectedBlocks(): if len(app.gcode.toPath(bid)) < 1: continue #nblock = Block("flat "+app.gcode[bid].name()) #for i in app.gcode[bid]: # nblock.append(re.sub(r"\s?z-?[0-9\.]+","",i)) #blocks.append(nblock) eblock = Block("flat " + app.gcode[bid].name()) eblock = app.gcode.fromPath(app.gcode.toPath(bid), eblock) blocks.append(eblock) #active = app.activeBlock() #if active == 0: active+=1 active = -1 #add to end app.gcode.insBlocks( active, blocks, "Shape flattened" ) #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Flat")) #<<< feed back result
def execute(self, app): #print("go!") blocks = [] bid = app.editor.getSelectedBlocks()[0] xbasepath = app.gcode.toPath(bid)[0] bid = app.editor.getSelectedBlocks()[1] xislandpath = app.gcode.toPath(bid)[0] xbasepath.intersectPath(xislandpath) xislandpath.intersectPath(xbasepath) #xnewisland = self.pathBoolIntersection(xbasepath, xislandpath) xnewisland = self.pathBoolIntersection(xislandpath, xbasepath) #pth = Path("temp") #basepath.invert() #pth.extend(basepath) #pth.extend(basepath) ##pth.invert() block = Block("diff") block.extend(app.gcode.fromPath(xnewisland)) blocks.append(block) #block = Block("diff") #block.extend(app.gcode.fromPath(pth)) #blocks.append(block) active = app.activeBlock() app.gcode.insBlocks( active, blocks, "Diff") #<<< insert blocks over active block in the editor app.refresh() #<<< refresh editor app.setStatus(_("Generated: Diff")) #<<< feed back result
def create_block(self, holes, name): targetDepth = self.fromMm("TargetDepth") peck = self.fromMm("Peck") dwell = self["Dwell"] block = Block(name) holesCount = 0 for bid in holes: for xH, yH, zH in bid: holesCount += 1 block.append(CNC.zsafe()) block.append(CNC.grapid(xH, yH)) if (peck != 0): z = 0 while z > targetDepth: z = max(z - peck, targetDepth) block.append(CNC.zenter(zH + z)) block.append(CNC.zsafe()) block.append(CNC.zenter(zH + targetDepth)) #dwell time only on last pass if dwell != 0: block.append(CNC.gcode(4, [("P", dwell)])) #Gcode Zsafe on finish block.append(CNC.zsafe()) return (block, holesCount)
def calc(self, xcenter, ycenter, radius, startangle, endangle): self.Points = [] xcenter, ycenter, radius, startangle, endangle = float(xcenter), float( ycenter), abs(float(radius)), float(startangle), float(endangle) xstart = xcenter + radius * math.cos(startangle * math.pi / 180.0) xend = xcenter + radius * math.cos(endangle * math.pi / 180.0) ystart = ycenter + radius * math.sin(startangle * math.pi / 180.0) yend = ycenter + radius * math.sin(endangle * math.pi / 180.0) i = xcenter - xstart j = ycenter - ystart blocks = [] block = Block(self.name) block.append(CNC.grapid(x=xstart, y=ystart)) block.append(CNC.grapid(z=0.0)) block.append("(entered)") if startangle < endangle: direction = 3 else: direction = 2 block.append(CNC.garc(direction, x=xend, y=yend, i=i, j=j)) block.append("(exiting)") block.append(CNC.grapid(z=CNC.vars["safe"])) blocks.append(block) return blocks
def execute(self, app): if Image is None: app.setStatus( _("Halftone abort: This plugin requires PIL/Pillow to read image data" )) return n = self["name"] if not n or n == "default": n = "Halftone" # Calc desired size channel = self["Channel"] invert = self["Invert"] drawSize = self["DrawSize"] cellSize = self["CellSize"] dMax = self["DiameterMax"] dMin = self["DiameterMin"] angle = self["Angle"] drawBorder = self["DrawBorder"] depth = self["Depth"] conical = self["Conical"] # Check parameters if drawSize < 1: app.setStatus( _("Halftone abort: Size too small to draw anything!")) return if dMin > dMax: app.setStatus( _("Halftone abort: Minimum diameter must be minor then Maximum" )) return if dMax < 1: app.setStatus(_("Halftone abort: Maximum diameter too small")) return if cellSize < 1: app.setStatus(_("Halftone abort: Cell size too small")) return tool = app.tools["EndMill"] tool_shape = tool["shape"] if conical: if tool_shape == "V-cutting": try: v_angle = float(tool["angle"]) except: app.setStatus( _("Halftone abort: Angle in V-Cutting end mill is missing" )) return else: app.setStatus( _("Halftone abort: Conical path need V-Cutting end mill")) return # Open picture file fileName = self["File"] try: img = Image.open(fileName) except: app.setStatus(_("Halftone abort: Can't read image file")) return # Create a scaled image to work faster with big image and better with small ones squareNorm = True if channel == 'Blue(sqrt)': img = img.convert('RGB') img = img.split()[0] elif channel == 'Green(sqrt)': img = img.convert('RGB') img = img.split()[1] elif channel == 'Red(sqrt)': img = img.convert('RGB') img = img.split()[2] else: img = img.convert('L') # to calculate luminance squareNorm = False # flip image to ouput correct coordinates img = img.transpose(Image.FLIP_TOP_BOTTOM) # Calc divisions for halftone divisions = drawSize / cellSize # Get image size self.imgWidth, self.imgHeight = img.size if (self.imgWidth > self.imgHeight): scale = drawSize / float(self.imgWidth) sample = int(self.imgWidth / divisions) else: scale = drawSize / float(self.imgHeight) sample = int(self.imgHeight / divisions) self.ratio = scale # Halftone circles = self.halftone(img, sample, scale, angle, squareNorm, invert) # Init blocks blocks = [] # Border block if drawBorder: block = Block("%s-border" % (self.name)) block.append(CNC.zsafe()) block.append(CNC.grapid(0, 0)) block.append(CNC.zenter(depth)) block.append(CNC.gcode(1, [("f", CNC.vars["cutfeed"])])) block.append(CNC.gline(self.imgWidth * self.ratio, 0)) block.append( CNC.gline(self.imgWidth * self.ratio, self.imgHeight * self.ratio)) block.append(CNC.gline(0, self.imgHeight * self.ratio)) block.append(CNC.gline(0, 0)) blocks.append(block) # Draw block block = Block(self.name) # Change color if channel == 'Blue(sqrt)': block.color = "#0000ff" elif channel == 'Green(sqrt)': block.color = "#00ff00" elif channel == 'Red(sqrt)': block.color = "#ff0000" block.append("(Halftone size W=%d x H=%d x D=%d ,Total points:%i)" % (self.imgWidth * self.ratio, self.imgHeight * self.ratio, depth, len(circles))) block.append("(Channel = %s)" % channel) for c in circles: x, y, r = c r = min(dMax / 2.0, r) if (r >= dMin / 2.): block.append(CNC.zsafe()) block.append(CNC.grapid(x + r, y)) block.append(CNC.zenter(depth)) block.append(CNC.garc( CW, x + r, y, i=-r, )) block.append(CNC.zsafe()) if conical: block.enable = False blocks.append(block) if conical: blockCon = Block("%s-Conical" % (self.name)) for c in circles: x, y, r = c blockCon.append(CNC.zsafe()) blockCon.append(CNC.grapid(x, y)) dv = r / math.tan(math.radians(v_angle / 2.)) blockCon.append(CNC.zenter(-dv)) blockCon.append(CNC.zsafe()) blocks.append(blockCon) # Gcode Zsafe active = app.activeBlock() app.gcode.insBlocks(active, blocks, "Halftone") app.refresh() app.setStatus( _("Generated Halftone size W=%d x H=%d x D=%d ,Total points:%i" % (self.imgWidth * self.ratio, self.imgHeight * self.ratio, depth, len(circles))))